回答編集履歴

2

もう少し改善できる点があったので補足

2021/07/15 21:07

投稿

xail2222
xail2222

スコア1508

test CHANGED
@@ -227,3 +227,71 @@
227
227
 
228
228
 
229
229
  の記述ミスですよね。
230
+
231
+
232
+
233
+ (4)
234
+
235
+ Arry.Add list, Array(.Cells(j, "Y"), .Cells(j, "Z"), .Cells(j, "AA"), .Cells(j, "AB"))
236
+
237
+
238
+
239
+ とありましたがよく見ると連続するセルですね。
240
+
241
+ この為
242
+
243
+
244
+
245
+ Arry.Add list, .Range("Y" & j & ":AB" & j).value
246
+
247
+
248
+
249
+ とした方が若干早いかもですね。
250
+
251
+ こちらの場合にすると処理の書き方が変わるので変えた内容も記載しておきます。
252
+
253
+
254
+
255
+ ```VBA
256
+
257
+ With ws2
258
+
259
+ For j = 2 To lRow2
260
+
261
+ list = .Cells(j, "G") & .Cells(j, "W")
262
+
263
+ Arry.Add list, .Range("Y" & j & ":AB" & j).Value
264
+
265
+ Next j
266
+
267
+ End With
268
+
269
+
270
+
271
+ Dim str, aKey, aItem
272
+
273
+
274
+
275
+ With ws1
276
+
277
+ Dim tV As Variant
278
+
279
+ ReDim tV(3 To lRow1, 0)
280
+
281
+ For k = 3 To lRow1
282
+
283
+ str = .Cells(k, "B") & .Cells(k, "C")
284
+
285
+ If Arry.Exists(str) Then
286
+
287
+ tV(k, 0) = Arry.Item(str)(1, 1)
288
+
289
+ End If
290
+
291
+ Next k
292
+
293
+ .Range("E3:E" & lRow1).Value = tV
294
+
295
+ End With
296
+
297
+ ```

1

辞書の値が配列である点の考慮が漏れていたので修正

2021/07/15 21:07

投稿

xail2222
xail2222

スコア1508

test CHANGED
@@ -6,188 +6,224 @@
6
6
 
7
7
 
8
8
 
9
+ Arry.Add list, Array(.Cells(j, "Y"), .Cells(j, "Z"), .Cells(j, "AA"), .Cells(j, "AB"))
10
+
11
+
12
+
13
+ ```
14
+
15
+ ですが,これだとRangeオブジェクトのまま操作していることになります。
16
+
17
+
18
+
19
+ ```VBA
20
+
21
+
22
+
23
+ Arry.Add list, Array(.Cells(j, "Y").value, .Cells(j, "Z").value, .Cells(j, "AA").value, .Cells(j, "AB").value)
24
+
25
+
26
+
27
+ ```
28
+
29
+ とすることで値での処理になります。
30
+
31
+
32
+
33
+ まぁ。これ自体は、今回の処理の遅さにはそれほど影響しないと思います。
34
+
35
+
36
+
37
+ ```VBA
38
+
39
+ With ws1
40
+
41
+ For k = 3 To lRow1
42
+
43
+ str = .Cells(k, "B") & .Cells(k, "C")
44
+
45
+
46
+
47
+ For x = 0 To Arry.count - 1
48
+
49
+ aKey = Arry.Keys()(x)
50
+
51
+ aItem = Arry.Items()(x)
52
+
53
+
54
+
55
+ If str = dcKey Then
56
+
57
+
58
+
59
+ .Cells(k, "E") = aItem(0)
60
+
61
+
62
+
63
+ End If
64
+
65
+
66
+
67
+ Next x
68
+
69
+
70
+
71
+ Next k
72
+
73
+ ```
74
+
75
+
76
+
77
+
78
+
79
+ こちらの方は、二つ問題があります。
80
+
81
+ 一つ目の問題は、辞書。Dictionaryを使っているのに、検索を自前で行っていること
82
+
83
+ 検索をDictionaryに任せると以下のようになります。
84
+
85
+
86
+
87
+ ```VBA
88
+
89
+ With ws1
90
+
91
+ For k = 3 To lRow1
92
+
93
+ str = .Cells(k, "B") & .Cells(k, "C")
94
+
95
+ If Arry.Exists(str) Then
96
+
97
+ .Cells(k, "E") = Arry.Item(str)(0)
98
+
99
+ End If
100
+
101
+ Next k
102
+
103
+ End With
104
+
105
+
106
+
107
+ ```
108
+
109
+ これである程度早くなります。
110
+
111
+
112
+
113
+ 次に、ヒットしない場合の動作が変わってしまって良ければですが
114
+
115
+
116
+
117
+ ```VBA
118
+
119
+ With ws1
120
+
121
+ Dim tV As Variant
122
+
123
+ ReDim tV(3 To lRow1, 0)
124
+
125
+ For k = 3 To lRow1
126
+
127
+ str = .Cells(k, "B") & .Cells(k, "C")
128
+
129
+ If Arry.Exists(str) Then
130
+
131
+ tV(k,0) = Arry.Item(str)(0)
132
+
133
+ End If
134
+
135
+ Next k
136
+
137
+ .Range("E3:E" & lRow1).Value = tV
138
+
139
+ End With
140
+
141
+
142
+
143
+ ```
144
+
145
+ このように配列で一括で、セルにセットすることでもある程度早くなります。
146
+
147
+ ヒットしない場合の動作を変えたくなければ
148
+
149
+
150
+
151
+ ```VBA
152
+
153
+ With ws1
154
+
155
+ Dim tV As Variant
156
+
157
+ tV = .Range("E3:E" & lRow1).Value
158
+
159
+ For k = 3 To lRow1
160
+
161
+ str = .Cells(k, "B") & .Cells(k, "C")
162
+
163
+ If Arry.Exists(str) Then
164
+
165
+ tV(k - 2, 1) = Arry.Item(str)(0)
166
+
167
+ End If
168
+
169
+ Next k
170
+
171
+ .Range("E3:E" & lRow1).Value = tV
172
+
173
+ End With
174
+
175
+ ```
176
+
177
+ となるでしょう。
178
+
179
+ 何が違うかと言えば、ヒットしなかったとき、値をそのままにしている。という点です。
180
+
181
+ 用途によって使い分けるといいかと思います。
182
+
183
+
184
+
185
+ 以上で、処理速度に関しては、早くなるかと思います。
186
+
187
+
188
+
189
+ (補足)
190
+
191
+ (1)
192
+
193
+ 処理速度とは関係ありませんが
194
+
195
+ Dim str
196
+
197
+ というのは、str関数を上書きしてしまう(str関数が使いにくくなる)ので使わない方が良いと思います。
198
+
199
+
200
+
201
+ (2)
202
+
203
+ Arryの値を配列で持っていますが一つ目の値しか使っていないですよね。
204
+
205
+ これは、想定通りなのでしょうか。
206
+
207
+ 想定通りであるのであれば、良いのですが。
208
+
209
+
210
+
211
+ (3)
212
+
213
+ 質問文では
214
+
215
+
216
+
9
217
  ARY.Add list, Array(.Cells(j, "Y"), .Cells(j, "Z"), .Cells(j, "AA"), .Cells(j, "AB"))
10
218
 
11
219
 
12
220
 
13
- ```
14
-
15
- ですが,これだとRangeオブジェクトのまま操作していることになります。
16
-
17
-
18
-
19
- ```VBA
221
+ となってますが
20
-
21
-
22
-
222
+
223
+
224
+
23
- ARY.Add list, Array(.Cells(j, "Y").value, .Cells(j, "Z").value, .Cells(j, "AA").value, .Cells(j, "AB").value)
225
+ Arry.Add list, Array(.Cells(j, "Y"), .Cells(j, "Z"), .Cells(j, "AA"), .Cells(j, "AB"))
24
-
25
-
26
-
27
- ```
226
+
28
-
29
- とすることで値での処理になります。
227
+
30
-
31
-
32
-
33
- まぁ。これ自体は、今回の処理の遅さにはそれほど影響しないと思います。
228
+
34
-
35
-
36
-
37
- ```VBA
38
-
39
- With ws1
40
-
41
- For k = 3 To lRow1
42
-
43
- str = .Cells(k, "B") & .Cells(k, "C")
44
-
45
-
46
-
47
- For x = 0 To Arry.count - 1
48
-
49
- aKey = Arry.Keys()(x)
50
-
51
- aItem = Arry.Items()(x)
52
-
53
-
54
-
55
- If str = dcKey Then
56
-
57
-
58
-
59
- .Cells(k, "E") = aItem(0)
60
-
61
-
62
-
63
- End If
64
-
65
-
66
-
67
- Next x
68
-
69
-
70
-
71
- Next k
72
-
73
- ```
74
-
75
-
76
-
77
-
78
-
79
- こちらの方は、二つ問題があります。
80
-
81
- 一つ目の問題は、辞書。Dictionaryを使っているのに、検索を自前で行っていること
82
-
83
- 検索をDictionaryに任せると以下のようになります。
84
-
85
-
86
-
87
- ```VBA
88
-
89
- With ws1
90
-
91
- For k = 3 To lRow1
92
-
93
- str = .Cells(k, "B") & .Cells(k, "C")
94
-
95
- If Arry.Exists(str) Then
96
-
97
- .Cells(k, "E") = Arry.Item(str)
98
-
99
- End If
100
-
101
- Next k
102
-
103
- End With
104
-
105
-
106
-
107
- ```
108
-
109
- これである程度早くなります。
110
-
111
-
112
-
113
- 次に、ヒットしない場合の動作が変わってしまって良ければですが
114
-
115
-
116
-
117
- ```VBA
118
-
119
- With ws1
120
-
121
- Dim tV As Variant
122
-
123
- ReDim tV(3 To lRow1, 0)
124
-
125
- For k = 3 To lRow1
126
-
127
- str = .Cells(k, "B") & .Cells(k, "C")
128
-
129
- If Arry.Exists(str) Then
130
-
131
- tV(k,0) = Arry.Item(str)
132
-
133
- End If
134
-
135
- Next k
136
-
137
- .Range("E3:E" & lRow1).Value = tV
138
-
139
- End With
140
-
141
-
142
-
143
- ```
144
-
145
- このように配列で一括で、セルにセットすることでもある程度早くなります。
146
-
147
- ヒットしない場合の動作を変えたくなければ
148
-
149
-
150
-
151
- ```VBA
152
-
153
- With ws1
154
-
155
- Dim tV As Variant
156
-
157
- tV = .Range("E3:E" & lRow1).Value
158
-
159
- For k = 3 To lRow1
160
-
161
- str = .Cells(k, "B") & .Cells(k, "C")
162
-
163
- If Arry.Exists(str) Then
164
-
165
- tV(k - 2, 1) = Arry.Item(str)
166
-
167
- End If
168
-
169
- Next k
170
-
171
- .Range("E3:E" & lRow1).Value = tV
172
-
173
- End With
174
-
175
- ```
176
-
177
- となるしょう
229
+ の記述ミスすよね
178
-
179
- 何が違うかと言えば、ヒットしなかったとき、値をそのままにしている。という点です。
180
-
181
- 用途によって使い分けるといいかと思います。
182
-
183
-
184
-
185
- 以上で、処理速度に関しては、早くなるかと思います。
186
-
187
-
188
-
189
- あと、処理速度とは関係ありませんが
190
-
191
- Dim str
192
-
193
- というのは、str関数を上書きしてしまう(str関数が使いにくくなる)ので使わない方が良いと思います。