[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『Dictionaryで2つ以上のKeyに対するItemの抽出方法』(Thomas)
Dictionaryで行のKeyと列のKeyの2つKeyにマッチしたItemをアウトプットしたく、下記コードを作り実行したのですが、うまくいかないです。やりたいことはSheet1にあるリストのItemをSheet2に移したいのですが、条件としてSheet2の行のKeyと列のKeyの2つKeyにマッチしたItemのみ移したいです。行のKeyと列のKeyは共に可変で、下記の様にDictionarにDictionaryを入れてみたのですがうまくいかない状況です。ネットで調べてみたのですが、1つのKeyに対するItemの抽出方法はあるのですが、2つ以上のKeyに対するItemの抽出方法が見つかりませんでした。念の為過去ログもひと通り確認しましたが同じ様な質問がないかと思いますので、もしよろしければどなたかご指導頂けます様お願い致します。
Sub Test4()
Dim Dic1 As Object Dim Dic2 As Object Dim i As Long Dim k As Long Dim lastrow As Long Dim lastcolumn As Long Dim keys1 As String Dim keys2 As String Dim Items1 As String Dim Items2 As String Dim ws01, ws02 As Worksheet
Set Dic1 = CreateObject("scripting.Dictionary") Set Dic2 = CreateObject("scripting.Dictionary") Set ws01 = Worksheets("Sheet1") Set ws02 = Worksheets("Sheet2")
lastrow = Cells(Rows.Count, 1).End(xlUp).Row lastcolumn = Cells(1, Columns.Count).End(xlToLeft).Column
With ws01 For i = 2 To lastrow For k = 2 To lastcolumn keys1 = ws01.Cells(1, k).Value Items1 = ws01.Cells(i, k).Value If Not Dic1.exists(keys1) Then Dic1.Add keys1, Items1 End If Next k Next i
For i = 2 To lastrow For k = 2 To lastcolumn keys2 = ws01.Cells(i, 1).Value If Not Dic2.exists(keys2) Then Dic2.Add keys2, Dic1 End If Next k Next i End With
With ws02 For i = 2 To lastrow For k = 2 To lastcolumn ws02.Cells(i, k).Value = Dic2(Key2) Next k Next i End With
Set Dic = Nothing
End Sub
< 使用 Excel:Excel2013、使用 OS:Windows8 >
keyC = ws01.Cells(1, k).Value keyR = ws01.Cells(j, 1).Value key = kwyC & vbTab & keyR dic(key) = ws01.Cells(i, k).Value
(マナ) 2022/01/05(水) 17:21
Sub Test4()
Dim Dic1 As Object Dim i As Long Dim k As Long Dim lastrow As Long Dim lastcolumn As Long Dim keys1 As String Dim keys2 As String Dim keys3 As String Dim ws01, ws02 As Worksheet
Set Dic1 = CreateObject("scripting.Dictionary") Set ws01 = Worksheets("Sheet1") Set ws02 = Worksheets("Sheet2")
lastrow = Cells(Rows.Count, 1).End(xlUp).Row lastcolumn = Cells(1, Columns.Count).End(xlToLeft).Column
With ws01 For i = 2 To lastrow For k = 2 To lastcolumn keys1 = ws01.Cells(1, k).Value keys2 = ws01.Cells(i, 1).Value keys3 = keys1 & vbTab & keys2 Dic1(keys3) = ws01.Cells(i, k).Value Next k Next i End With
With ws02 For i = 2 To lastrow For k = 2 To lastcolumn ws02.Cells(i, k).Value = Dic1(keys3) Next k Next i End With
Set Dic = Nothing
End Sub
(Thomas) 2022/01/05(水) 19:15
Sub Test4修正() Dim Dic1 As Object Dim i As Long Dim k As Long Dim lastrow As Long Dim lastcolumn As Long Dim keys1 As String Dim keys2 As String Dim keys3 As String Dim ws01 As Worksheet, ws02 As Worksheet
Set Dic1 = CreateObject("scripting.Dictionary") Set ws01 = Worksheets("Sheet1") Set ws02 = Worksheets("Sheet2")
lastrow = ws01.Cells(Rows.Count, 1).End(xlUp).Row lastcolumn = ws01.Cells(1, Columns.Count).End(xlToLeft).Column For i = 2 To lastrow For k = 2 To lastcolumn keys1 = ws01.Cells(1, k).Value keys2 = ws01.Cells(i, 1).Value keys3 = keys1 & vbTab & keys2 Dic1(keys3) = ws01.Cells(i, k).Value Next k Next i
lastrow = ws02.Cells(Rows.Count, 1).End(xlUp).Row lastcolumn = ws02.Cells(1, Columns.Count).End(xlToLeft).Column For i = 2 To lastrow For k = 2 To lastcolumn keys1 = ws02.Cells(1, k).Value keys2 = ws02.Cells(i, 1).Value keys3 = keys1 & vbTab & keys2 ws02.Cells(i, k).Value = Dic1(keys3) Next k Next i
Set Dic = Nothing End Sub
(マナ) 2022/01/05(水) 19:31
こんな感じのことでしょうか
For j = 2 To lastrow keyR = ws01.Cells(j, 1).Value If Not dic.exists(keyR) Then Set dic(keyR) = CreateObject("scripting.Dictionary") End If For k = 2 To lastcolumn keyC = ws01.Cells(1, k).Value dic(keyR)(keyC) = ws01.Cells(j, k).Value Next Next
(マナ) 2022/01/05(水) 19:48
=INDEX(Sheet1![リスト範囲] ,MATCH([行の検索値],Sheet1![Key行],0) ,MATCH([列の検索値],Sheet1![Key列],0) )
・・・みたいな事なのでしょうか。
とすれば、 Dic1---[行の検索値]から[リスト範囲]の「行番号」を得る辞書 Dic2---[列の検索値]から[リスト範囲]の「列番号」を得る辞書 として、 得られた「行番号」「列番号」から[リスト範囲]の「該当セル」を導き出す という組み方も考えられそうですよね。
(白茶) 2022/01/05(水) 19:49
Sub Test5()
Dim Dic As Object Dim i As Long Dim j As Long Dim k As Long Dim lastrow As Long Dim lastcolumn As Long Dim keys1 As String Dim keys2 As String Dim keys3 As String Dim keysR As String Dim keysC As String Dim ws01 As Worksheet, ws02 As Worksheet
Set Dic = CreateObject("scripting.Dictionary") Set ws01 = Worksheets("Sheet1") Set ws02 = Worksheets("Sheet2")
lastrow = ws01.Cells(Rows.Count, 1).End(xlUp).Row lastcolumn = ws01.Cells(1, Columns.Count).End(xlToLeft).Column
For j = 2 To lastrow keyR = ws01.Cells(j, 1).Value If Not Dic.exists(keyR) Then Set Dic(keyR) = CreateObject("scripting.Dictionary") End If For k = 2 To lastcolumn keyC = ws01.Cells(1, k).Value Dic(keyR)(keyC) = ws01.Cells(j, k).Value Next Next
lastrow = ws02.Cells(Rows.Count, 1).End(xlUp).Row lastcolumn = ws02.Cells(1, Columns.Count).End(xlToLeft).Column For j = 2 To lastrow keyR = ws02.Cells(j, 1).Value If Not Dic.exists(keyR) Then Set Dic(keyR) = CreateObject("scripting.Dictionary") End If For k = 2 To lastcolumn keyC = ws02.Cells(1, k).Value Dic(keyR)(keyC) = ws02.Cells(j, k).Value Next Next
Set Dic = Nothing
End Sub
(Thomas) 2022/01/05(水) 20:32
lastrow = ws02.Cells(Rows.Count, 1).End(xlUp).Row lastcolumn = ws02.Cells(1, Columns.Count).End(xlToLeft).Column For j = 2 To lastrow keyR = ws02.Cells(j, 1).Value For k = 2 To lastcolumn keyC = ws02.Cells(1, k).Value ws02.Cells(j, k).Value = Dic(keyR)(keyC) Next Next
でも、入れ子にする意味はないと思いますよ。
(マナ) 2022/01/05(水) 20:53
(マナ) 2022/01/05(水) 21:05
> またDictionaryにDictionaryのコードも下記の様に修正したのですが、うまくいきませんでした。
まず、変数が宣言と使用時で違ってます。
宣言 Dim keysR As String Dim keysC As String
使用時の一例 Dic(keyR)(keyC) = ws01.Cells(j, k).Value
モジュールの先頭に、Option Explicit を追加してコンパイルすると、間違いを指摘してくれますので習慣づけしておきましょう。
Office TANAKA - 今さら聞けないVBA[変数って宣言しなくちゃいけないの? http://officetanaka.net/excel/vba/beginner/06.htm
あと、ws01のForループとws02のForループのコードが同じになってます。 どちらも格納のコードですので、出力されるはずかありません。
下記のように修正すればいいでしょう。
------------------------- Sub Test5改() Dim Dic As Object Dim j As Long Dim k As Long Dim lastrow As Long Dim lastcolumn As Long Dim keyR As String Dim keyC As String Dim ws01 As Worksheet, ws02 As Worksheet Set Dic = CreateObject("scripting.Dictionary") Set ws01 = Worksheets("Sheet1") Set ws02 = Worksheets("Sheet2") lastrow = ws01.Cells(Rows.Count, 1).End(xlUp).Row lastcolumn = ws01.Cells(1, Columns.Count).End(xlToLeft).Column For j = 2 To lastrow keyR = ws01.Cells(j, 1).Value If Not Dic.exists(keyR) Then Set Dic(keyR) = CreateObject("scripting.Dictionary") End If For k = 2 To lastcolumn keyC = ws01.Cells(1, k).Value Dic(keyR)(keyC) = ws01.Cells(j, k).Value Next Next lastrow = ws02.Cells(Rows.Count, 1).End(xlUp).Row lastcolumn = ws02.Cells(1, Columns.Count).End(xlToLeft).Column For j = 2 To lastrow keyR = ws02.Cells(j, 1).Value If Dic.exists(keyR) Then For k = 2 To lastcolumn keyC = ws02.Cells(1, k).Value If Dic(keyR).exists(keyC) Then ws02.Cells(j, k).Value = Dic(keyR)(keyC) End If Next End If Next Set Dic = Nothing End Sub ------------------------ (hatena) 2022/01/05(水) 21:12
白茶さんの提案した方法をコードにしてみました。
----------------------- Sub Test6() Dim i As Long, j As Long Dim DicR As Object, DicC As Object Dim ws01 As Worksheet, ws02 As Worksheet Dim keyR As String, keyC As String Dim lastCol As Long
Set DicR = CreateObject("scripting.Dictionary") Set DicC = CreateObject("scripting.Dictionary") Set ws01 = Worksheets("Sheet1") Set ws02 = Worksheets("Sheet2")
'ws01の行のキーと行番号を格納 For i = 2 To ws01.Cells(Rows.Count, 1).End(xlUp).Row DicR(ws01.Cells(i, 1).Value) = i Next 'ws01の列のキーと列番号を格納 For j = 2 To ws01.Cells(1, Columns.Count).End(xlToLeft).Column DicC(ws01.Cells(1, j).Value) = j Next
lastCol = ws02.Cells(1, Columns.Count).End(xlToLeft).Column For i = 2 To ws02.Cells(1, Columns.Count).End(xlToLeft).Column keyR = ws02.Cells(i, 1).Value If DicR.exists(keyR) Then For j = 2 To lastCol keyC = ws02.Cells(1, j).Value If DicC.exists(keyC) Then ws02.Cells(i, j).Value = ws01.Cells(DicR(keyR), DicC(keyC)).Value End If Next End If Next Set DicR = Nothing Set DicC = Nothing End Sub ------------------------------- (hatena) 2022/01/05(水) 21:57
Dictionaryは使いません。全く別案です。
ws01データを配列に取り込んで、
ws02の並びに組み換えて転記しています。
Option Explicit
Sub test() Dim r1 As Range, r2 As Range Dim gyo, retu
Set r1 = Worksheets("Sheet1").Cells(1).CurrentRegion Set r1 = Intersect(r1, r1.Offset(1, 1)) Set r2 = Worksheets("Sheet2").Cells(1).CurrentRegion Set r2 = Intersect(r2, r2.Offset(1, 1))
gyo = Application.Match(r2.Columns(0), r1.Columns(0), 0) retu = Application.Match(r2.Rows(0), r1.Rows(0), 0)
r2.Value = Application.Index(r1.Value, gyo, retu) On Error Resume Next r2.SpecialCells(xlCellTypeConstants, xlErrors).ClearContents
End Sub
(マナ) 2022/01/07(金) 21:19
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.