
以前、質問で複数の行をRangeに格納し一括で削除する方法を教えていただきました。
実践したコードが以下の通りです。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
'Unionで指定の行を複数格納
For i = TergetSetSheets.Range("Y" & Rows.Count).End(xlUp).Row To 7 Step -7
If SetRan Is Nothing Then
Set SetRan = TergetSetSheets.Rows(i - p)
Else
Set SetRan = Union(SetRan, TergetSetSheets.Rows(i - p))
End If
Next
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
500行くらいなら0.03秒くらいで処理できていたのですが、
4700行で6.8秒、9400行で52秒になりました。
※描写は停止にしています。
これ以上早く処理を行うことはできるのでしょうか?
なるべくなら行の削除を行いたいと思っています。
なぜなら表の集計をこの後に行うのにあらかじめ不要な行を先に削除しておくことにより
処理速度が上がるのではないかと思っているからです。
いい方法がありましたら知恵を貸してください。
どうかよろしくお願いいたします。

No.2ベストアンサー
- 回答日時:
まず現行マクロの改良としては、「オブジェクトに触る回数を少なくする」
TergetSetSheetsこれはワークシートだと思いますが、ループ内で9000行処理するなら9000回同じシート名を指定することになり、低速化の原因になります。下記のようにすると指定が省略されて速く、しかも見た目スッキリで可読性が上がります。
With TergetSetSheets
For i = .Range("Y" & Rows.Count).End(xlUp).Row To 7 Step -7
If SetRan Is Nothing Then
Set SetRan = .Rows(i - p)
Else
Set SetRan = Union(SetRan, .Rows(i - p))
End If
Next
End With
SetRanはセルではなく行のようですね。遅くなりませんか?1セルだけであっても、一括削除する際にEntireRowとすれば行になりますよ。この比較は私もしたことがないので、確信持っては言えませんが。
次に、削除せず残す方に規則性があるなら、Autofilterを使う方法があります。マクロでなく通常の手動操作でもフィルタがありますが、あれです。あれで削除する行「以外」が表示されるようにして、全選択→コピー→別シートにペースト これでも速いです。これを考えると、手動でもいいんじゃないの?とか藪蛇な思いがあります(笑)
Union の後で一括deleteもAutofilterもそうですが、エクセルでは一気に選択、一気に処理するのが速いです。乱暴に言うと一行ステートメントで「一括処理」するのが速いのです。その意味ではFor Nextループは一回ずつ順番に9000回処理するため、低速化の一因になります。しかし今回の場合、やらない訳には行きませんので残してます。
老婆心ながら、エクセルVBAの質問なら、カテゴリはVisual Basicまたはエクセルが良いです。
回答者1の30246kikuさんの対策とHigh_Scoreさんの対策を試してみました。
----------------------------------------------------------------
データ数 588 9408 65534
従来 0.046875 50.20313 終わらない
対処1 0.0390625 51.44531 終わらない
対処2 0.05078125 52.30859 終わらない
AutoFilter 0.4765625 0.7578125 8.277344
30246kikuさん 0.2070313 0.90625 35.40234
----------------------------------------------------------------
※対処1:オブジェクトに触れる回数を減らす
※対処2:Rowではなくセル指定
以上のような結果になりました。
今回は実装が簡単で処理が速いオートフィルターを使用してみたいと思います。
コピー後の貼り付けでフィルターで除外されたものはコピーされないとは知りませんでした;(非表示だからそのままコピーされるのかと思っていました;)
あと今後もVBAで質問があるときはカテゴリに気を付けたいと思います。
とても勉強になりました。
ありがとうございます。
No.1
- 回答日時:
> 例:
> A B
> 1 太郎 住所
> 2 電話
> 3 メールアドレス
> 4 誕生日
> 5 年齢
> 6 性別
> 7 既婚
> 8 花子 住所
> 以下続く
この7行が繰り返されていて、
例えば、年齢、既婚 部分の行を一気に消したい・・・
という事で良かったでしょうか
作業列として、今使っている最終列+2の所の列を使います。
その作業列に
=IF(INDEX({0,0,0,0,1,0,1},MOD(ROW()-1,7)+1)>0,1,"")
という計算式を埋め込んで、削除する行を特定します。
{0,0,0,0,1,0,1} このパターンは、
左から、住所、電話・・・に対応していて、削除したい所を > 0 で設定します。
{0,0,0,0,1,0,1}
↓誕生日も削除対象にするのなら、左から4つ目の 0 を変更
{0,0,0,1,1,0,1}
以下の Samp1 でどうなりますか?
Option Explicit
Public Sub Samp1()
Dim iRowH As Long, iCol As Long
Dim i As Long
Const CLIMIT As Long = 5000
With ActiveSheet
With .UsedRange
With .Cells(.Rows.Count, .Columns.Count)
iCol = .Column + 2
iRowH = .Row
End With
End With
With .Cells(1, iCol).Resize(iRowH)
.Formula = _
"=IF(INDEX({0,0,0,0,1,0,1},MOD(ROW()-1,7)+1)>0,1,"""")"
.Value = .Value
On Error Resume Next
For i = (iRowH - 1) \ CLIMIT To 0 Step -1
.Cells(i * CLIMIT + 1).Resize(CLIMIT) _
.SpecialCells(xlCellTypeConstants, xlNumbers) _
.EntireRow.Delete
Next
.ClearContents
End With
End With
End Sub
※ 速くならなかったらごめんなさい
※ ScreenUpdating 等は必要に応じて追加してください
なお、確認用データは以下で作ってました
Public Sub testData()
Dim r As Range
For Each r In Range("A1:Z30000")
r = r.Address(False, False)
Next
Columns.AutoFit
End Sub
回答ありがとうございます。
歴然と速くなりました!!
またとても勉強になりました。
今後VBAでプログラムを行うときは参考にさせていただきます。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 数字が「0」の列を削除するため、下記のコードを実行しましたが、コンパイルエラーSubまたはFunct 3 2022/12/04 00:00
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
- Visual Basic(VBA) 【VBAエラー】Nextに対するForがありません 対策について 5 2022/11/21 21:26
- Excel(エクセル) マクロで最終行から上に検索を逆にしたい 1 2022/05/17 18:27
- Excel(エクセル) マクロで行を追加、削除すると行位置がずれますが、解決方法はありませんか?。 5 2022/05/28 16:03
- Excel(エクセル) VBAで組み合わせ算出やCOUNTIFSの処理を高速化したいです。 4 2022/04/07 02:38
- Visual Basic(VBA) VBA 行削除した連番 4 2023/06/27 16:00
- Visual Basic(VBA) 3つの条件を指定してVBAで行を削除したい 条件1:分類1が重複 条件2:分類2が重複 条件3:個数 6 2022/06/24 11:07
- Visual Basic(VBA) Excelで下記のようにマクロを作ったところ、一回目は実行できたのですが、二回目以降「実行時エラー1 1 2022/03/25 08:08
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
このQ&Aを見た人はこんなQ&Aも見ています
-
エクセルVBA Unionはなぜ遅い?
Visual Basic(VBA)
-
EXCEL マクロ 列の削除に時間がかかる
Excel(エクセル)
-
VBA 複数の列を高速で削除する方法
Excel(エクセル)
-
-
4
VBAで文字列を数値に変換したい
Excel(エクセル)
-
5
エクセル:マクロ「Application.CutCopyMode = False」って?
Excel(エクセル)
-
6
excelの不要な行の削除ができない!
Excel(エクセル)
-
7
エクセルVBAで5行目からオートフィルタモードに設定したいたい
Excel(エクセル)
-
8
Excelでのセル内容の高速消去方法
その他(プログラミング・Web制作)
-
9
Excel VBA データ削除の高速化
その他(Microsoft Office)
-
10
VBA .Value=.Value ?
Excel(エクセル)
-
11
EXCEL VBA マクロ 実行する度に処理速度がどんどん遅くなる原因が知りたい
Excel(エクセル)
-
12
エクセルでの列、行の挿入、削除に時間がかかるようになったが・・。
Excel(エクセル)
-
13
B列の最終行までA列をオートフィル
Visual Basic(VBA)
-
14
ExcelのVBAで連番を振る。
Excel(エクセル)
-
15
エクセル VBA シートのコピー
その他(プログラミング・Web制作)
-
16
マクロで#N/A"のエラー行を削除したい"
Visual Basic(VBA)
-
17
基準日以前のデータを範囲を指定して削除するVBA
Excel(エクセル)
-
18
【Excel VBA】複数ある特定の文字列を含む行を削除
Excel(エクセル)
-
19
【VBA】条件に一致しない行を削除したい
Visual Basic(VBA)
-
20
エクセルVBA 4行飛ばしで転記するループ処理
Excel(エクセル)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ExcelのVBAで、選択したファイ...
-
指定時間にプリントアウトする方法
-
マクロの解読に困っています
-
複数の関数の中から戻り値の戻し方
-
ドリブン??
-
VBA フォルダ内の全てブックの...
-
エクセル 複数の文字を同時に検...
-
vbaのエラー対応(実行時エラー...
-
UWSファイルを VBで実行させたい
-
VBS mdb参照時にテーブルor列が...
-
AVIFileInitに関して
-
VBS 処理中の中断処理
-
VBA Vlookup #N/A表示させない方法
-
SQLの条件式
-
RaiseEventのメリット
-
access2010 マクロで...
-
Javaについての質問なんですが…
-
UWSCのTHREADについて
-
「内部処理形式 String の Vari...
-
2つのシートの任意のセルの番号...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【C#/Java?】try-catchでcatch...
-
vbaのエラー対応(実行時エラー...
-
private subモジュールを他のモ...
-
マクロで、次のコードへ行く前...
-
シグナル 6(SIGABRT)とは?
-
特定の名前のオートシェイプの...
-
IF文に時間(何時から何時ま...
-
どう増強すべきか
-
特定のファイルを他のプロセス...
-
Word VBA。各マクロの間に待ち...
-
どうやってもFor文を抜けてしま...
-
Excel VBA セルの名前があるか...
-
ExcelのVBAで、選択したファイ...
-
【C#】Page_Loadさせない方法に...
-
StatusStripの表示が更新されな...
-
途中で処理を中断させたい (ア...
-
エクセル VBAで複数セル選択時...
-
Functionで戻り値を複数返す方法
-
VBAでBook読み込み時の非表示方...
-
VBA 複数の行を高速で削除する...
おすすめ情報