複数の列を高速で削除する方法で悩んでおります。
別々の4つのシートに71個の同じ項目が用意されています。
ユーザーの設定で欲しい項目のみ表示させたいと思っております。
以下使用しているコードの内容です。
--------------------------------------------------------------------
Sub HideRun()
Dim cnt As Integer
Dim HinagaraRan As Range
Dim CompRan As Range
Dim ProRan As Range
Dim SetRan As Range
cnt = 71
'非表示の設定を格納
Do While cnt <> 0
If HideMember(cnt) <> 0 Then
If HinagaraRan Is Nothing Then
Set HinagaraRan = TergetHinagataSheets.Columns(HideMember(cnt))
Set CompRan = TergetCompletionSheets.Columns(HideMember(cnt))
Set ProRan = TergetProvisionalSheets.Columns(HideMember(cnt))
Set SetRan = TergetSetSheets.Columns(HideMember(cnt))
Else
Set HinagaraRan = Union(HinagaraRan, TergetHinagataSheets.Columns(HideMember(cnt)))
Set CompRan = Union(CompRan, TergetCompletionSheets.Columns(HideMember(cnt)))
Set ProRan = Union(ProRan, TergetProvisionalSheets.Columns(HideMember(cnt)))
Set SetRan = Union(SetRan, TergetSetSheets.Columns(HideMember(cnt)))
End If
End If
cnt = cnt - 1
Loop
HinagaraRan.EntireColumn.Delete
CompRan.EntireColumn.Delete
ProRan.EntireColumn.Delete
SetRan.EntireColumn.Delete
End Sub
--------------------------------------------------------------------
問題なのがSetRan.EntireColumn.Deleteの実行がやたら時間がかかってしまっています。
(※TergetSetSheetsはデータが60000件入っております)
他のシートは削除に時間がかからない為、データ件数が影響しているのではないかと考えSetRan.EntireColumn.Clearを加えて列の削除前にデータの削除を行いましたが、遅くなりました;
現在の処理のスピードです。
データ数:65535件 処理速度:14.89063秒
データ数: 9409件 処理速度:14.84375秒
となっています。
この内容からもデータ件数による影響はあまり関係ないのではないかと思っています。
となると私のコードの書き方に問題があると思い質問いたしました。
何かいい方法がありましたらお力を貸してください。
宜しくお願いいたします。
No.1ベストアンサー
- 回答日時:
速くなるかわかりませんが、作業用に1行使えるものとします
以下は、前回の質問での、行・列 の違いだけです
削除を指示する配列は Variant で、削除する所に 1 を設定しておきます。
(設定しない所の初期状態 Empty も利用)
(配列添え字=列位置にしておく)
・対象シート1行目に1行挿入
・挿入した行に削除指示配列をそのまま代入
・1行目の 1 を特定して .EntireColumn.Delete
・作業用の行を削除して
をシート分繰り返す
Samp1 は雰囲気
Option Explicit
Public Sub Samp1()
Dim vA As Variant, v As Variant
ReDim vA(1 To 71)
vA(2) = 1
vA(5) = 1
vA(6) = 1
vA(8) = 1
vA(15) = 1
vA(16) = 1
For Each v In Array("Sheet1", "Sheet2", "Sheet3", "Sheet4")
With Worksheets(v)
.Rows(1).Insert
With .Rows(1)
.Cells(1).Resize(, UBound(vA)) = vA
.SpecialCells(xlCellTypeConstants, xlNumbers) _
.EntireColumn.Delete
.EntireRow.Delete
End With
End With
Next
End Sub
※ 列が 71 しかないのなら
> With .Rows(1)
> .Cells(1).Resize(, UBound(vA)) = vA
↓
With .Cells(1).Resize(, UBound(vA))
.Value = vA
でも・・・
※ この記述にしておいたのは、
配列 HideMember (1 ~ 71) の内容がどうなっているのかわからなかったため
これを元に、提示あった変数等を使ってみると
Public Sub Samp2()
Dim vA As Variant, v As Variant
Dim i As Long
vA = Array(TergetHinagataSheets, _
TergetCompletionSheets, _
TergetProvisionalSheets, _
TergetSetSheets)
For Each v In vA
With v
.Rows(1).Insert
With .Rows(1)
For i = 1 To 71
If (HideMember(i) <> 0) Then
.Columns(HideMember(i)).Rows(1) = 1
End If
Next
.SpecialCells(xlCellTypeConstants, xlNumbers) _
.EntireColumn.Delete
.EntireRow.Delete
End With
End With
Next
End Sub
※ 未検証
※ 配列 HideMember の中身はどうなっているのでしょう
列位置を数値にしたもの? 3 とか?
文字列のまま? "B" とか?
範囲を示す? "D:F" とか?
一応、これらのパターンどれでも動くと思います
ReDim vA(1 To 71)
vA(2) = 2
vA(5) = "D:F"
vA(6) = "J:L"
vA(8) = "O"
で
For i = 1 To 71
If (vA(i) <> 0) Then
.Columns(vA(i)).Rows(1) = 1
End If
Next
した時には If でエラーにならず、動きましたが・・・
内容によって良さそうな記述に変更してください。
.Columns(vA(i)).Rows(1) で良いのか・・・とか
※ 上記処理では1行目に挿入していますが、シートの構成で
他セルを参照する計算式等が埋め込まれていたら遅くなると思います。
その時には、行位置を変更しない 最終行+xx の所を作業用にすれば良いと思います。
※ SpecialCells を使っているので、想定量?でしっかり検証してください
前回の SpecialCells.EntireRow.Delete では、ある程度分割しないとおかしくなってたので・・・
SpecialCells.EntireColumn.Delete する時も、分割処理が必要?かも??
蛇足になりますが、
前回質問の記述で xls 行ぎりぎりまで使われると思っていなかったので、処理の抜けがあります。
たぶん、65001 ~ 65534 内は削除されていなかったと思います。
> 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
↓
Dim j As Long を宣言しておいてから
On Error Resume Next
j = iRowH Mod CLIMIT
If (j = 0) Then j = CLIMIT
For i = (iRowH - 1) \ CLIMIT To 0 Step -1
.Cells(i * CLIMIT + 1).Resize(j) _
.SpecialCells(xlCellTypeConstants, xlNumbers) _
.EntireRow.Delete
j = CLIMIT
Next
の方が良いかと・・・
回答は最終形ではないので、検証はしっかりと行ってください。
30246kikuさん
度々回答ありがとうございます。
前回の回答に対するアドバイスもしていただき勉強になりました。
また今回の問題に対しての対策を行ってみたところ処理速度はあまり変化がありませんでした。
他の方法でなにかないか模索してみたいと思います。
No.3
- 回答日時:
まだ解決しませんか。
うまくいくかは実験してみてください。
Deleteは、エクセルでも結構負担になる動作です。
関数でもかかっていたらなおさらです。
一案ですが
71列程度であれば
必要な列をその都度、別シートに追加した方が早いかと
No.2
- 回答日時:
#1です
ダメもとで、現状の処理を以下記述で挟んでみてどうなりますか
Application.Calculation = xlCalculationManual
~ 現状の処理
Application.Calculation = xlCalculationAutomatic
実際にはシートはその4つだけではなくて、
他シートから参照されていたり・・・・とかあったりして?
その場合には速くなるかも?
また、Change イベント等処理を記述していたら、
イベントを抑止してからやってみるとか
30246kikuさん
返信遅くなり申し訳ありません。
特に参照させていないのであまり変化が得れませんでした;
今回はデーター量が大きい場合は処理前に時間がかかる処理だとアナウンスを置くこととプログレスバーの設置で対応してみます;
エクセルのバージョンに左右されないためになるべく関数などは使用しない方向で作成したいと思っていました。
30246kikuさんのアドバイスは望んだ結果ではなかったですが手法としてとても勉強になりました。
なのでベストアンサーとして選ばさせていただきたいと思います。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 配列の勉強をしています。使用する変数の意味、検索条件の書き方が難しいです。 2 2022/09/15 14:06
- Visual Basic(VBA) 【前回の続き続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/24 20:49
- Visual Basic(VBA) オブジェクトが見つかりません 1 2023/06/24 19:43
- Visual Basic(VBA) エクセルVBAコピー 2 2022/06/08 21:45
- Visual Basic(VBA) 【ご教示ください】VBAの記述方法がわかりません。 2 2022/08/12 21:28
- Visual Basic(VBA) Dateserialで データ抽出 2 2022/06/26 21:07
- Excel(エクセル) VBAで組み合わせ算出やCOUNTIFSの処理を高速化したいです。 4 2022/04/07 02:38
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- Visual Basic(VBA) エクセルVBAのコードで質問です。 下のコードはJ16の文字列をB3を起点とする範囲から探して、見つ 5 2023/04/07 11:07
- Visual Basic(VBA) 【前回の続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/16 16:44
このQ&Aを見た人はこんなQ&Aも見ています
-
新NISA制度は今までと何が変わる?非課税枠の拡大や投資対象の変更などを解説!
少額から投資を行う人のための非課税制度であるNISAが、2024年に改正される。おすすめの銘柄や投資額の目安について教えてもらった。
-
EXCEL マクロ 列の削除に時間がかかる
Excel(エクセル)
-
エクセルVBA Unionはなぜ遅い?
Visual Basic(VBA)
-
VBA 複数の行を高速で削除する方法
その他(プログラミング・Web制作)
-
-
4
エクセルでエラーが出て困っています。
Excel(エクセル)
-
5
Excelでのセル内容の高速消去方法
その他(プログラミング・Web制作)
-
6
エクセルの行の削除を配列で高速化したい
その他(Microsoft Office)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAで繰り返しコピーしながら下...
-
ExcelのVlookup関数の制限について
-
オートフィルタ使用時にCOUNTIF...
-
文字の色も参照 VLOOKUP
-
【条件付き書式】countifsで複...
-
Excel の複数シートの列幅を同...
-
エクセルで横並びの複数データ...
-
エクセルVBA 行追加時に自...
-
エクセルの列の限界は255列以上...
-
エクセルの保護で、列の表示や...
-
VLOOKアップ関数の結果の...
-
【VBA】ピボットテーブルを既存...
-
excel 複数のシートの同じ場所...
-
Excelでの並べ替えを全シートま...
-
エクセル マクロ 標準モジュー...
-
エクセル関数に詳しい方、教え...
-
Excel VBA ピボットテーブルに...
-
SUMPRODUCTにて別シートのデー...
-
スプレッドシートでindexとIMPO...
-
シートをまたぐ条件付き書式に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ExcelのVlookup関数の制限について
-
文字の色も参照 VLOOKUP
-
オートフィルタ使用時にCOUNTIF...
-
エクセルの保護で、列の表示や...
-
VBAで繰り返しコピーしながら下...
-
Excel の複数シートの列幅を同...
-
【VBA】シート名と見出しが一致...
-
エクセルで横並びの複数データ...
-
エクセルの列の限界は255列以上...
-
Excelでの並べ替えを全シートま...
-
【条件付き書式】countifsで複...
-
VLOOKアップ関数の結果の...
-
Excel VBA ピボットテーブルに...
-
エクセル マクロ 標準モジュー...
-
Excelで、ファイル名、シート名...
-
エクセルで、チェックボックス...
-
【VBA】複数のシートの指定した...
-
エクセルVBAで、ある文字を含ん...
-
スプレッドシートでindexとIMPO...
-
SUMPRODUCTにて別シートのデー...
おすすめ情報