質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

1回答

3040閲覧

VBA配列による重複のカウント

TAKAYUKIM

総合スコア3

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2022/04/07 08:06

VBAの配列について質問があります。
処理速度についてかなり差が出ていて、教えてください。

Dictionaryを利用して重複したデータのカウントを行っています。countifのような形です。
データの始まりは4行目からで重複しているデータはC列、L列にカウントした数字を入れています。約3万件のデータがあり、シートはほかに7枚あり、INDEX・MATCH関数を多く利用しています。ファイルサイズは約5MBあります。
VBAを実行した結果のイメージは以下の通りです。
C列 L列
A1   1
A1   2
A1   3
B1   1
B1   2
B2   1

コードについては以下のように記載しています。

VBA

1Sub 連番カウント() 2 Dim i As Long, STG As Long 3 Dim key As String 4 Dim dicT As Object 5 Dim startDateTime As Date 6 Dim endDateTime As Date 7 Dim processTime As Date 8 9 Dim ws1 As Worksheet 10 11 '開始日時を取得 12 startDateTime = Now 13 14 Set ws1 = ThisWorkbook.Worksheets(4) 15 16 Application.ScreenUpdating = False 17 Application.Calculation = xlCalculationManual 18 Application.EnableEvents = False 19 20 With ws1 21 22 'STGで開始する行を指定 例:4行目からならSTG=4とする' 23 STG = 4 24 25 Set dicT = CreateObject("Scripting.Dictionary") 26 27 'Row.Count,Cの場合C行を対象とする' 28 For i = STG To Cells(Rows.Count, "C").End(xlUp).Row 29 key = Cells(i, "C").Value 30 31 If dicT.Exists(key) = False Then 32 dicT.Add key, 1 33 Else 34 dicT(key) = dicT(key) + 1 35 End If 36 '重複カウントを格納する列を指定。この場合L行' 37 Cells(i, "L").Value = dicT(key) 38 Next 39 40 End With 41 42 Application.ScreenUpdating = True 43 Application.Calculation = xlCalculationAutomatic 44 Application.EnableEvents = True 45 46 '終了日時を取得 47 endDateTime = Now 48 49 '処理時間を算出 50 processTime = endDateTime - startDateTime 51 52 MsgBox "処理が完了しました!" & vbCrLf & vbCrLf & _ 53 "開始日時:" & startDateTime & vbCrLf & _ 54 "終了日時:" & endDateTime & vbCrLf & _ 55 "処理時間:" & processTime & vbCrLf, _ 56 vbOKOnly + vbInformation, "計測結果" 57 58End Sub

L列に既にデータが入っていた場合は10秒ほどで終わります。前のデータがあった場合は13分かかっており、この差がなぜでてきているのか不明な状況です。

お力貸していただけないでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hatena19

2022/04/07 08:27

「L列に既にデータが入っていた場合」と「前のデータがあった場合」の違いがなんなのかが具体的にわかるように説明を追加していただけませんか。
TAKAYUKIM

2022/04/07 08:32

申し訳ございません。記載ミスです。 「前のデータがあった場合」ではなく、「以前のデータを削除しクリアした状態の場合」 となります。
guest

回答1

0

提示されたコードからはそのような差がでる原因はわかりませんが、
とりあえず、現状のコードを配列を利用して高速化するコード例をあげておきます。

vba

1Sub 連番カウント() 2 Dim i As Long, STG As Long 3 Dim key As String 4 Dim dicT As Object 5 Dim startDateTime As Date 6 Dim endDateTime As Date 7 Dim processTime As Date 8 9 Dim ws1 As Worksheet 10 11 '開始日時を取得 12 startDateTime = Now 13 14 Set ws1 = ThisWorkbook.Worksheets(4) 15 16 Application.ScreenUpdating = False 17 Application.Calculation = xlCalculationManual 18 Application.EnableEvents = False 19 20 With ws1 21 22 'STGで開始する行を指定 例:4行目からならSTG=4とする' 23 STG = 4 24 25 Set dicT = CreateObject("Scripting.Dictionary") 26 27 '対象セル範囲を配列に格納 28 Dim ary 29 ary = .Range(.Cells(STG, "C"), .Cells(.Rows.Count, "C").End(xlUp)).Value 30 31 For i = 1 To UBound(ary) 32 key = ary(i, 1) 33 dicT(key) = dicT(key) + 1 34 ary(i, 1) = dicT(key) 35 Next 36 .Cells(STG, "L").Resize(UBound(ary)).Value = ary 37 End With 38 39 Application.ScreenUpdating = True 40 Application.Calculation = xlCalculationAutomatic 41 Application.EnableEvents = True 42 43 '終了日時を取得 44 endDateTime = Now 45 46 '処理時間を算出 47 processTime = endDateTime - startDateTime 48 49 MsgBox "処理が完了しました!" & vbCrLf & vbCrLf & _ 50 "開始日時:" & startDateTime & vbCrLf & _ 51 "終了日時:" & endDateTime & vbCrLf & _ 52 "処理時間:" & processTime & vbCrLf, _ 53 vbOKOnly + vbInformation, "計測結果" 54 55End Sub

投稿2022/04/07 08:32

編集2022/04/07 08:34
hatena19

総合スコア33715

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TAKAYUKIM

2022/04/08 01:08

お返事が遅くなりました。 ありがとうございます。 こちらでお示しいただいたコードを実行してみました。L列に値が入らない状況です。 ご教示いただけないでしょうか。
hatena19

2022/04/08 01:39

当方のサンプルでは問題なく入ってます。 まったく同じコードですか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問