Excel (VBA) |
![]() ![]() |
(Windows 10 Home : Microsoft 365)
大したVBA処理でもないのに遅くなってしまいます
投稿日時: 22/09/02 17:52:19
投稿者: SURT
|
---|---|
ある売上データを連続で入力します
|
![]() |
投稿日時: 22/09/02 17:58:37
投稿者: SURT
|
---|---|
追記です
|
![]() |
投稿日時: 22/09/02 18:22:47
投稿者: taitani
|
---|---|
・マクロVBAの高速化・速度対策の具体的手順と検証
|
![]() |
投稿日時: 22/09/02 19:15:49
投稿者: simple
|
---|---|
changeイベントプロシージャーの中でセルを変更すると、
|
![]() |
投稿日時: 22/09/02 21:40:37
投稿者: simple
|
---|---|
それでは、既に指摘がありましたが、
Application.Calculation = xlCalculationManualとし、最後に Application.Calculation = xlCalculationAutomaticとしてみてはいかがですか? |
![]() |
投稿日時: 22/09/15 18:42:50
投稿者: SURT
|
---|---|
様々な回答ありがとうございます
|
![]() |
投稿日時: 22/09/15 20:24:15
投稿者: simple
|
---|---|
繰り返しになりますが、下記でも同様の動作遅延が起きますか?
Private Sub Worksheet_Change(ByVal Target As Range) With Target If .Column <> 8 Or .Row = 1 Then Exit Sub If .Offset(, -1).Value = "" Then Application.EnableEvents = False Application.Calculation = xlCalculationManual .Offset(, -1).Value = .Offset(-1, -1).Value If .Offset(, 1).Value = "" Then .Offset(, 1).Value = .Offset(-1, 1).Value Application.EnableEvents = True Application.Calculation = xlCalculationAutomatic End If End With End Subこれでも遅延とすれば、ファイル自体になんらかの異常が発生しているくらいしか、 考えつきませんね。 まったく新しいブックに、データを移して同じ事象が発生するか確認されたらいかがですか? (データは、できればテキストエディターなどにいったんコピーして、直接コピーしないほうが 良いと思います。異常の原因自体がコピーされる恐れがあるので。 式は、再度入力してください。) |
![]() |
投稿日時: 22/09/16 19:06:45
投稿者: SURT
|
---|---|
書いていただいたコードでも遅延しました(わずかに速くなったように感じました)
|
![]() |
投稿日時: 22/09/16 21:47:38
投稿者: simple
|
---|---|
引用: なんらかの状況(書式が多数ある等々)で、ブックが不安定になっていたものと想像されます。 その原因はMS社以外の第三者には分かりません。想像するのみです。 引用:おっしゃる意味が分かりません。 Targetというのは変化が生じたセルですから、全体を選択している訳ではありません。 コード自体には特段の問題はなかったのでは? ブックが不安定になっていたことが最大の原因と考えられますから、 それを解消することが「解決策」であり、それは果たされたのではないんですか? |
![]() |
投稿日時: 22/09/18 18:02:40
投稿者: SURT
|
---|---|
伝え方が悪くてすみません
|
![]() |
投稿日時: 22/09/18 19:31:26
投稿者: simple
|
---|---|
念のため5万行のテーブルを作ってやってみましたが、遅延はありませんでした。
|
![]() |
投稿日時: 22/09/20 15:27:12
投稿者: SURT
|
---|---|
記載したコードと
|
![]() |
投稿日時: 22/09/20 15:39:59
投稿者: SURT
|
---|---|
アニメーションが原因かとおもいオフにしましたが変化なし
|
![]() |
投稿日時: 22/09/20 15:42:04
投稿者: taitani
|
---|---|
気になったので私も動作テストしました。
|
![]() |
投稿日時: 22/09/20 15:44:06
投稿者: taitani
|
---|---|
そもそも、
|
![]() |
投稿日時: 22/09/20 15:48:25
投稿者: SURT
|
---|---|
先程貼った動画のようにテンキーで手入力で入力しています
|
![]() |
投稿日時: 22/09/20 15:51:45
投稿者: SURT
|
---|---|
ちなみに、計算式を空欄にしても動作にかわりはありませんでした
|
![]() |
投稿日時: 22/09/20 16:11:11
投稿者: taitani
|
---|---|
すみません、入れ違いでしたね。
Private Sub Worksheet_Change(ByVal Target As Range) '個数を入力する列数を定義 If Target.Column = 8 Or Target.Row <> 1 Then With Target '日付(個数からのオフセット距離)が空欄なら If .Offset(, -1).Value = "" Then Application.EnableEvents = False Application.Calculation = xlCalculationManual '日付をコピー .Offset(, -1).Value = .Offset(-1, -1).Value '担当者IDが空欄なら上の行の担当者IDをコピー If .Offset(, 1).Value = "" Then .Offset(, 1).Value = .Offset(-1, 1).Value Application.EnableEvents = True Application.Calculation = xlCalculationAutomatic End If End With End If End Sub ※ simple さんの Code で、Target 判断を前にしただけです。 |
![]() |
投稿日時: 22/09/20 20:04:57
投稿者: SURT
|
---|---|
差は感じられませんでした
|
![]() |
投稿日時: 22/09/21 10:44:13
投稿者: WinArrow
|
---|---|
Excelのテーブル機能には、
|
![]() |
投稿日時: 22/09/22 19:12:17
投稿者: WinArrow
|
---|---|
ListObjectを利用した例
Private Sub Worksheet_Change(ByVal Target As Range) Dim ListOBJ As ListObject, N As Long If Target.Address(0, 0) = "J1" Then Application.EnableEvents = False Set ListOBJ = Me.ListObjects(1) ListOBJ.ListRows.Add N = ListOBJ.Range.Rows.Count ListOBJ.ListRows(N - 1).Range(1) = Target.Value If ListOBJ.ListRows(N - 1).Range(1) = "" Then ListOBJ.ListRows(N - 1).Range(1) = ListOBJ.ListRows(N - 2).Range(1) End If Application.EnableEvents = True End If End Sub |
![]() |
投稿日時: 22/09/23 13:47:15
投稿者: WinArrow
|
---|---|
ちょっとした疑問
|
![]() |
投稿日時: 22/09/24 14:55:14
投稿者: SURT
|
---|---|
WinArrowさんコードありがとうございます
|
![]() |
投稿日時: 22/09/24 15:31:53
投稿者: WinArrow
|
---|---|
VBAでListObjectを使って入力するには、
|
![]() |
投稿日時: 22/09/24 21:49:13
投稿者: WinArrow
|
---|---|
私がListObjectを推奨する理由
|
![]() |
投稿日時: 22/09/27 17:08:49
投稿者: mattuwan44
|
---|---|
原因はよくわかりませんが。。。。
|
![]() |
投稿日時: 22/09/29 10:47:47
投稿者: WinArrow
|
---|---|
そもそも・・・テーブル化した目的は、何でしょう?
|
![]() |
投稿日時: 22/09/30 11:44:04
投稿者: simple
|
---|---|
以下のとおり実験してみました。
(1) 0.3828125秒 テーブルなし (2) 0.5585938秒 テーブルあり (3) 0.5507813秒 ListObject利用 もう一回 (1) 0.375 秒 テーブルなし (2) 0.5703125秒 テーブルあり (3) 0.5429688秒 ListObject利用となりました。解釈は皆さまにお任せいたします。 入力は、テーブルなしの状態で行い、データ入力後にテーブル化してから、 PowerQuery等を使ってデータ操作するのが、今どきかもしれませんね。 以下参考までに使用したコードを載せておきます。 Dim ws As Worksheet Dim myRange As Range Sub Table利用せず() Dim k& Dim t Set ws = Sheet1 Set myRange = ws.[A1].Resize(50000, 9) Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Call 初期設定 With ws t = Timer ' ここ以降の実行時間を測定 For k = 45001 To 50000 If .Cells(k, 7).Value = "" Then .Cells(k, 7).Value = .Cells(k - 1, 7).Value If .Cells(k, 9).Value = "" Then .Cells(k, 9).Value = .Cells(k - 1, 9).Value End If End If Next End With Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic Debug.Print Timer - t; " テーブルなし" End Sub Sub Table利用() Dim k& Dim t Set ws = Sheet1 Set myRange = ws.[A1].Resize(50000, 9) Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Call 初期設定 With ws .ListObjects.Add(xlSrcRange, myRange, , xlYes).Name = "テーブル1" t = Timer For k = 45001 To 50000 If .Cells(k, 7).Value = "" Then .Cells(k, 7).Value = .Cells(k - 1, 7).Value If .Cells(k, 9).Value = "" Then .Cells(k, 9).Value = .Cells(k - 1, 9).Value End If End If Next End With Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic Debug.Print Timer - t; " テーブルあり" End Sub Sub ListObject利用() Dim listObj As ListObject Dim k& Dim t Set ws = Sheet1 Set myRange = ws.[A1].Resize(50000, 9) Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Call 初期設定 With ws .ListObjects.Add(xlSrcRange, myRange, , xlYes).Name = "テーブル1" Set listObj = .ListObjects("テーブル1") t = Timer ' ここ以降の実行時間を測定 For k = 45001 To 50000 If listObj.ListRows(k - 1).Range(7) = "" Then listObj.ListRows(k - 1).Range(7) = listObj.ListRows(k - 2).Range(7) If listObj.ListRows(k - 1).Range(9) = "" Then listObj.ListRows(k - 1).Range(9) = listObj.ListRows(k - 2).Range(9) End If End If Next End With Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic Debug.Print Timer - t; " ListObject利用" End Sub Function 初期設定() myRange.ClearContents On Error Resume Next If ws.ListObjects.Count > 0 Then ws.ListObjects(1).Delete End If On Error GoTo 0 'ダミーデータをセット ws.[A1].Resize(50000, 6).Formula = "=row() & ""_"" & column()" ws.[G1:G45000] = DateSerial(2022, 10, 1) ws.[I1:I45000] = "A100" End Function |
![]() |
投稿日時: 22/09/30 17:01:15
投稿者: WinArrow
|
---|---|
simpleさん、コード作成ご苦労様です。
|
![]() |
投稿日時: 22/10/01 09:57:28
投稿者: simple
|
---|---|
ご指摘のとおりですね。
|
![]() |
投稿日時: 22/10/01 14:58:55
投稿者: WinArrow
|
---|---|
いろいろテストしたところ
|
![]() |
投稿日時: 22/10/01 15:14:20
投稿者: simple
|
---|---|
以下のコードを実行すると、
Sub Table利用() Dim k& Dim t Set ws = Sheet1 Set myRange = ws.[A1].Resize(45000, 9) Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Call 初期設定 With ws .ListObjects.Add(xlSrcRange, myRange, , xlYes).Name = "テーブル1" t = Timer For k = 45001 To 50000 If .Cells(k, 7).Value = "" Then .Cells(k, 7).Value = .Cells(k - 1, 7).Value If .Cells(k, 9).Value = "" Then .Cells(k, 9).Value = .Cells(k - 1, 9).Value End If End If Next End With Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic Debug.Print Timer - t; " テーブルあり" End Sub Function 初期設定() ws.[A1].Resize(50000, 9).ClearContents On Error Resume Next If ws.ListObjects.Count > 0 Then ws.ListObjects(1).Delete End If On Error GoTo 0 'ダミーデータをセット ws.[A1].Resize(45000, 6).Formula = "=row() & ""_"" & column()" ws.[G1:G45000] = DateSerial(2022, 10, 1) ws.[I1:I45000] = "A100" End Function |