Excel (VBA) |
![]() ![]() |
(Windows 10 Pro : Excel 2016)
配列処理への変換(処理の高速化)
投稿日時: 23/07/13 10:58:42
投稿者: ひろまさ
|
---|---|
ご教示をお願いしたい事がございます。
|
![]() |
投稿日時: 23/07/13 11:13:34
投稿者: WinArrow
|
---|---|
掲示のコードは、実際に動いているコードではありませんね?
引用: ↓ Dim he As Worksheet, he2 As Worksheet Dim i As Long, j As Long データ側:オートフィルタで絞り込めば、全件ループは必要ありません。 マスタ側:VLOOKUP関数などを使って検索すれば、ループ不要になります。 ループを協力減らすことです。 検討してみてください。 |
![]() |
投稿日時: 23/07/13 13:00:17
投稿者: simple
|
---|---|
■作業内容がちょっとよく分からないので、サンプルデータを提示してください。
入力シート(sheets(3)) マスターシート(sheets(2)) -------------------------- ------------------------------------ A(1) C(3) I(9) A(1) B(2) D(4) F(6) 1 図番 個数 品物 ??? 図番 個数 2 3 4 5???は何でしょうか。ロジックにかかわります。 ■現在はどのくらいの時間がかかっていますか?参考までに教えて下さい。 ちなみに、 Sub test() Dim t t = Timer ' ここに作業コードを書きます。 Debug.Print Timer - t End Subなどとすると実行時間がわかります。 # まったく余談なんですが、heというのは何の略なんでしょう。気になります。 # ws(worksheetから)とかsh(sheetから)とかはよく見ますが、She..に対するHeなんですかねw。 |
![]() |
投稿日時: 23/07/13 14:20:58
投稿者: ひろまさ
|
---|---|
WinArrow様
|
![]() |
投稿日時: 23/07/13 14:49:10
投稿者: ひろまさ
|
---|---|
simple様
|
![]() |
投稿日時: 23/07/13 14:55:16
投稿者: simple
|
---|---|
拝見しました。
|
![]() |
投稿日時: 23/07/13 15:17:45
投稿者: ひろまさ
|
---|---|
simple様
|
![]() |
投稿日時: 23/07/13 20:04:10
投稿者: simple
|
---|---|
動作確認しておりませんが、下記のコードではいかがでしょうか。
Sub test2() Dim wsM As Worksheet, wsD As Worksheet Dim dic As Object Dim s As String Dim k As Long, j As Long Set wsM = ThisWorkbook.Sheets(2) 'マスタデータ Set wsD = ThisWorkbook.Sheets(3) '入力データ Set dic = CreateObject("Scripting.Dictionary") With wsM For k = 2 To .Cells(Rows.Count, 1).End(xlUp).Row If .Cells(k, 1) = "消しゴム" Then dic(.Cells(k, 2).Value) = k End If Next End With With wsD For j = 2 To .Cells(Rows.Count, 1).End(xlUp).Row s = .Cells(j, 3).Value If dic.Exists(s) Then k = dic(s) .Cells(j, 3) = wsM.Cells(k, 4) '図番 .Cells(j, 9) = wsM.Cells(k, 6) '個数 End If Next End With End Sub なぜ消しゴムとか限定するのか意味不明で、忸怩たる思いのなかでのコード作成でした。 なお、もっと早いものについては、別の方からの回答をお待ちください。 私はこれで一段落とします。 |
![]() |
投稿日時: 23/07/13 22:17:00
投稿者: WinArrow
|
---|---|
引用: ↑ "消しゴム"という条件に付いて、明快な回答がありませんが、 何故、マスタ側なんですか? データ側の条件ならば理解できるのですが・・・ |
![]() |
投稿日時: 23/07/13 23:50:12
投稿者: hatena
|
---|---|
質問のコードを機械的に配列処理に変換したコードです。
Public Sub ArraySample() Dim he As Worksheet, he2 As Worksheet Set he = ThisWorkbook.Sheets(2) 'マスタデータ Set he2 = ThisWorkbook.Sheets(3) '入力データ Dim ary, ary2 ary = he.Range("A1").CurrentRegion.Value 'マスタデータの表範囲を配列に格納 ary2 = he2.Range("A1").CurrentRegion.Value '入力データの表範囲を配列に格納 Dim i, j As Long For j = 2 To UBound(ary2) For i = 2 To UBound(ary) If ary(i, 1) = "消しゴム" Then If ary(i, 2) = he2.Cells(j, 3) Then ary2(j, 3) = ary(i, 4) '図番 ary2(j, 9) = ary(i, 6) '個数 Exit For End If End If Next i Next j he2.Range("A1").CurrentRegion.Value = ary2 '更新した配列を表範囲に代入 End Sub これでかなり高速化はできると思います。 ただし、二重ループは処理数が大きくなるので、simpleさんも回答されているDictionaryを使ってマッチングさせるとより高速になるでしょう。 |
![]() |
投稿日時: 23/07/14 00:13:34
投稿者: hatena
|
---|---|
simpleさんのコードを拝借して、配列で処理するようにしてみました。
Public Sub DictionarySample() Dim he As Worksheet, he2 As Worksheet Set he = ThisWorkbook.Sheets(2) 'マスタデータ Set he2 = ThisWorkbook.Sheets(3) '入力データ Dim ary, ary2 ary = he.Range("A1").CurrentRegion.Value 'マスタデータの表範囲を配列に格納 ary2 = he2.Range("A1").CurrentRegion.Value '入力データの表範囲を配列に格納 Dim dic As Object Set dic = CreateObject("Scripting.Dictionary") Dim i As Long For i = 2 To UBound(ary) If ary(i, 1) = "消しゴム" Then dic(ary(i, 2)) = i 'Key:旧図番, Item:行番号 End If Next Dim j As Long, s As String For j = 2 To UBound(ary2) s = ary2(j, 3) If dic.Exists(s) Then '入力シートの図番がDictionaryに存在したら i = dic(s) ary2(j, 3) = ary(i, 4) '図番 ary2(j, 9) = ary(i, 6) '個数 End If Next j he2.Range("A1").CurrentRegion.Value = ary2 '更新した配列を表範囲に代入 End Sub |
![]() |
投稿日時: 23/07/14 07:25:04
投稿者: WinArrow
|
---|---|
何度も同じ質問をさせていただきます。
ひろまさ さんの引用: 疑問点が2つあります。 (1)旧図番を新図番に変換する対象が、左端の番号(1,5)と説明されていいるが、 [1]:旧図番「A4」は「B5」に変換対象にんります。 ・・・しかし、"消しゴム"には該当していない("ゴム"を消しゴム"と置き換えても) [5]:旧図番「A3」は、変換後も「A3」・・・これでよいのですか? |
![]() |
投稿日時: 23/07/14 09:55:56
投稿者: ひろまさ
|
---|---|
simple様
|