[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『Dictionaryに配列を格納』(まー)
下記のようにDictionaryに配列を格納して、itemをインデックス番号で取り出すようにしたいのですが、下の構文で型が一致しませんとでます。 w(i, 1) = myDic(ws.Range("F" & i + 1).Value)(0) どうすればよいのかご教授願います。素人なので根本的に間違っているかもしれないので詳しく教えていただけると幸いです。
Sub test2() Dim las As Long, myr As Long, i As Long Dim ws As Worksheet Dim myDic As Object Dim w() As String Set ws = Sheets("Sheet1") myr = ws.Range("B" & Rows.Count).End(xlUp).Row With Sheets("Sheet2") las = .Range("A" & Rows.Count).End(xlUp).Row Set myDic = CreateObject("scripting.dictionary") For i = 2 To las If Not myDic.exists(.Range("CR" & i)) Then myDic(.Range("CR" & i).Value) = Array(.Range("AP" & i), .Range("DA" & i), .Range("DB" & i)) End If Next ReDim w(1 To myr - 1, 1 To 3) For i = 1 To UBound(w, 1) w(i, 1) = myDic(ws.Range("F" & i + 1).Value)(0) w(i, 2) = myDic(ws.Range("F" & i + 1).Value)(1) w(i, 3) = myDic(ws.Range("F" & i + 1).Value)(2) Next Sheets("A").Range("A1").Resize(UBound(w, 1), 3) = w End With End Sub
If Not myDic.exists(ws.Range("F" & i + 1).Value) Then MsgBox "[" & ws.Range("F" & i + 1).Value & "]がDictionary に登録されていません。" Else w(i, 1) = myDic(ws.Range("F" & i + 1).Value)(0) w(i, 2) = myDic(ws.Range("F" & i + 1).Value)(1) w(i, 3) = myDic(ws.Range("F" & i + 1).Value)(2) End If (Mook)
現在のコードでエラーが出ますか? Dictionary を使用して Range Objectの値を参照する場合は、必ず .Value Propertyを 記述しないとエラーの元ですけど。 (seiya)
w(i, 1) = myDic(ws.Range("F" & i + 1).Value)(0) これは、myDicのなかで、キーがws.Range("F" & i + 1).Valueであるものを取り出す。 で、あれば、先にセットしているような一次元配列が取得できるけど、キーがなければ 空白のVariant型データがかえってくる。なので、かえってきたもの(0) なんてやると 配列じゃないからだめということになる。
そもそもが、myDicへのセットはSheet2のセルの値をキーにしているのに、 ws.と、Sheet1のセルの値をキーにして取り出そうとしている。 なので、当然、未登録(このキーでは書きもまれていない)が発生する。 myDic に登録されているかどうかは myDIc.Exists(キー) で判定可能(True/Flaseがかえってくる) 未登録の場合は、それなりの対処が必要。(スキップするのか、あるいは、何か省略値で処理するのか)
ところで、
w(i, 1) = myDic(ws.Range("F" & i + 1).Value)(0) w(i, 2) = myDic(ws.Range("F" & i + 1).Value)(1) w(i, 3) = myDic(ws.Range("F" & i + 1).Value)(2)
こうしてもいいけど、myDicへのアクセス、ws.Range("F" & i + 1) へのアクセスが、それぞれ3回発生。 Variant型の変数を規定しておいて(たとえば Dim vvv As Variant) vvv = myDic(ws.Range("F" & i + 1).Value) と1回だけ取得して
w(i, 1) = vvv(0) w(i, 2) = vvv(1) w(i, 3) = vvv(2)
とやるほうが、効率がいい。
ぶらっと立ち寄り
追伸
seiyaさんの指摘はきわめて重要。 Dictionaryに限らず、たとえばVariant型変数に Array(セルRange,セルRange) なんてやると 格納された要素は値ではなく、Rage Object。だから、あとで値として取りだそうとすると不具合がでる。 これに限らず、プロパティは、省略せず、かならず明記!
ぶらっと立ち寄り
いま、思い出した。 myDic(.Range("CR" & i).Value) = Array(.Range("AP" & i), .Range("DA" & i), .Range("DB" & i)) この記述、私自身が、「ま」さんのQにサンプルとしてアップしたコードに記載した表記だったような・・・
>これに限らず、プロパティは、省略せず、かならず明記!
この指導文は、自分自身に向けて!
ぶらっと立ち寄り@めちゃくちゃ懺悔
おっしゃるとおり、Valueプロパティを入れたら動きました。 初心者ですいません。 もう一つ質問です。
上記のDictionaryのItemに配列を入れる件ですが、Arrayに入れる個数が不規則な場合です。
例えばA列にA1からAのn行までをArrey関数に入れる場合
Dim i as Long , n as Long Dim v as String Dim vvv as Variant With ActiveSheet n=.Range("A" & Rows.Count).end(xlup).Row v=.Cells(1,1).value For i = 1 to n v=v & "," & .Cells(i,1) Next vvv=Array(v) End With としてmyDicのアイテムとして格納しmyDic(★)(0)とすると、v が取り出されてしまいます。 どのようにしたらよいですか?
vvv=Array(v)) → vvv=Split(v,",") HelpでSplit関数 (seiya)
次々に質問するのではなく1つづつ解決していきませんか?
[[20110530155910]] 『Dictionaryについて』(まー)
[[20110529220102]] 『Rangeでの配列』(まー)
[[20110525000008]] 『outlookのメール本文にセルの内容を貼り付けたい』(まー)
[[20110517093650]] 『関数の参照先について』(まー)
(放置新聞)
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.