
以下(1)のようなデータがあります。※実際はもっと項目数は多いです。
(1)を元に、別シートに(2)のような集計を出したいのですが、
数式を埋め込みたくないため、VBAでカウントさせて実データを埋め込みたいです。
(1) A B
| 名前 | 出身 |
├────┼────┤
| 田中 | 岩手 |
| 吉田 | 秋田 |
| 井上 | 沖縄 |
| 加藤 | 島根 |
| 鈴木 | 岐阜 |
| 木本 | 愛知 |
| 伊藤 | 沖縄 |
| 宮田 | 秋田 |
| 佐藤 | 長野 |
↓↓↓
(2) A B
| 出身 | 人数 |
├────┼────┤
| 岩手 | 1 |
| 秋田 | 2 |
| 沖縄 | 2 |
| 島根 | 1 |
| 岐阜 | 1 |
| 愛知 | 1 |
| 長野 | 1 |
そこで以下のように書いてみたところ、正しくカウントは取れるのですが、
思った以上に処理時間がかかってしまいました。
Dim dc1 As Integer
Dim dc2 As Integer
dc1 = Worksheets("Sheet1").Range("A65536").End(xlUp).Row
dc2 = Worksheets("Sheet2").Range("A65536").End(xlUp).Row
i1 = 0
i2 = 0
For i1 = 2 To dc2
cnt = 0
For i2 = 2 To dc1
If Worksheets("Sheet2").Cells(i1, 1) = Worksheets("Sheet1").Cells(i2, 1) Then
cnt = cnt + 1
End If
Next i2
Worksheets("Sheet2").Cells(i1, 2) = cnt
cntRec = cntRec + 1
Application.StatusBar = "件数処理実行中・・・(現在 " & cntRec & "件)"
Next i1
(1)を元に(2)のような表を作成するのに、もっと処理時間が短くなるような
書き方はありますでしょうか?よろしくお願いいたします。

No.3ベストアンサー
- 回答日時:
Public Sub ToDoHuKen()
Dim dc1 As Integer, dc2 As Integer
Dim i1 As Integer, cnt As Integer
dc1 = Worksheets("Sheet1").Range("A65536").End(xlUp).Row
dc2 = Worksheets("Sheet2").Range("A65536").End(xlUp).Row
For i1 = 2 To dc2
cnt = 0
'組み込み関数を使ったほうが速い
cnt = WorksheetFunction.CountIf(Worksheets("Sheet1").Range("A2:A" & dc1), Worksheets("Sheet2").Cells(i1, 1))
Worksheets("Sheet2").Cells(i1, 2) = cnt
Next i1
End Sub
lotilyxoen様、ご回答ありがとうございました。
14分ぐらいかかっていた処理が33秒まで短縮されました。
こんなにも違いが出るとは正直驚きです。本当に勉強になりました。
No.5
- 回答日時:
こんにちは。
>Application.StatusBar = "件数処理実行中・・・(現在 " & cntRec & "件)"
こんなオプションはいらないのでは?
既に、フィルタオプション等で、一意のリストが出来ているのは、残りは、このようにすれば済むと思います。
Sub TestMacro1()
Dim sRng As String
With Worksheets("Sheet1")
sRng = .Range("B2", .Cells(Rows.Count, 2).End(xlUp)).Address(, , xlR1C1, True)
End With
With Worksheets("Sheet2")
With .Range("A2", .Cells(Rows.Count, 1).End(xlUp)).Offset(, 1)
.FormulaLocal = "=CountIf(" & sRng & ",RC[-1])"
.Value = .Value
End With
End With
End Sub
No.4
- 回答日時:
>Application.StatusBar = "件数処理実行中・・・(現在 " & cntRec & "件)"
この表示処理にも時間がかかります。処理の進捗度合いを知りたいだけなら、
If cntRec Mod 100 = 0 Then
Application.StatusBar = "件数処理実行中・・・(現在 " & cntRec & "件)"
End If
とかした方が、速くはなります。速度を考慮したら表示しないのが一番ですが。
cistronezk様、ご回答ありがとうございます。
ご指摘いただいたところを直したところ、直す前と比べて2、3秒ほど短縮できました。
相談前は10分以上かかっていた処理だったため、ハングアップでないことを
使用者に認識させる目的で表示させておりましたが、皆様のご回答のおかげで
1分を切るようになったため、cistronezk様のご助言どおり、表示させない方向で
検討してみます。
No.2
- 回答日時:
もしSheet1がB列でソートされているとしたら、下記のコードでかなり早くなります。
もちろんB列でソートされていないと思いますので、いったん別の列にコピーしその列だけでソートしてから実行すればコピー&ソートの時間が増えるだけ済みます。(当然参照列は変わります)
なお、コピー&ソートをマクロの中に組み込むこともできますので、必要ならそうしてください。
Sub Test()
Dim i As Integer
Dim dc1 As Integer
Dim dc2 As Integer
Dim S As String
Dim cnt As Integer
Dim cntRec As Integer
dc1 = Worksheets("Sheet1").Range("A65536").End(xlUp).Row
dc2 = Worksheets("Sheet2").Range("A65536").End(xlUp).Row
For i = 2 To dc2
Worksheets("Sheet2").Cells(i, 2) = 0
Next i
cntRec = 0
i = 2
S = Worksheets("Sheet1").Cells(i, 2).Value
cnt = 1
Do
i = i + 1
If Worksheets("Sheet1").Cells(i, 2).Value <> S Or i > dc1 Then
If S <> "" Then
Worksheets("Sheet2").Range("A2:A" & dc2).Find(What:=S).Offset(0, 1).Value = cnt
cntRec = cntRec + 1
Application.StatusBar = "件数処理実行中・・・(現在 " & cntRec & "件)"
End If
S = Worksheets("Sheet1").Cells(i, 2)
cnt = 0
End If
cnt = cnt + 1
Loop While i <= dc1
End Sub
nag0720様、ご回答ありがとうございます。
14分ほどかかっていた処理が35秒まで短縮されました。
今回は他の方の方法で対応させていただきましたが、非常に勉強になりました。
No.1
- 回答日時:
配列を使用する方法です
Sub test()
Dim dc1 As Variant
Dim dc2 As Variant
Dim i1 As Long, i2 As Long, cnt As Long, cntRec As Long
dc1 = Worksheets("Sheet1").Range("B2", Worksheets("Sheet1").Range("B65536").End(xlUp))
dc2 = Worksheets("Sheet2").Range("A2", Worksheets("Sheet2").Range("A65536").End(xlUp))
For i1 = 1 To UBound(dc2, 1)
cnt = 0
For i2 = 1 To UBound(dc1, 1)
If dc2(i1, 1) = dc1(i2, 1) Then
cnt = cnt + 1
End If
Next i2
Worksheets("Sheet2").Cells(i1 + 1, 2) = cnt
cntRec = cntRec + 1
Application.StatusBar = "件数処理実行中・・・(現在 " & cntRec & "件)"
Next i1
'Application.StatusBar = False
End Sub
参考まで
hige_082様、ご回答ありがとうございます。
14分ぐらいかかっていた処理が55秒と素晴らしく短縮されました。
今回は別の方の方法で対処させていただきましたが、
本当に勉強になりました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) なぜExit Subがあるのかわかりません 4 2023/02/19 12:34
- Excel(エクセル) VBAで組み合わせ算出やCOUNTIFSの処理を高速化したいです。 4 2022/04/07 02:38
- Visual Basic(VBA) 前回ご教授いただいたコードに覚えたてのループ処理で品名りんごAから順に20回for nextでループ 7 2023/01/13 22:01
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Visual Basic(VBA) vbaを早くしたい 5 2022/09/09 10:58
- Visual Basic(VBA) 配列の勉強をしています。使用する変数の意味、検索条件の書き方が難しいです。 2 2022/09/15 14:06
- Visual Basic(VBA) VBA Userformで一部別シートに転記がしたいのですが 2 2023/05/24 13:08
- Visual Basic(VBA) Excelで下記のようにマクロを作ったところ、一回目は実行できたのですが、二回目以降「実行時エラー1 1 2022/03/25 08:08
- Visual Basic(VBA) ユーザーフォーム「frm_基本❶」を立ち上げると新規で入力する行数を右下のNoとして表示しています。 1 2023/03/16 19:02
- Visual Basic(VBA) VBAが止まります。 1 2022/09/02 14:51
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「ご処理進めて頂きますようお...
-
エクセルで、日付を入力すると...
-
VBAでループ内で使う変数名を可...
-
月度は何て読みますか?
-
男性に対して、『女性への気遣...
-
VBAでCOPYを繰り返すと、処理が...
-
switch の範囲指定
-
【Excel】特定の文字を含むセル...
-
DoEventsがやはり分からない
-
インタラクティブの反対語は?
-
VBA 特定の文字が入力されたセ...
-
Do~Loopした回数をカウントしたい
-
お家デートをしててハグを長い...
-
Loadイベント中にほかのイベン...
-
エクセルマクロVBA構成の相談
-
[大至急]5つの数字のパターンは?
-
RPGプログラムの*HIVALについて
-
vba 空のデータをSplitする時の...
-
JDBCでの大量データ検索でResul...
-
再帰処理を途中で抜けるには
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「ご処理進めて頂きますようお...
-
エクセルで、日付を入力すると...
-
VBAでループ内で使う変数名を可...
-
【Excel】特定の文字を含むセル...
-
switch の範囲指定
-
EXCEL VBA マクロ 実行する度に...
-
UMLでの例外処理
-
DoEventsがやはり分からない
-
月度は何て読みますか?
-
お家デートをしててハグを長い...
-
VB.NET Excelを読み込んでDataT...
-
VBの質問#if 0 then ってどう...
-
Do~Loopした回数をカウントしたい
-
VBAでCOPYを繰り返すと、処理が...
-
メルカリのメルカードで買い物...
-
インタラクティブの反対語は?
-
Loadイベント中にほかのイベン...
-
リョウ・・・量?料?
-
vba 空のデータをSplitする時の...
-
findは動くがfindnextがマクロ...
おすすめ情報