Excel (VBA) |
![]() ![]() |
(Windows 11 Home : Microsoft 365)
実行時にエクセルが度々落ちるのでコードを修正したい
投稿日時: 23/02/23 00:35:42
投稿者: miyuukate
|
---|---|
お世話になっています。
A B C D E 1 日付〜 2 3 種類〜 4 5 6 7 8 番号 日付 種類 色 可否 9 1 44928 丸 赤 可 10 2 44958 三角 白 可 11 3 44959 四角 赤 可 12 4 13 5 14 6 15 7 16 8 17 9 18 10 〜 複数のファイル「元*」シート「1番」「2番」(2番にはリンク設定と保護あり) A B C D 1元データ 2 3 4 5 6 7 8 日付 種類 色 可否 9 2月1日 三角 白 可 10 2月2日 四角 赤 可 ファイル「一覧表」標準モジュール1のコード Sub 一覧表() Dim swb As Workbook Dim sws As Worksheet Dim dwb As Workbook Dim dws As Worksheet Dim sFolder As String Dim sFile As String Dim dFolder As String Dim FSO As New Scripting.FileSystemObject Dim i As Long Dim sLastRow As Long Dim dLastRow As Long Dim noNeedToMove As Boolean Dim RowP As Long sFolder = "C:\Users\Documents\一覧\元\" sFile = Dir(sFolder & "元*.xlsx") dFolder = "C:\Users\Documents\一覧\済\" If sFile = "" Then MsgBox sFolder & "ファイルはありません", vbExclamation, "ファイルなし" Exit Sub End If Application.ScreenUpdating = False Application.EnableEvents = False Application.Calculation = xlCalculationManual Set dwb = ThisWorkbook Set dws = dwb.Worksheets("一覧") Do Until sFile = "" Set swb = Workbooks.Open(sFolder & sFile) Set sws = swb.Worksheets("1番") noNeedToMove = True dLastRow = dws.Cells(dws.Rows.Count, 2).End(xlUp).Row With sws sLastRow = .Cells(.Rows.Count, 1).End(xlUp).Row For i = 9 To sLastRow If .Cells(i, 4) = "可" Then .Range(.Cells(i, 1), .Cells(i, 4)).Copy dws.Cells(dLastRow + 1, 2).PasteSpecial Paste:=xlPasteValues dLastRow = dLastRow + 1 Else noNeedToMove = False End If Next i End With If noNeedToMove Then With swb.Worksheets("2番") If WorksheetFunction.CountIf(.Range(.Cells(9, 4), .Cells(10, 4)), "") <= 2 Then noNeedToMove = False End If End With End If swb.Close False If noNeedToMove Then FSO.MoveFile sFolder & sFile, dFolder End If sFile = Dir() Loop If Not dws.Cells(9, 2) = "" Then With dws.Sort .SortFields.Clear .SortFields.Add Key:=Range("B9"), Order:=xlAscending .SetRange Range(Cells(9, 2), Cells(dLastRow, 5)) .Header = xlNo .Apply End With dws.Range("A9:E" & dLastRow).RemoveDuplicates (Array(2, 3)) End If [u] [b]For RowP = dws.[B9].SpecialCells(xlCellTypeLastCell).Row To 1 Step -1 If Cells(RowP, "A").Borders(xlEdgeRight).LineStyle = xlNone Then Rows(RowP).Delete End If Next RowP[/b][/u] Set FSO = Nothing Set swb = Nothing Set sws = Nothing Set dwb = Nothing Set dws = Nothing Application.ScreenUpdating = True Application.EnableEvents = True Application.Calculation = xlCalculationAutomatic End Sub ファイル「一覧表」標準モジュール2のコード Sub 一覧2() Dim swb As Workbook Dim sws As Worksheet Dim dwb As Workbook Dim dws As Worksheet Dim sFolder As String Dim sFile As String Dim dFolder As String Dim FSO As New Scripting.FileSystemObject Dim i As Long Dim sLastRow As Long Dim dLastRow As Long Dim noNeedToMove As Boolean Dim RowP As Long 'コピー元ファイル sFolder = "C:\Users\Documents\一覧\元\" sFile = Dir(sFolder & "元*.xlsx") 'コピー後の移動フォルダー dFolder = "C:\Users\Documents\一覧\済\" If sFile = "" Then MsgBox sFolder & "ファイルはありません", vbExclamation, "ファイルなし" Exit Sub End If Application.ScreenUpdating = False Application.EnableEvents = False Application.Calculation = xlCalculationManual Set dwb = ThisWorkbook Set dws = dwb.Worksheets("一覧2") Do Until sFile = "" Set swb = Workbooks.Open(sFolder & sFile) Set sws = swb.Worksheets("2番") noNeedToMove = True dLastRow = dws.Cells(dws.Rows.Count, 2).End(xlUp).Row With sws sLastRow = .Cells(.Rows.Count, 1).End(xlUp).Row For i = 9 To sLastRow If .Cells(i, 4) = "可" Then .Range(.Cells(i, 1), .Cells(i, 4)).Copy dws.Cells(dLastRow + 1, 2).PasteSpecial Paste:=xlPasteValues dLastRow = dLastRow + 1 Else noNeedToMove = False End If Next i End With swb.Close False If noNeedToMove Then FSO.MoveFile sFolder & sFile, dFolder End If sFile = Dir() Loop If Not dws.Cells(9, 2) = "" Then With dws.Sort .SortFields.Clear .SortFields.Add Key:=Range("B9"), Order:=xlAscending .SetRange Range(Cells(9, 2), Cells(dLastRow, 5)) .Header = xlNo .Apply End With dws.Range("A9:E" & dLastRow).RemoveDuplicates (Array(2, 3)) End If [u] [b]For RowP = dws.[B9].SpecialCells(xlCellTypeLastCell).Row To 1 Step -1 If Cells(RowP, "A").Borders(xlEdgeRight).LineStyle = xlNone Then Rows(RowP).Delete End If Next RowP[/b][/u] Set FSO = Nothing Set swb = Nothing Set sws = Nothing Set dwb = Nothing Set dws = Nothing Application.ScreenUpdating = True Application.EnableEvents = True Application.Calculation = xlCalculationAutomatic End Sub ステップインで確認したところ下線部分で繰り返しが延々続きました。ここのコードをどのように修正していいのか、他にももっと修正箇所があるのか、その辺りがわからずアドバイスお願いいたします。 |
![]() |
投稿日時: 23/02/23 20:27:35
投稿者: simple
|
---|---|
Excelが落ちる原因はわかりません。データが悪さをしているケースもあるでしょうから。
|
![]() |
投稿日時: 23/02/23 21:30:56
投稿者: miyuukate
|
---|---|
simple さんの引用: コメントありがとうございます。 質問について下記に記載しました。ご確認お願いします。 質問1 転記は値だけでもし罫線のないところに転記されれば削除対象になります。 9行〜1000行まで罫線があり、その中に値が転記されますが、RemoveDuplicateで同一行削除をすると表の間に削除した件数分の罫線なしの空白行ができるので、それを削除したくて罫線のあるなしで削除するようにしました。(1行〜7行までは表の外ですが文字がある行が削除されないようにA列右側に罫線をいれています) 質問2 Cell(9,4)かCell(10,4)のどちらかにでも「可」があるとファイルが「済」フォルダーに移動しないようにということでこのようにしました。(どちらか1つにしか「可」がないというケースもあり、その場合は移動しないとしたかったので) 質問3 ご指摘ありがとうございます。シート指定が抜けてるところは修正しました。 コードの見直しも再度いたします。 |
![]() |
投稿日時: 23/02/23 23:43:14
投稿者: simple
|
---|---|
行削除は、コストの高い処理です。(Excelにとって負荷が高く、時間もかかります。)
WorksheetFunction.CountIf(.Range(.Cells(9, 4), .Cells(10, 4)), "")に、"可"は関係ないですよね。 WorksheetFunction.CountIf(.Range(.Cells(9, 4), .Cells(10, 4)), "") は 0,1,2のいずれかになりますが、それはすべて2以下じゃないですか。 判定の意味がわからないですね。 (2) If noNeedToMove Then FSO.MoveFile sFolder & sFile, dFolder End If 移動する必要なし、なら移動させるんですか? 変数の使い方の話ですが、頭が混乱しませんか? 片方のシートだけで判定して、ファイルを移動してしまってよいのか、とか ロジックがよくわからないですね。 いずれにしても、それらはこちらで検証する話ではないので、 そちらでよく検証して下さい。 私は以上です。頑張ってください。 |
![]() |
投稿日時: 23/02/24 00:47:34
投稿者: miyuukate
|
---|---|
[quote="simple"]行削除は、コストの高い処理です。(Excelにとって負荷が高く、時間もかかります。)
|