シート2のボタンをクリックすると
Sub 編集が起動します。
Sub 編集にはCallで2種類のプロシージャーを
呼び出します。
シート1には約20,000行のデータがあります。
処理に約2分かかっています。
もう少し高速にする方法は
有りますでしょうか?
プロシージャーは分けておきたいです。
シートに式は入れたくありません。
Sub 編集にはCall文でさらに別のプロシージャーを5個呼び出しますが
F8キーで確認すると、それらは秒速で処理されてました。
一番時間がかかっているのがこの部分なので
この部分を対策したいです。
よろしくお願いします。
Sub 編集()
Call 検索キー
Call 日付02
Sheets("シート1").Select
Range("R1") = "キー"
Range("S1") = "日付"
Columns("B:B").Select
Selection.Delete Shift:=xlToLeft
Columns("F:F").Select
Selection.Delete Shift:=xlToLeft
Columns("H:O").Select
Selection.Delete Shift:=xlToLeft
Range("A1").Select
MsgBox "編集終了"
Sheets("シート2").Select
End Sub
Sub 検索キー()
'2010年11月17日
'R列にC,D,E列を連結させた値を転記
Sheets("シート1").Select
行 = 2
Do
If Cells(行, 1).Value = "" Then Exit Do
Cells(行, 18).Value = Cells(行, 3) & Cells(行, 4) & Cells(行, 5)
行 = 行 + 1
Loop
End Sub
Sub 日付02()
'2010年11月17日
'A列の値、半角数字8桁を下4桁で
'2桁目に/を入れてS列に転記(セルの値もセル表示も)
'例:A列20101117 S列 11/17
'セルの値が2010/11/17でセルの表示が11/27は不可
Sheets("シート1").Select
For 行 = 2 To Cells(Rows.Count, "A").End(xlUp).Row
With Cells(行, 19)
.NumberFormat = "@"
.Value = Format(Cells(行, 1), "!@@/@@")
End With
Next
End Sub
No.8ベストアンサー
- 回答日時:
>..Sub test1を改造して
>これで動きましたが記述があっているか不安です。
あってますよ。
コメントは
>'計算式をA2に入れてコピー。出た値を値貼付
貼付というより
'計算式をA2に入れてコピー。計算式を値化。
がしっくりくるかも。
.Range(..).Value = .Range(..).Value
左辺のセル範囲の.Valueプロパティに右辺のセル範囲の.Valueをセットする、
という認識でいいと思います。
ついでに書いておきますと
Sub test10()
Dim mx As Long
Dim i As Long
Dim v
Dim w() As String '書き出し用
With Sheets("シート●")
'D最終行:F2の値を配列に取る
v = .Range("F2", .Cells(.Rows.Count, 4).End(xlUp)).Value
mx = UBound(v)
'必要サイズの配列を準備。
ReDim w(1 To mx, 1 To 1)
'Loop処理
For i = 1 To mx
w(i, 1) = v(i, 1) & v(i, 2) & v(i, 3)
Next
'書き出し
With .Range("■").Resize(mx)
.ClearContents
.NumberFormat = "@"
.Value = w
End With
End With
Erase w
End Sub
Sub test20()
Dim mx As Long
Dim i As Long
Dim v
Dim w() As String '書き出し用
With Sheets("シート●")
'A2:A最終行の値を配列に取る
v = .Range("A2", .Cells(.Rows.Count, 1).End(xlUp)).Value
mx = UBound(v)
'必要サイズの配列を準備。
ReDim w(1 To mx, 1 To 1)
'Loop処理
For i = 1 To mx
w(i, 1) = Format$(v(i, 1), "!@@/@@")
Next
'書き出し
With .Range("■").Resize(mx)
.ClearContents
.NumberFormat = "@"
.Value = w
End With
End With
Erase w
End Sub
20,000行程度だったら
Sub test1改造() と Sub test10() は速度的には大差ないと思います。
この回答への補足
ありがとうございます。
Sub test10( )
は本スレッドの質問とは別の
(1)A列にD,E,Fの値を連結して転記
に流用する為に、教えていただいた記述を私が変更した→Sub test1改造
の配列型版?でいいのですよね。
↓↓
別ファイルで Sub test1改造 と入れ替えて問題なく動きました。
Sub test20( ) は本スレッドの質問の
(2)R列にC,D,E列の値を連結して転記
(3)S列にA列の日付を編集して転記
(4)プロシージャーを分けたい
に対して(2)(3)を同時に処理を行う記述の Sub test2( )を
(3)のみにした物 (別途 列削除と項目名転記部分は除く) ですよね。
ちなみに Sub test2( ) を(2)と(3)に分ける場合は
・Sub test10( )を記述変更
・Sub test20( )はそのまま
でいいと思い、
Sub test10( )を
A列にD,E,Fの値を連結して転記
↓↓
R列にC,D,Eの値を連結して転記
に修正して
Sub test10改造( )
'2010年11月23日
'R列にC,D,E列を連結させた値を転記
'配列型
'最高速型
Dim mx As Long
Dim i As Long
Dim v
Dim w() As String '書き出し用
With Sheets("シート1")
'●C最終行:E2の値を配列に取る
v = .Range("E2", .Cells(.Rows.Count, 3).End(xlUp)).Value
mx = UBound(v)
'必要サイズの配列を準備。
ReDim w(1 To mx, 1 To 1)
'Loop処理
For i = 1 To mx
w(i, 1) = v(i, 1) & v(i, 2) & v(i, 3)
Next
'●書き出し
With .Range("R2").Resize(mx)
.ClearContents
.NumberFormat = "@"
.Value = w
End With
End With
Erase w
End Sub
↓↓
Sub test10改造( )
Sub test20( )
と並べて動作させて
↓↓
Sub test2( )
と同じ結果でした。(記述の変更はこれでいいのですよね。)
本スレッドの質問のファイルは、もうプロシージャーを分ける必要が無くなりましたので
全て連結させたいただきました
Sub test2( ) を使用し
プロシージャーを分けたかった理由である別ファイルの方は今回教えていただいた
Sub test10( )
で行います。
ありがとうございました。
速くなりました。
本スレッドの質問
・R列にC,D,E列の値を連結した値を転記
・S列にA列の日付を編集してS列に転記
にて20,000行の状態で
私の記述では最初は約25秒でした。
Sub test2
のおかげで1秒以内になりました。
・R列にC,D,E列の値を連結した値を転記
→A列にD,E,F列の値を連結した値を転記 に流用したい
>20,000行程度だったら
>Sub test1改造( ) と Sub test10( ) は速度的には大差ないと思います。
↓↓
最初は私の記述で約2分。
別スレッドで教えていただいた
VLOOKUPの高速化(別方法)で6秒になり、
(別方法の部分自体は0.1秒)
Sub test1改造( )→ Sub test10( ) に変更で
3秒まで短縮されました。
(Sub test10自体は0.1秒くらい)
またコメントの方も教えていただきまして感謝いたします。
本スレッドの質問も高速化され、別ファイルへの流用まで高速化できました。
どうもありがとうございました。
No.7
- 回答日時:
>計算式を貼り付けて、出た値を値貼付した方が
>早いのかな?ですが
サンプルとしてはこんな感じです。
Sub test1()
With Sheets("シート1")
With .Range("R2", .Cells(.Rows.Count, 1).End(xlUp).Offset(, 17))
.NumberFormat = "general"
.Formula = "=C2&D2&E2"
.NumberFormat = "@"
.Value = .Value
End With
End With
End Sub
提示された情報でまとめてみると
Sub test2()
Dim mx As Long
Dim i As Long
Dim v
Dim w() As String '書き出し用
Dim t As Single
t = Timer
'Applicationプロパティを制御。定番です。
With Application
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlCalculationManual
End With
With Sheets("シート1")
'A最終行:E2の値を配列に取る
v = .Range("E2", .Cells(.Rows.Count, 1).End(xlUp)).Value
'添字最大値(セルから配列に取った場合最少値は1)
mx = UBound(v)
'必要サイズの配列を準備。
ReDim w(1 To mx, 1 To 2)
'Loop処理
For i = 1 To mx
w(i, 1) = v(i, 3) & v(i, 4) & v(i, 5)
w(i, 2) = Format$(v(i, 1), "!@@/@@")
Next
'書き出し
With .Range("R2:S2").Resize(mx)
'String配列を書き出す時は既データをClearContentsしたほうが速い
.ClearContents
.NumberFormat = "@"
.Value = w
End With
.Range("B:B,G:G,J:Q").Delete
End With
With Application
.Calculation = xlCalculationAutomatic
.EnableEvents = True
.ScreenUpdating = True
End With
Erase w
Debug.Print Timer - t
End Sub
こんな感じになるでしょうか。
>'Applicationプロパティを制御。定番です。
元のコードにこの制御を加えるだけでも改善すると思われます。
この回答への補足
大変ありがとうございました。
スレッドの質問にて
「2つのプロシージャーは分けておきたい」
と書いたのは別なものに流用したかったからです。
Sub test2
の中には
Sub test1
が組み込まれています。
今回は一番高速なSub test2を使用させていただきます。
今回のやりたかった事は
・R列にC,D,E列を結合した値を転記
・S列に日付を転記
でした。
で今回の質問とは別なファイルは、
A列にD,E,F列を結合した値を転記だけで
日付の転記は無いです。
教えていただいたSub test1を改造して
これで動きましたが記述があっているか不安です。
↓↓↓↓
Sub test1改造()
'2010年11月22日
'A列にD,E,F列の結合した値を転記
'計算式をA2に入れてコピー。出た値を値貼付
With Sheets("シートZ")
'式を入れる場所はセルA2。
'最終データがある行の確認を行うのは4=D列。Rows.Countは4。
'式を入れるのはA列なのでD列より左3つ。よってOffsetは-3。
With .Range("A2", .Cells(.Rows.Count, 4).End(xlUp).Offset(, -3))
.NumberFormat = "general"
.Formula = "=D2&E2&F2"
.NumberFormat = "@"
.Value = .Value
End With
End With
End Sub
これよりもSub test2の方が高速なので
Sub test2から日付転記部分を除去しSub test1の部分だけを
改造しようと挑戦しましたが私の技量では、うまくできませんでした。
Sub test2の改造は私では出来ませんでした。
取り合えず高速化は出来ましたので、どうもありがとうございました。
No.6
- 回答日時:
若干早くなった程度ですか・・・。
2000では5千ちょっとしか対応できないTransposeを使っているので20000件は試せませんが、5000件でやったところ
Sub 日付02()は 00:00:04
Sub 日付03()は 00:00:00
でした。
Sub 検索キー() 00:00:02
Sub 検索キー02() 00:00:01
です。
そんなに時間がかかるなら別の原因がありそうですね。
わざわざすいません。
Sub 検索キーのほうですが
セルR2
に式を入れて、オートフィルだと
秒速です。
計算式を貼り付けて、出た値を値貼付した方が
早いのかな?ですが
その記述を書けません。(ToT)/~~~
これは
シート2~6までデータが有って
その内容を全てシート1に貼り付けて
この2個のプロシージャーを走らせてシート1の値を編集しています。
ファイルサイズは15Mもあります。
とりあえず、シート2~6までは不要なので
削除してシート1だけにしたら
40秒に短縮されました。
No.5
- 回答日時:
失礼、Sub 日付02() もFor Nextでまわしてるんでしたね。
では、これも配列に取り込みます。
Sub 日付03()
Dim myRng As Range
Dim myAr, myBr
Dim i As Long
With Sheets("シート1")
Set myRng = .Range(.Cells(2, "A"), .Cells(Rows.Count, "A").End(xlUp))
myAr = myRng.Value
ReDim myBr(LBound(myAr, 1) To UBound(myAr, 1))
For i = LBound(myAr, 1) To UBound(myAr, 1)
myBr(i) = Format(myAr(i, 1), "!@@/@@")
Next i
myRng.Offset(, 18).NumberFormat = "@"
myRng.Offset(, 18).Value = Application.Transpose(myBr)
End With
End Sub
No.4
- 回答日時:
LOOPは Sub 検索キー ですね。
配列に取り込むならこんな感じかな。
エクセル2003でしたよね?
2000だとエラーになります。
Sub 検索キー02()
'R列にC,D,E列を連結させた値を転記
Dim myV
Dim myW
Dim x As Long, i As Long
With Sheets("シート1")
myV = .Range(.Cells(2, "A"), .Cells(2, "A").End(xlDown)).Resize(, 5).Value 'データを配列変数myVに
x = UBound(myV, 1) '行数取得
ReDim myW(1 To x)
For i = LBound(myV, 1) To UBound(myV, 1)
myW(i) = myV(i, 3) & myV(i, 4) & myV(i, 5) '結合データを配列変数myWに
Next i
.Cells(2, 18).Resize(x, 1).Value = Application.Transpose(myW) '転記
End With
End Sub
ありがとうございます。
数値を文字列としての問題があって
値が9.01+Eとかなる場合がありました。
先頭に(Dim myVの前)
Sheets("シート1").Select
Columns("R:R").Select
Selection.NumberFormatLocal = "@"
と入れたら直りました。
速度は少し速くなった感じです。
No.3
- 回答日時:
こんにちは。
既に他の回答の方も書かれていますが、
配列変数を使うと高速できると思います。
イメージとしてはセルに入力されている値をチェックするのではなく、
変数に入れておいた値をチェックする感じですかね。
Do
If Cells(行, 1).Value = "" Then Exit Do
Cells(行, 18).Value = Cells(行, 3) & Cells(行, 4) & Cells(行, 5)
行 = 行 + 1
Loop
上記のところの前に
Dim varData as variant
set varData = Worksheet(1).Range("A1").CurrntRegion.Value
などとして変数にデータ全部を格納します。
イメージ的には上記変数varDataには表のレイアウトのまんまデータが格納されています。
それをループしてチェックするようにし、
変数に値を入れていき、最後に変数の中身をシートに吐き出す(展開する)形式にすると
処理速度は全然違うと思います。
varDataは配列となっており、ループ処理で添え字(Ubound、Lbound)などで気をつける必要があります。
いかがでしょうか?
No.2
- 回答日時:
対策1、シートとのアクセス回数を減らす。
対策2、表示はまとめて最後に行う。
Step1、必要なシート情報を配列変数に取り込む。
Step2、表示する配列データを生成する。
Step3、表示する。
シート1のデータが固定性の高いものであれば、構造体変数に取り込みバイナリファイルとして吐き出しておく。この手が可能ならば1秒以内に表示が始まると思います。
>Step1、必要なシート情報を配列変数に取り込む。
>Step2、表示する配列データを生成する。
>Step3、表示する。
私の技量では対応出来そうもないです。
どうもありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) まとめシートから集計シートへA列のコードが一致したら1行コピーするマクロをネット上で見つけました。こ 1 2022/08/30 14:11
- Visual Basic(VBA) VBA Userformで一部別シートに転記がしたいのですが 2 2023/05/24 13:08
- Visual Basic(VBA) 複数csvを横に追加していくマクロについて 2 2023/04/25 09:19
- Visual Basic(VBA) フォルダの場所を可変にしたいです(マクロ) 4 2023/05/11 10:00
- Visual Basic(VBA) エクセル VBA 処理スピードを上げたいのですが。 6 2023/03/31 20:52
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Excel(エクセル) マクロで最終行から上に検索を逆にしたい 1 2022/05/17 18:27
- Excel(エクセル) VBAについて 3 2022/06/19 18:19
- Excel(エクセル) エクセルVBAでオブジェクトが必要です 2 2022/09/10 16:37
- Visual Basic(VBA) 別シートから年齢別の件数をカウントしたいの続き 5 2023/01/24 00:16
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
至急!尿検査前日にオナニーし...
-
首吊りどこ締めるの
-
尿検査の前日は自慰控えたほう...
-
尿検査前日に自慰行為した時の...
-
射精をして1週間以内に尿検査を...
-
中出しをするとお腹が痛い・・・。
-
彼女のことが好きすぎて彼女の...
-
腕を見たら黄色くなってる部分...
-
これって喉仏ですか? 私は女性...
-
勃起する時って痛いんですか? ...
-
白血球が多いとどんな心配があ...
-
検便についてです。 便は取れた...
-
変な話しになります。尿検査で...
-
今朝、毎朝の習慣でオナニーし...
-
舌の裏の痛みのないプツプツの...
-
口の中に黒い血の塊
-
男です。昨日の午後3時くらいに...
-
2つの数値のうち、数値が小さい...
-
納豆食べた後の尿の納豆臭は何故?
-
精子が黄色?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
首吊りどこ締めるの
-
中出しをするとお腹が痛い・・・。
-
麻疹風疹の抗体検査結果につい...
-
エクセルでエラーが出て困って...
-
白血球が多いとどんな心配があ...
-
彼女のことが好きすぎて彼女の...
-
検便についてです。 便は取れた...
-
勃起する時って痛いんですか? ...
-
至急!尿検査前日にオナニーし...
-
納豆食べた後の尿の納豆臭は何故?
-
これって喉仏ですか? 私は女性...
-
EXCELで条件付き書式で空白セル...
-
精子が黄色?
-
小数点以下を繰り上げたものを...
-
値が入っているときだけ計算結...
-
口の中に黒い血の塊
-
健否~書類の書き方~
-
甲状腺が腫れているが血液検査...
-
はしかの抗体検査は何科の病院...
-
テスターで断線を調べる方法教...
おすすめ情報