初心者です。
検索で拾ったコードを組み合わせて、下のようなコードでマクロを作りました。
2万行を超えるデータを、オートフィルである列の中から「1」以外を行で削除するようにします。
実際に実行すると、時間がかかりポインタがクルクルとなっています。
もっと早く処理できるようにできますでしょうか。どこかおかしいところがありますでしょうか。
ご指摘のほどよろしくお願いします。
Sub コマンドボタン枝番_Click()
Dim intRowCount, i As Integer
Dim lngTotal, lngWriteTotal As Long
If MsgBox("枝番1以外を削除します。" & vbCrLf & _
"処理を実行しますか?", vbYesNo + vbQuestion, "行削除マクロ") = vbNo Then
Exit Sub
End If
Application.ScreenUpdating = False
lngTotal = Application.WorksheetFunction.CountA(Range("AV2:AV40000"))
Worksheets("全体").Activate
Worksheets("全体").Range("AV1").Select
Selection.AutoFilter
Selection.CurrentRegion.Select
intRowCount = Selection.Rows.Count + 1
ActiveSheet.Range("$A$1:$BO$40000").AutoFilter Field:=48, Criteria1:=">1", _
Operator:=xlAnd
Rows("2:40000").Select
Selection.Delete Shift:=xlUp
Selection.AutoFilter
Application.Goto reference:=Range("A1"), Scroll:=True
lngWriteTotal = WorksheetFunction.CountA(Range("AV2:AV40000"))
MsgBox "処理を完了しました。" & vbCrLf & _
"件数:" & vbCrLf & lngWriteTotal
Worksheets("手順シート").Activate
Application.ScreenUpdating = True
Exit Sub
End Sub
No.1ベストアンサー
- 回答日時:
オートフィルタの状態で削除するから、実際は飛び飛びの行削除になっててそこで処理が重くなってるんじゃないかと。
先に、AV列(48番目の列)でソートをかけてしまって、
そののちに1以外(1より大きい数でいいんですよね?)をフィルターすると、
連続した列の削除になるので、処理時間が短くなります。
投稿されたコードの途中に★★★で囲まれた部分を追加して、処理速度を確認してみてください。
・・・
lngTotal = Application.WorksheetFunction.CountA(Range("AV2:AV40000"))
Worksheets("全体").Activate
'★★★
ActiveWorkbook.Worksheets("全体").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("全体").Sort.SortFields.Add Key:=Range("AV2:AV40000") _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("全体").Sort
.SetRange Range("A1:BO40000")
.Header = xlYes
.Apply
End With
'★★★★
Worksheets("全体").Range("AV1").Select
Selection.AutoFilter
・・・
No.7
- 回答日時:
たびたびごめんなさい。
No.6の最後で記載した部分(どこかのセルに「_」をつかっていないか?)
が気になったのでためしに、該当行にアンダーバー入りの文字列のセルで試してみました。
>myStr = myStr & myR(i, j) & "_"
の行でエラーになってしまいました。
というコトはおそらくセル内にアンダーバー入りのセルがあるのでは?
No.4のコードの
>myStr = myStr & myR(i, j) & "_"
と
>myAry = Split(myKey(i), "_")
の2行のアンダーバーの部分を
カンマなど使っていない文字に変更してみてください。
>myStr = myStr & myR(i, j) & ","
といった感じで・・・
※ カンマに限らず「#」などどんな文字でも構いません。
セル内に存在しない文字にします。m(_ _)m
No.6
- 回答日時:
No.4・5です。
>元データのどこからどこまでと交換するのでしょか。
前回のコードは「全体」シートの
>lastRow = .Cells(Rows.Count, "A").End(xlUp).Row
でA列最終行を取得
>lastCol = .Cells(1, Columns.Count).End(xlToLeft).Column
で1行目項目行の最終列を取得するようにしていますので、
A列と1行目に最終行・最終列までデータがちゃんと入っていれば
その範囲すべてが対象になっているはずです。
2行目以降を検索し、AV列が「1」の場合の行のみ
A列から各行のデータを項目名がある最終列までアンダーバー「_」で連結し
各行すべての「連結文字」を一旦仮想配列に登録しています。
項目名がBD列まで入っているのであれば
仮に、AV2セルが「1」の場合
A2_B2_C2_・・・・_BD2
という具合に該当行(残す行?)のみ登録しています。
最後にA列~最終列2行目以降のデータを一旦消去し
A2セル以降に登録している行データを
「_」で分割させ、各列に表示させる!
といった流れのコードです。
※ 注意点として、
万一、アンダーバー「_」を使っているセルがある場合は誤作動しますので、
区切り文字をカンマ「,」などの使っていない文字にする必要があるかもしれません。m(_ _)m
No.5
- 回答日時:
No.4です。
>myStr = myStr & myR(i, j) & "_" でエラーになります。
他のところでエラーになる可能性はあっても、
この行は単純に
A列~最終列のセルを「_」で繋いでいるだけなので、この行でエラーになるコト自体が考えにくいのですが・・・
セルはどのようなデータが入っているのでしょうか?
その辺が判れば少しはお役に立てるかもしれません。
※ 前回のコードで最初の5行で色々変数の宣言をしていますが、
もちろんそれはそのままありますよね?m(_ _)m
No.4
- 回答日時:
こんにちは!
オートフィルタではなく別案です。
値だけの操作で、AV列が1のデータのみを「全体」シートに残すようにしてみました。
本来であれば元データを削除するより、別シートに書き出す方が良いと思うのですが、
元データに手を付けています。
尚、1行目は項目行でデータは2行目以降にあり、
A列で最終行を取得していますので、A列にはAV列の最終行と同じ行までデータがある!という前提です。
標準モジュールです。
Sub Sample1()
Dim myDic As Object
Dim i As Long, j As Long
Dim lastRow As Long, lastCol As Long
Dim myStr As String, buf As String
Dim myKey, myR, myAry
Set myDic = CreateObject("Scripting.Dictionary")
With Worksheets("全体")
lastRow = .Cells(Rows.Count, "A").End(xlUp).Row
lastCol = .Cells(1, Columns.Count).End(xlToLeft).Column
myR = Range(.Cells(2, "A"), .Cells(lastRow, lastCol))
For i = 1 To UBound(myR, 1)
If myR(i, 48) = 1 Then
For j = 1 To lastCol
myStr = myStr & myR(i, j) & "_"
Next j
buf = Left(myStr, Len(myStr) - 1)
If Not myDic.exists(buf) Then
myDic.Add buf, ""
End If
End If
myStr = ""
Next i
myKey = myDic.keys
Range(.Cells(2, "A"), .Cells(lastRow, lastCol)).ClearContents
myR = Range(.Cells(2, "A"), .Cells(UBound(myKey) + 2, lastCol))
For i = 0 To UBound(myKey)
myAry = Split(myKey(i), "_")
For j = 0 To UBound(myAry)
myR(i + 1, j + 1) = myAry(j)
Next j
Next i
Range(.Cells(2, "A"), .Cells(UBound(myKey) + 2, lastCol)) = myR
Set myDic = Nothing
End With
MsgBox "完了" & vbCrLf & "件数:" & UBound(myKey) + 1 & "件"
End Sub
こんな感じではどうでしょうか。
ちなみにこちらで試した結果
6万行のサンプルで約5秒かかりました。m(_ _)m
No.3
- 回答日時:
追記
元のシートをB列が1のみで書き換えるのであれば、
' 表示データクリア
Sheets("Sheet1").Range("A:B").Value = ""
curRow = 1
Do Until rs.EOF
Sheets("Sheet1").Range("A" & curRow).Value = rs!F1
Sheets("Sheet1").Range("B" & curRow).Value = rs!F2
rs.MoveNext
curRow = curRow + 1
Loop
とします。
元の表の1行目に、列の見出しを付ける場合、
A列の見出し=項目
B列の見出し=枝番
'1行目がヘッダの場合はHDR=YESにする。NOの場合はF1,F2,F3・・・と番号が振られる。
cn.Properties("Extended Properties") = "Excel 12.0;HDR=YES;IMEX=1"
SQLは、
'---------------------------------------
'項目(A列),枝番(B列)を抽出
'WHERE(条件) 枝番(B列)が1のデータを抽出
' 項目(A列)で並べ替え
'---------------------------------------
sql = "SELECT" _
& " 項目, 枝番" _
& " FROM [Sheet1$]" _
& " WHERE 枝番=1" _
& " ORDER BY 項目"
rs.Open sql, cn, adOpenStatic
' 表示データクリア
Sheets("Sheet1").Range("A:B").Value = ""
Sheets("Sheet1").Cells(1, 1) = "項目"
Sheets("Sheet1").Cells(1, 2) = "枝番"
curRow = 2
Do Until rs.EOF
Sheets("Sheet1").Range("A" & curRow).Value = rs!F1
Sheets("Sheet1").Range("B" & curRow).Value = rs!F2
rs.MoveNext
curRow = curRow + 1
Loop
No.2
- 回答日時:
SQLを使ってみてはいかがでしょうか?
オートフィルタを適用するために、範囲選択したり、フィルタをつけたり外したり、
無駄な動作が多くなりますね。
EXCEL SQLで検索すると、出てきますよ。
SQLを使うと、データの抽出が簡単にできます。
例えば、
A列、B列のデータを抽出。ただし、B列のデータが”1”のデータのみ抽出してSheet2
に貼り付ける。
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim xl_file As String
Dim sql As String
Dim curRow As Integer
'ツールメニューの参照設定'
' Microsoft ActiveX Data Objects 2.8 Library'
'チェック'
xl_file = ThisWorkbook.FullName '他のブックを指定しても良い'
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Provider = "Microsoft.ACE.OLEDB.12.0"
'1行目がヘッダの場合はHDR=YESにする。NOの場合はF1,F2,F3・・・と番号が振られる。
cn.Properties("Extended Properties") = "Excel 12.0;HDR=NO;IMEX=1"
cn.Open ThisWorkbook.FullName '自ワークブックのファイル名を指定しているが、
Set rs = New ADODB.Recordset
'---------------------------------------
'F1(A列),F2(B列)を抽出
'WHERE(条件) F2(B列)が1のデータを抽出
' F1(A列)で並べ替え
'---------------------------------------
sql = "SELECT" _
& " F1, F2" _
& " FROM [Sheet1$]" _
& " WHERE F2=1" _
& " ORDER BY F1"
rs.Open sql, cn, adOpenStatic
' 表示データクリア
Sheets("Sheet2").Range("A:D").Value = ""
curRow = 1
Do Until rs.EOF
Sheets("Sheet2").Range("A" & curRow).Value = rs!F1
Sheets("Sheet2").Range("B" & curRow).Value = rs!F2
rs.MoveNext
curRow = curRow + 1
Loop
MsgBox "処理を完了しました。" & vbCrLf & _
"件数:" & vbCrLf & curRow - 1
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) エクセル VBA 処理スピードを上げたいのですが。 6 2023/03/31 20:52
- Visual Basic(VBA) エクセルのマクロについて教えてください。 7 2023/07/04 09:18
- Visual Basic(VBA) エクセルのマクロを使ってメールを送る方法について教えてください 2 2022/03/29 01:36
- Visual Basic(VBA) VBAでoutlook365が起動しません。 4 2022/08/25 13:31
- Visual Basic(VBA) VBAが止まります。 3 2022/08/31 14:09
- PowerPoint(パワーポイント) エクセルのマクロについて教えてください。 1 2022/03/25 17:03
- Access(アクセス) ExcelのVBAコードについて教えてください。 4 2023/01/20 09:44
- Visual Basic(VBA) エクセルのマクロについて教えてください。 2 2023/07/06 17:46
- Excel(エクセル) エクセルのVBAにショートカットキーの割り当て 3 2022/07/13 14:19
- Visual Basic(VBA) エクセルのマクロについて教えてください。 1 2022/03/28 14:52
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【関数】スペースがいくつ入っ...
-
西暦や和暦の表示をyyyymmdd表...
-
Excelのセルを飛ばして入力する
-
Excelのオートフィル
-
別シートからの文字を変更
-
Excel 2019 のピボットテーブル...
-
エクセルの行の抽出について質...
-
【マクロ】エクセルにかいてあ...
-
スプレッドシート クエリ関数 1...
-
エクセルでセルに「氏名を入力...
-
MOS365 Excel Expert / Excel R...
-
excelの不要な行の削除ができな...
-
EXACT関数とIF関数の組み合わせ...
-
スプレッドシートの関数VLOOKUP...
-
Excelで全角を半角にしたいので...
-
Excel初心者です。 詳しい方、...
-
エクセルの数式で教えてください。
-
4つのパターンを表示するEXACT...
-
スマートな関数を教えて下さい。
-
【Excel】セル内の時間帯が特定...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ファイル内にある数字の出現回...
-
Excel関数の先頭に「@」が入っ...
-
エクセルの気味悪い不思議
-
Excel VBAで、実行時にsheet上...
-
表示されている人数だけを数え...
-
他人が作ったマクロの理解
-
Excelの関数について質問です。
-
Excel 集計表
-
エクセル 日時の計算式について
-
Excelの関数に関して質問です。...
-
エクセル:セル内の文字列の下...
-
絞り込み検索
-
エクセルの関数で
-
エクセルの書式設定について教...
-
余分なEXCELファイルに印刷され...
-
VBA 同一シート内での転記の仕方
-
長期休みの関数はありますか
-
Excelの空のセル
-
エクセルで入力してある文を別...
-
Excelのマクロで、セルを結合し...
おすすめ情報
ご回答ありがとうございます。
早速、コードを実行しましたところ、myStr = myStr & myR(i, j) & "_" でエラーになります。
何か、変更や追加しないといけなかったでしょうか。
ご面倒をおかけいたしますが、ご教授いただけますでしょうか。
ご面倒をおかけして申し訳ありません。
列は、A列からBO列まであり、登録日、お客様名、住所、発注番号、・・・、枝番、・・・です。
AV列が枝番です。
すみませんが、根本的な話で恐縮ですが、
教えていただきましたコードは、元データのどこからどこまでと交換するのでしょか。