

他所サイトのQ&Aです。行削除の下記3つの方法について
①Unionで溜めておき一気に削除。変数でなくSelectで溜める
②Unionで溜めておき一気に削除。変数で溜める
③最終行から1行ずつ削除
300行削除 いずれも0.2秒程度
3000行削除 ①②140秒 ③2秒
Unionを使う場合、処理行数が多くなると急激に遅くなります。なぜ?と言っても仕様なのだからしょうがない?③と同等または遅いくらいなのだから、Union使う意味ないように思えて来ました。これまでの自分の認識ではUnion一気削除の方が速いので、少々困惑気味です。
Sub ①()
t = Timer
Application.ScreenUpdating = False
Max = 10000
For i = 3 To Max
If i Mod 2 <> 0 Then
If i = 3 Then
Rows(i).Select
Else
Union(Selection, Rows(i)).Select
End If
End If
Next i
Selection.Delete shift:=xlUp
Application.ScreenUpdating = True
Cells(1, 1).Value = Timer - t
End Sub
Sub ②()
Dim rng As Range, i As Long
t = Timer
Max = 10000
Set rng = Cells(3, 1)
For i = 5 To Max Step 2
Set rng = Union(rng, Cells(i, 1))
Next i
rng.EntireRow.Delete
Cells(1, 2) = Timer - t
End Sub
Sub ③()
Dim i As Long
Dim Max As Long
t = Timer
Max = 10000
For i = Max To 3 Step -2
Rows(i).Delete
Next i
Cells(1, 3) = Timer - t
End Sub
No.2ベストアンサー
- 回答日時:
こんばんは。
あまり細かい所までは検討されていませんが、確かに、メモリの許容量というものが存在するのかもしれません。しかし、これほど細切れですと、Union でその都度取り込んでいくことに、オーバーヘッドが掛かって遅延化してくるのではないでしょうか?
以下は、Application.ScreenUpdating = False には、影響されませんが、なぜか、Select を使ったほうが速いようです。
メモリ自体の問題なら、以下の場合も問題が発生するように思うのです。
タイムは、
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
を使いました。
{④_A}: 3192
{④_B}: 2426
Sub ④_A()
With Range("A1").CurrentRegion
With .Columns(.Columns.Count + 1)
.FormulaLocal = "=IF(MOD(ROW(),2)=1,"""",1)"
.Value = .Value
.SpecialCells(xlCellTypeConstants, xlNumbers).EntireRow.Delete
End With
End With
Range("A1").Select
End Sub
Sub ④_B()
With Range("A1").CurrentRegion
With .Columns(.Columns.Count + 1)
.FormulaLocal = "=IF(MOD(ROW(),2)=1,"""",1)"
.Value = .Value
.SpecialCells(xlCellTypeConstants, xlNumbers).EntireRow.Select
End With
End With
Selection.Delete
Range("A1").Select
End Sub
'//
> Step 2 の場合に遅くなります。
この場合は、対象セルの移動自体に負荷がかかるのではないかと思うのです。
いつもありがとうございます。
1行おきに選択するため、unionのオーバーヘッドにより遅延するが理由のようですね。オーバーヘッドは知りませんでした。勉強になりました。
No.6
- 回答日時:
#5です
せっかくなので、
> SpecialCells を如何しても使いたいのであれば、
> 作業列で消したい行は空白、残したいものは行番号
> これでソートして・・・・
> 空白は後ろ1か所にまとまるので SpecialCells での領域数は1つ・・・
★ 部分が Samp1 からの変更点です
作業列内、消す行を空白にして、1行目は消しちゃいけないので 1 を設定
その後、全体を対象に作業列で昇順ソートして、
1個の領域になった空白部分を SpecialCells にて・・・
念のため、空白がない時用に On Error Resume Next
※ SpecialCells も対象が連続しているので速い・・・
Samp1 とあまり変わらない処理時間かと・・・
今回の様に、対象が飛びとびの状態で SpecialCells します?
実際に体感してみてください・・・
Public Sub Samp2()
Dim i As Long, j As Long
Const CF As String = "=IF(MOD(ROW(),2)=0,ROW(),"""")"
Application.ScreenUpdating = False
With ActiveSheet.UsedRange
Debug.Print .Cells.Address
i = 1 - .Cells(1).Row
j = .Columns.Count + 1
With .Offset(i).Resize(.Rows.Count - i, j)
With .Columns(j)
.Formula = CF
.Value = .Value
.Cells(1) = 1 ' ★
End With
.Sort .Cells(j), xlAscending, Header:=xlNo ' ★
With .Columns(j) ' ★
On Error Resume Next ' ★
.SpecialCells(xlCellTypeBlanks).EntireRow.Delete ' ★
On Error GoTo 0 ' ★
.ClearContents
End With
End With
End With
Application.ScreenUpdating = True
End Sub
No.5
- 回答日時:
#3です
今回のご質問は、消すことではなく・・・
> Unionはなぜ遅い
ですよね
消す方法の具体例を記述した方が良いのでしょうか?
ということで
> 他所サイトのQ&Aです。行削除の下記3つの方法について
他所サイトのQ&A は、以下だったでしょうか?
Vbaにて3行目以上の奇数行を削除するこーどをか
http://detail.chiebukuro.yahoo.co.jp/qa/question …
私は3つの方法以外で回答してました
#3で記述した 重複の削除 を使った方法を・・・
実際にやって・・・確認しやすいようにデータ作成も付けていたのに・・・
質問者さんには不評だったようです
こちらにも載せておきます
なお、確認用データ作成部分は 12万件 用に変えておきました
わかりにくそうなところを解説しておくと、
変数 i は、UsedRange は必ず A1 ~ 得られるものではないので
A1 ~ の範囲を対象にするための調整用
※ 今回は行方向だけを考えれば良いので、列方向は無視
変数 j は、作業用列
3行目からということで、1行目の空白だけが残れば・・・
※ バージョンによって 重複の削除 が使えない・・・なら、
SepcialCells の上限はある??・・・
・・・なら、他の方法を考える? 並び替えして領域数を減らす?
ちなみに、2007 では ④_B 実行で全部消えた・・・
なので、私の環境では比較はできませんが、以下 Samp1 は
12万行では、2 秒以下(列数によって若干変動)
2万行では 0.3 秒付近(列数によって若干変動)
Public Sub Samp1()
Dim i As Long, j As Long
Const CF As String = "=IF(MOD(ROW(),2)=0,ROW(),"""")"
Application.ScreenUpdating = False
With ActiveSheet.UsedRange
i = 1 - .Cells(1).Row
j = .Columns.Count + 1
With .Offset(i).Resize(.Rows.Count - i, j)
With .Columns(j)
.Formula = CF
.Value = .Value
End With
.RemoveDuplicates j, xlNo
.Columns(j).ClearContents
End With
End With
Application.ScreenUpdating = True
End Sub
' 確認用データ作成
Public Sub testData2()
Dim r As Range
Dim i As Long, j As Long
Const CRH As Long = 120000
Randomize
i = Int(4 * Rnd())
j = Int(10 * Rnd()) + 1
Application.ScreenUpdating = False
Cells.Delete
For Each r In Range("A1").Offset(i).Resize(2, j)
r.Value = r.Address(False, False)
Next
With Range("A1").Offset(i).CurrentRegion
.AutoFill .Resize(CRH)
End With
Columns.AutoFit
Application.ScreenUpdating = True
End Sub
※ Application.ScreenUpdating 使うのなら、上記の様に
セルに何か操作する部分も False ~ True で挟んだ方が良いと思います
No.4
- 回答日時:
こんにちは。
A B C D E
59444 43249 40485 52547 1 ←連番
12万行で同じく試してみました。
さすがに、Application.ScreenUpDating は加えました。
Sub ④_B()
With Range("A1").CurrentRegion
With .Columns(.Columns.Count + 1)
.FormulaLocal = "=IF(MOD(ROW(),2)=1,"""",1)"
.Value = .Value
.SpecialCells(xlCellTypeConstants, xlNumbers).EntireRow.Select
End With
End With
Application.ScreenUpdating = False
Selection.Delete
Application.ScreenUpdating = True
Range("A1").Select
End Sub
'//
120000 → 60000
④_B: 384135 (0:06:24)
SepcialCells については、実際、こちらでも試してみました。
Excel 2013 で、SpecialCells は、最後まで通りました。
http://www.excelguru.ca/blog/2009/07/23/excel-20 …
Excel 2010 Finally Fixes SpecialCells 8192 Limit
SpecialCells についての問題は、Excel 2007までで、Excel 2010では直ったと上記では書かれています。Excel 2007の問題については、他でも、Excel 2007専用に、特別あつらえしなければならないようです。
決して、上位バージョンがよいというわけではありませんが、Version ごとに問題が隠れていることがありますから、本来は、Version を言わないといけないこともあるのかもしれません。よくある話なのですが・・・。
No.3
- 回答日時:
Union の処理を推測すればわかると思いますよ
以下を記述して、実行してみると
Public Sub Samp1()
Dim rng As Range
Set rng = Range("B2")
Debug.Print rng.Address
Set rng = Union(rng, Range("B3"))
Debug.Print rng.Address
Set rng = Union(rng, Range("B4"))
Debug.Print rng.Address
Set rng = Union(rng, Range("C2"))
Debug.Print rng.Address
Set rng = Union(rng, Range("C3"))
Debug.Print rng.Address
Set rng = Union(rng, Range("C4"))
Debug.Print rng.Address
End Sub
表示されるのが以下
$B$2
$B$2:$B$3
$B$2:$B$4
$B$2:$B$4,$C$2
$B$2:$B$4,$C$2:$C$3
$B$2:$C$4
隣接する塊にしようという動きをするみたい??
個数が多くなれば、この処理に時間がかかるようになり・・・
という解釈では?
一気に削除するのなら、
作業列(行)を1つ使って、残す行には行番号、消す行は空白・・・
1行目が項目行なら、空白設定
項目行がなければ、1行目に行挿入・・・
全体を対象に、作業列で「重複の削除」
空白部分は先頭側の1個以外は重複で消えるので・・・
行挿入していたらその行消して、作業列綺麗にして・・・
これが速いと思います
SpecialCells という話もあるかもしれませんが、
これが扱える領域個数には上限(8192)があって、
大量のデータの時には使えない
SpecialCells を如何しても使いたいのであれば、
作業列で消したい行は空白、残したいものは行番号
これでソートして・・・・
空白は後ろ1か所にまとまるので SpecialCells での領域数は1つ・・・
ありがとうございます。
Unionされたセル範囲の中身確認は思い付きませんでした。対策は編集列を設けて重複削除、specialcellsと色々あるようですね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 数字が「0」の列を削除するため、下記のコードを実行しましたが、コンパイルエラーSubまたはFunct 3 2022/12/04 00:00
- Visual Basic(VBA) Excelで下記のようにマクロを作ったところ、一回目は実行できたのですが、二回目以降「実行時エラー1 1 2022/03/25 08:08
- Excel(エクセル) マクロで最終行から上に検索を逆にしたい 1 2022/05/17 18:27
- Visual Basic(VBA) VBA Userformで一部別シートに転記がしたいのですが 2 2023/05/24 13:08
- Excel(エクセル) VBAの指示の内容 昨日こちらでご教示頂いたのですが初心者な為、一つ一つの指示が何をやっているのかわ 2 2022/10/25 18:08
- Visual Basic(VBA) いつもお世話になっております、VBAで教えて頂きたいのですが 2 2022/05/05 22:20
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- Excel(エクセル) VBAで組み合わせ算出やCOUNTIFSの処理を高速化したいです。 4 2022/04/07 02:38
- Visual Basic(VBA) ExcelVBAに関する質問 3 2023/02/17 10:47
- Visual Basic(VBA) VBAで教えて頂きたいのですが? 1 2022/04/29 02:36
このQ&Aを見た人はこんなQ&Aも見ています
-
VBA 複数の行を高速で削除する方法
その他(プログラミング・Web制作)
-
EXCEL VBA マクロ 実行する度に処理速度がどんどん遅くなる原因が知りたい
Excel(エクセル)
-
エクセル:マクロ「Application.CutCopyMode = False」って?
Excel(エクセル)
-
-
4
Excelのセルの色指定をVBAから配列を用いて効率的に行う方法はあり
Visual Basic(VBA)
-
5
エクセルVBAのEntireRow.Hiddenをスピードアップしたいのですが・・・。
Excel(エクセル)
-
6
EXCELのVBAでシートコピーをしたとき元のマクロを削除するには?
Excel(エクセル)
-
7
VBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。
Excel(エクセル)
-
8
EXCEL マクロ 列の削除に時間がかかる
Excel(エクセル)
-
9
VBAのコマンドボタンの文字列の改行方法は?
Visual Basic(VBA)
-
10
エクセルVBA 罫線 処理時間短縮
Word(ワード)
-
11
ExcelのVBA。public変数の値が消える
Visual Basic(VBA)
-
12
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
-
13
Excel-VBA>コントロールをグレイアウトするには?
Excel(エクセル)
-
14
For~Next ループ内でUnionメソッドを使うとエラーになります。
Visual Basic(VBA)
-
15
VBAでシート書式の自動変換を作動させない方法
Excel(エクセル)
-
16
ExcelのVBAでGoToの代わりに…
Excel(エクセル)
-
17
VBA:ユーザーフォームのマルチページに色を付けたい。
Word(ワード)
-
18
エクセルのラベルの値(文字列)を垂直方向で中央揃えにするには?
Excel(エクセル)
-
19
エクセルVBAでRangeの引数制限?
Excel(エクセル)
-
20
エクセルVBA 配列からセルに「関数式」を一気代入したい
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセル 指定した文字列を含...
-
桁数が混在する並び替えの方法
-
エクセルで一部除外した数字を...
-
EXCELでマクロを用い日付をテキ...
-
Excelでの並べ替え
-
エクセルで合算後の降順がうま...
-
エクセルVBA Unionはなぜ遅い?
-
VLOOKUPで文字が反映さ...
-
データベースを検索するマクロ...
-
Excelで数値→文字列変換で指数...
-
Excelの関数について、特定の文...
-
テキストボックス内の文字のふ...
-
Excelで行ごとコピー、同じ行を...
-
エクセルにおける、グラフの指...
-
日付が1年以内になると他のセル...
-
たくさん作った同じ設定のグラ...
-
エクセルでグラフタイトルが折...
-
エクセル 入力中に表示されな...
-
【Excel】貼り付けた画像がいつ...
-
エクセル
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセル 指定した文字列を含...
-
桁数が混在する並び替えの方法
-
エクセルで一部除外した数字を...
-
EXCEL VBA 指定範囲内で特定の...
-
エクセルの関数SUBSTITUTEを、...
-
エクセルVBA Unionはなぜ遅い?
-
エクセル マクロで列を連続し...
-
ExcelVBA:列方向の並び替え O...
-
エクセルで列内の同じIDの商品...
-
エクセルで同じ名前ごとの合計...
-
EXCEL 指定した曜日に番号を振...
-
エクセルvba 一つ上の行を指定...
-
VBAでFormula関数を使ってVlook...
-
エクセルの質問(結合と集計に...
-
エクセルで2列を検索し2列とも...
-
EXCELである列を上から順にチェ...
-
エクセル2003で住所録の抽出
-
Excel 複数キーワードの確認方法
-
エクセルマクロでA欄に値があ...
-
エクセルのVLOOKUP関数の応用
おすすめ情報
問題の詳細が判明しました。
>For i = 5 To Max Step 2
For i = 5 To Max だと短時間です。つまりStep 2 の場合に遅くなります。処理回数は半分になる筈なのに。Step 3にすると30秒、、、