回答編集履歴

2

さらに追記

2017/05/14 04:55

投稿

hatena19
hatena19

スコア33782

test CHANGED
@@ -166,8 +166,6 @@
166
166
 
167
167
  End Sub
168
168
 
169
-
170
-
171
169
  ```
172
170
 
173
171
 
@@ -183,3 +181,151 @@
183
181
  質問の追記のコードに `Application.EnableEvents = False` `Application.ScreenUpdating = True` を追加したもので、53秒前後、上記のコードで、18秒前後でした。
184
182
 
185
183
 
184
+
185
+ 追記の追記
186
+
187
+ ---
188
+
189
+ さらにさらにチューンナップしてみました。
190
+
191
+
192
+
193
+ **チューンナップ方針**
194
+
195
+ - 2重のループ内で、Like演算子で部分一致チェックをしているが、これに時間がかかっているようだ。そこで、 `ADomain Like "*" & NgDomain & "*"` を `InStr(ADomain , NgDomain ) > 0` 変更してみたら、処理時間が半分に短縮できた。
196
+
197
+ - InStrって高速なんだな!ならば、検索対象ドメインを連結して一つの文字列として、InStrで検索したらどうだろう。
198
+
199
+
200
+
201
+ ```
202
+
203
+ Sub SetColor4()
204
+
205
+ Dim OpenFileName As String
206
+
207
+ Dim Buf As String
208
+
209
+ Dim aryNgDomain
210
+
211
+ Dim aryADomain()
212
+
213
+ Dim strADomain As String
214
+
215
+ Dim aryRDomain()
216
+
217
+ Dim NgDomain, ADomain
218
+
219
+ Dim n As Long, p As Long, p0 As Long
220
+
221
+
222
+
223
+ Sheet1.Cells.Interior.Color = xlNone '背景色リセット
224
+
225
+ OpenFileName = Application.GetOpenFilename("テキスト文書,*.txt")
226
+
227
+
228
+
229
+ Dim t As Single
230
+
231
+ t = Timer
232
+
233
+
234
+
235
+ Application.EnableEvents = False
236
+
237
+ Application.ScreenUpdating = False
238
+
239
+ Application.Calculation = xlCalculationManual
240
+
241
+
242
+
243
+ 'テキストを一気に配列に読み込む
244
+
245
+ With CreateObject("Scripting.FileSystemObject")
246
+
247
+ With .GetFile(OpenFileName).OpenAsTextStream
248
+
249
+ Buf = .ReadAll
250
+
251
+ .Close
252
+
253
+ End With
254
+
255
+ End With
256
+
257
+ aryNgDomain = Split(Buf, vbCrLf)
258
+
259
+
260
+
261
+ With Workbooks(1).Worksheets(1)
262
+
263
+ aryADomain = .Range("A2:A" & .Cells(.Rows.Count, 1).End(xlUp).Row).Value
264
+
265
+ End With
266
+
267
+ 'Transposeで1次元配列に変換して、Joinで結合
268
+
269
+ strADomain = "|" & Join(WorksheetFunction.Transpose(aryADomain), "|") & "|"
270
+
271
+
272
+
273
+ 'NGドメインに一致するドメインを配列に格納
274
+
275
+ For Each NgDomain In aryNgDomain
276
+
277
+ p = 1
278
+
279
+ Do
280
+
281
+ p = InStr(p, strADomain, NgDomain, vbBinaryCompare)
282
+
283
+ If p = 0 Then Exit Do
284
+
285
+ p0 = InStrRev(strADomain, "|", p, vbBinaryCompare) + 1
286
+
287
+ ReDim Preserve aryRDomain(n)
288
+
289
+ p = InStr(p, strADomain, "|")
290
+
291
+ aryRDomain(n) = Mid(strADomain, p0, p - p0)
292
+
293
+ n = n + 1
294
+
295
+ Loop
296
+
297
+ Next
298
+
299
+
300
+
301
+ '該当ドメインの背景色設定
302
+
303
+ With Workbooks(1).Worksheets(1).Range("A1")
304
+
305
+ .AutoFilter Field:=1, Criteria1:=aryRDomain, Operator:=xlFilterValues
306
+
307
+ .CurrentRegion.SpecialCells(xlCellTypeVisible).Interior.Color = RGB(242, 221, 220)
308
+
309
+ .AutoFilter
310
+
311
+ End With
312
+
313
+ Workbooks(1).Worksheets(1).Rows(1).Interior.Color = xlNone
314
+
315
+ Application.EnableEvents = True
316
+
317
+ Application.ScreenUpdating = True
318
+
319
+ Application.Calculation = xlCalculationAutomatic
320
+
321
+
322
+
323
+ t = Timer - t
324
+
325
+ Debug.Print "setColor2 "; t & "秒かかりました。"
326
+
327
+ End Sub
328
+
329
+ ```
330
+
331
+ 結果、1秒!!で終わりました。

1

追記

2017/05/14 04:55

投稿

hatena19
hatena19

スコア33782

test CHANGED
@@ -29,3 +29,157 @@
29
29
 
30
30
 
31
31
  を挿入すると速度はかなり改善されると思います。
32
+
33
+
34
+
35
+ 追記
36
+
37
+ ---
38
+
39
+ さらなる高速化してみました。
40
+
41
+
42
+
43
+ **チューンナップ方針**
44
+
45
+
46
+
47
+ - テキストファイルはFileSystemObjectで全文を読み込む(Line Input で1行ずつ読み込むより高速)、Splitで行毎の配列にする
48
+
49
+ - セルに一つずつアクセスせずに、検索対象セルを一気に配列に代入して、配列にアクセスする。
50
+
51
+ - 上記2つの配列をFor Eachでループさせて、条件チェックして、該当するドメインを動的配列に格納。
52
+
53
+ - AutoFilter の Criteria1 に上記の動的配列を設定して、実行する(1回の処理で済む)
54
+
55
+
56
+
57
+ ```
58
+
59
+ Sub SetColor()
60
+
61
+ Dim OpenFileName As String
62
+
63
+ Dim buf As String
64
+
65
+ Dim aryNgDomain
66
+
67
+ Dim aryADomain()
68
+
69
+ Dim aryRDomain()
70
+
71
+ Dim NgDomain, ADomain
72
+
73
+ Dim n As Long
74
+
75
+
76
+
77
+ Sheet1.Cells.Interior.Color = xlNone '背景色リセット
78
+
79
+ OpenFileName = Application.GetOpenFilename("テキスト文書,*.txt")
80
+
81
+
82
+
83
+ Dim t As Single
84
+
85
+ t = Timer
86
+
87
+
88
+
89
+ Application.EnableEvents = False
90
+
91
+ Application.ScreenUpdating = False
92
+
93
+
94
+
95
+ 'テキストを一気に配列に読み込む
96
+
97
+ With CreateObject("Scripting.FileSystemObject")
98
+
99
+ With .GetFile(OpenFileName).OpenAsTextStream
100
+
101
+ buf = .ReadAll
102
+
103
+ .Close
104
+
105
+ End With
106
+
107
+ End With
108
+
109
+ aryNgDomain = Split(buf, vbCrLf)
110
+
111
+
112
+
113
+ 'NGドメインに一致するドメインを配列に格納
114
+
115
+ With Workbooks(1).Worksheets(1)
116
+
117
+ aryADomain = .Range("A2:A" & .Cells(.Rows.Count, 1).End(xlUp).Row).Value
118
+
119
+ For Each NgDomain In aryNgDomain
120
+
121
+ For Each ADomain In aryADomain
122
+
123
+ If ADomain Like "*" & NgDomain & "*" Then
124
+
125
+ ReDim Preserve aryRDomain(n)
126
+
127
+ aryRDomain(n) = ADomain
128
+
129
+ n = n + 1
130
+
131
+ End If
132
+
133
+ Next
134
+
135
+ Next
136
+
137
+ End With
138
+
139
+
140
+
141
+ '該当ドメインの背景色設定
142
+
143
+ With Workbooks(1).Worksheets(1).Range("A1")
144
+
145
+ .AutoFilter Field:=1, Criteria1:=aryRDomain, Operator:=xlFilterValues
146
+
147
+ .CurrentRegion.SpecialCells(xlCellTypeVisible).Interior.Color = RGB(242, 221, 220)
148
+
149
+ .AutoFilter
150
+
151
+ End With
152
+
153
+ Workbooks(1).Worksheets(1).Rows(1).Interior.Color = xlNone
154
+
155
+ Application.EnableEvents = True
156
+
157
+ Application.ScreenUpdating = True
158
+
159
+
160
+
161
+ t = Timer - t
162
+
163
+ Debug.Print "setColor "; t & "秒かかりました。"
164
+
165
+
166
+
167
+ End Sub
168
+
169
+
170
+
171
+ ```
172
+
173
+
174
+
175
+ ドメインリスト 20,000件、テキストのNGドメイン 3,000件のサンプルデータを rnd関数で自動生成しました。
176
+
177
+ それを元に実験してみました。
178
+
179
+ 当方の環境(Win10 64bit, Excel2016 32bit, CPU Core i7, RAM 16GB)
180
+
181
+
182
+
183
+ 質問の追記のコードに `Application.EnableEvents = False` `Application.ScreenUpdating = True` を追加したもので、53秒前後、上記のコードで、18秒前後でした。
184
+
185
+