[[20160921103056]] 『連想配列でkeyにセルを格納し呼び出したい』(とある中古屋さん) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『連想配列でkeyにセルを格納し呼び出したい』(とある中古屋さん)

初めて質問させていただくので至らぬところがあればご指導お願いします

現在、excelで在庫管理のシステムを作っています(なぜexcelでということはご容赦下さい)
大枠のシステム自体は出来たのですがISBNで検索した本の場所を特定するシステムに躓いています

自分がたてた大まかな理論、構図としては
・地図をセルで作り、各棚に棚番号を割り振る
・在庫管理シートに新たな列『場所』を追加して検索するISBNの欄に、その本がある棚番号を入力する
・棚番号を変数として扱い対応したセルを格納する
・VLookupでセルに入力された棚番号を取り出し、棚番号からセルを取り出し、そのセルを塗る

といった感じで作ろうとしています
恐らく連想配列が必要なのでしょうがどうしたら出来るのか分からず困っています

下記が出来たところまでのマクロです

Sub 地図検索()

    '地図検索システム作成

    '変数使用の宣言
    Dim Ws As Worksheet
    Dim Dat As Range
    Dim Res As Range
    Dim Room As Object
    Dim Paint As String

    '各棚セルを変数に割り振り
    Set Room = CreateObject("Scripting.Dictionary")
    Room.Add "L1", Range("B20").Value
    Room.Add "L2", Range("F20").Value
    Room.Add "L3", Range("J20").Value

    '変数に定義する
    Set Ws = ThisWorkbook.Worksheets("在庫管理")  '在庫管理シートをWsとする
    Set Dat = Ws.Columns("A")  '在庫管理シートのA列をDatとする
    Set Res = Range("C44")  '検索するISBNを入力するセルをResとする

    '変数に計算されたものを入れる
    Tall = WorksheetFunction.CountA(Dat)  '在庫管理シートのA列の入力の行数を確認しtTallとする
    Frame = Ws.Range(Ws.Cells(2, 1), Ws.Cells(Tall, 14))  '在庫管理シートの範囲をFrameとする
    Paint = WorksheetFunction.VLookup(Res.Value, Frame, 13, False)  '入力されたISBNを検索し、設定範囲内N列の場所のセルの値をPaintとする

    'Paintの値をセルに変換し、セルを塗る
    Item(Paint).Interior.ColorIndex = 3

    '割り振りを破棄
    Set Room = Nothing
End Sub

< 使用 Excel:Excel2010、使用 OS:WindowsVista >


 >>恐らく連想配列が必要なのでしょうがどうしたら出来るのか分からず困っています 

 要件がいまいち不明ですけど、処理する部品として Dictionary を使うということもありえるでしょうし、
 Dictionary を使わなくても、(おそらく)処理可能でしょう。

 あくまで、要件を明確にされるべきだと思います。
 それによって、じゃぁ、こんなようにDictionaryを使いましょうという回答もでてくるかもしれません。
 (要件を実現するためのコードの仕様としてDictionaryの登場はあるかもしれません。)

 それとも、要件は自分の中では明確だ。それを処理するためにDictionaryを使うというロジック仕様も間違っていない。
 ただ、Dictionaryの使い方がよくわからない。教えてほしい。

 こういうことでしょうか?
 であれば、(Dictionaryを使うコード自体は簡単というか、単純ですので)ネットで検索して勉強されたら
 よろしいかと思います。

 あるいは、実際にDictionaryを使って処理するコードを書いておられるとしたら、それをアップし、
 自分としては、これで、これこれ、こうなると思って記述しているけど、そうならず、こうなってしまう。
 なぜだろうという質問にされるべきかな?

 つまり、何が質問のテーマなのか、何を質問しておられ、何を回答したらいいのか、よくわからないというのが
 感想です。

(β) 2016/09/21(水) 16:56


要領を得ない質問をしてしまいすみません

Q.意図した構図のシステムを作るにはdictionaryを使用するのが適切なのか
問題無いならば

    'Paintの値をセルに変換し、セルを塗る
    Item(Paint).Interior.ColorIndex = 3

Q.上記の辺りでエラーが発生するのでどう処理をしたら良いのか
あとExcelを触り始めたのばかりなので

Q.システムが絡まっていないか、もっと早く回転するシステムもあるのではないか
この三点が質問内容です
お手数おかけしてすみません

(とある中古屋さん) 2016/09/21(水) 17:19


 > Set Room = CreateObject("Scripting.Dictionary")
レイトバインドしていますが、このオブジェクトはレイトバインドだと、.Itemとか.Keyのプロパティが利用できないのです。
アーリーバインドに変えてみてください。

具体的には、まず「参照設定」で「Microsoft Scripting Runtime」をチェックします。でもって、配列の宣言部分は以下。

 Dim Room As New Dictionary

(???) 2016/09/21(水) 17:49


また、Dictionaryを使うべきか?、という事については、別に毎回セルを全検索しても良いのでは?、と思います。

具体的には、セルに値を入れた後、コマンドボタンでも配置しておき、押下されると Excelの検索機能が動作し、番号が一致するセルに飛ぶ。
どんな命令を使うのかは、手作業で実行しマクロ記録すれば判ります。いかがでしょうか。
(???) 2016/09/21(水) 17:54


宣言文を変えるだけで良かったんですね!
ありがとうございます
設定自体は変えてはいたんですが、自分が何かシステムを間違えているのではっと思っていました

全部のセルを検索は一度試してみて測ってみようかと思います
どうもありがとうございます!
(とある中古屋さん) 2016/09/21(水) 19:05


 解決後(??)ですけど。

 >>意図した構図のシステムを作るにはdictionaryを使用するのが適切なのか 

 もう少し、やりたいことを、コードがどうこう、キーのマッチングがどうこうということではなく、
 運用要件として、元データのレイアウトと項目説明、そのデータに対する処理要件、結果の反映要件とレイアウト。
 こういったものを、かみ砕いて説明すべきです。

 コメントしましたが、Dictionaryを使って処理することもできるでしょうし、使わずに処理することもできるでしょう。
 Dictionaryを使用するのが適切か という問いそのものが、的外れのような気がしますよ。

(β) 2016/09/21(水) 19:20


うーん、結局できなかったです……

βさんへ
あまり話しすぎるのもダメだと思い省略してしまいました

Excelの内容は
シートが、データ検索、出入管理、在庫管理、見取り図の4つ
今回使っているのは在庫管理と見取り図のシート
見取り図にはISBNを入力するセルを作り、その隣に今回実装予定のマクロのボタンもある
見取り図には地図があり、それ自体はセルで出来ていて、色を塗るならセルを指定したら塗れる
在庫管理にはデータが各項目ごとに記入がされている
ISBN、タイトル、作者、等の項目が一行目の横向きに書いてある

在庫管理シート
  A     B     C        N
1 ISBN   タイトル  作者   ……  場所
2 978406/ ○○○a   △△△      L3
3 978406/ ○○○b   △△△      L3
4 978406/ ○○○c   △△△      L3

見取り図シート(地図に関しては例えばの形で書いています)
 ABCDEFGHIJKLMNO
1
2    ■■■■ ■■■■  ■
3               ■
4    ■■■■ ■■■■  ■
5               ■
6
7   「    」←こちらにISBN  ボタン□

(とある中古屋さん) 2016/09/22(木) 11:00


とりあえずMicrosoft Scripting Runtimeにはチェック入れてます

マクロの内容は以下の通りです

Sub 地図検索()

    '地図検索システム作成

    '変数使用の宣言
    Dim Ws As Worksheet
    Dim Dat As Range
    Dim Res As Range
    Dim Ans As Object
    Dim Paint As String
    Dim Room As New Scripting.Dictionary

    '各棚セルを変数に割り振り
    Room.Add "L1", Range("B20").Value
    Room.Add "L2", Range("F20").Value
    Room.Add "L3", Range("J20").Value

    '変数に定義する
    Set Ws = ThisWorkbook.Worksheets("在庫管理")  '在庫管理シートをWsとする
    Set Dat = Ws.Columns("A")  '在庫管理シートのA列をDatとする
    Set Res = Range("C44")  '検索するISBNを入力するセルをResとする

    '変数に計算されたものを入れる
    Tall = WorksheetFunction.CountA(Dat)  '在庫管理シートのA列の入力の行数を確認しtTallとする
    Frame = Ws.Range(Ws.Cells(2, 1), Ws.Cells(Tall, 14))  '在庫管理シートの範囲をFrameとする
    Paint = WorksheetFunction.VLookup(Res.Value, Frame, 13, False)  '入力されたISBNを検索し、設定範囲内N列の場所のセルの値をPaintとする
    'Paintの値をセルに変換し、セルを塗る
    Ans = Room.Items(Paint)←
    Ans.Interior.ColorIndex = 3

    '割り振りを破棄
    Set Room = Nothing
End Sub

←ここでエラーが発生します
エラーの内容は型が一致しないとのこと
Variantやらobjectつっこんでも変わりなし
Stringは突っ込んだらセルを認識できなくなる
どうしたらエラーをなくしてキーからセルを取り出せますか?
(とある中古屋さん) 2016/09/22(木) 11:15


すみません、自決しました

Room.Add "L3", Range("J20")
Set Ans = Room.Item(Paint)

.Value←がいらなかったようです
(とある中古屋さん) 2016/09/22(木) 11:56


すみません、自決?後にすみません。

???さんがお書きになった、
> > Set Room = CreateObject("Scripting.Dictionary")
>レイトバインドしていますが、このオブジェクトはレイトバインドだと、.Itemとか.Keyのプロパティが利用できないのです。
が良く理解できないでいます。

 Sub test()
     Dim dic As Object

     Set dic = CreateObject("Scripting.Dictionary")

     dic("a") = 1
     dic("b") = 2
     dic.Key("b") = "c"

     Debug.Print dic("c")  ' => 2 が出力されます
 End Sub

 何か、使えそうな感じですけど。
(γ) 2016/09/22(木) 14:41

お目汚し、横レスすみません
もしかしたらもうすでにお調べして知ってるかもしれませんが……

http://oshiete.goo.ne.jp/qa/8167504.html
Dictionaryについてさがしていたらこれが出てきました
回答の中にはhttp://www5f.biglobe.ne.jp/~f-lap/tips_staticarray.htm
っという参照URLもあったので
自分は理解できませんでしたが役に立てたら幸いです
(とある中古屋さん) 2016/09/22(木) 15:08


情報提供、ありがとうございます。
すみません、私のコメントへの参考情報でしょうか。
私の発言に対してどのようなインプリケーションがあるのでしょうか。
教えてください。
 
実行速度とか、インテリセンスの利き方とかは承知していますが、
機能に差があるという話は初耳でしたのでお聞きしています。
(γ) 2016/09/22(木) 15:26


すみません(;
まだExcel齧って二週間も経ってないんです
VBAに至っては4日目くらいなんです
Dictionaryの細かな違いについて聞いたのだと思い、以前それっぽいURLを出したのです
ほんとすみません

で、あと多分ですが機能差については、無いと思います
鵜原パソコンソフト研究所のサイトをよく閲覧しているのですが
http://excel-ubara.com/excelvba4/EXCEL216.htmlでは全く問題ないといった感じで
書いてるようなので……

ちなみに宣言文とは全く関係ないところでミスをしていたので
宣言文を変えたから直った、一歩近づいたということも無いと思います

>>マナさんへ
名前定義でですか
総当たりのイメージとしては
=ならばgoto、Elseなら次へで考えていました
名前定義についても調べてみようと思います
(とある中古屋さん) 2016/09/22(木) 15:53


ごめんなさい。
よく理解しないでコメントしてしまったと思い
削除したのですが遅すぎました。

Dictionaryに登録するかわりに
棚番号で当該セル範囲を名前定義しておけば
Vlookupの検索だけですむという考えです。

(マナ) 2016/09/22(木) 16:08


 横から失礼します。

 ???さんのバインディングに関するコメントは、インテリセンスがきかないということでしょうかね。
 事前バインディングであれ、実行時バインディングであれ、機能は全く変わりませんので。

 それにしてもγさんに、Dictionaryのなんぞやをアドバイスなどという大それたレス、初めて見ましたねぇ。

 いずれにしても、質問者さん、何か Dictionary が、特定の何かをするための完成品だと、そう誤解しておられるような気がしますね。
 Dictionaryは、あくまでDictionary という【道具】に過ぎないのですけど・・・

 なんだか、【連想配列にチャレンジするんだ!!】と、肩に力が入りすぎているような気がします。

(β) 2016/09/22(木) 20:29


βさん、どうもです。
いえいえ、駆け出しの者ですので。
実は、DictionaryのKey項目をつけかえるというコードは始めて書いたような次第です。
おっしゃるようにインテリセンスのことに言及されたとすれば、腹に落ちます。
もっとも、参照設定しておけば、
  Dim dic As Dictionary
  Set dic = CreateObject("Scripting.Dictionary")
と書いてもインテリセンスは利くので、
CreateObjectの使用とは無関係なんですけども。
(こうしたことは百も承知のご発言だったはずで、
 こちらの解釈が狭いんだろうとは思います。)

(γ) 2016/09/22(木) 20:52


 私もDictionaryのキーの付け替えコードは書いたことがありません。
 使える局面も、少なからずあると思うのですが、

 Sub Test()
    Dim dic As Object

    Set dic = CreateObject("Scripting.Dictionary")

    dic("A") = "abc"
    dic("B") = "xyz"

    dic.Key("B") = "A"

 End Sub

 この状況だとエラーになってしまいますので、キーの付け替え前に、付け替え後のキーが存在すれば、それをRemoveしてからキー変更をする、
 あるいは要件によっては、すでに存在するので付け替えできないといった制御をいれる必要があって、ちょっと
 面倒かもしれませんね。

(β) 2016/09/22(木) 22:59


質問者の自分の結論としては
なんだか知恵袋と同じような場所だなぁと思いました
私はここに来たのは初めてで、右も左も分からず
とりあえず、自分が作りたい理由と、こうしたシステムにしたいというのを明記して
それでも情報が不足してるのかも知れないと思い最初に「至らぬ所があれば」そういう文を入れたのですが

返ってくる内容は、あやふやなものばかりで
最終行き着くのは、自分で調べたら?というもの
調べて調べて分からなかったからきたのですが……
・どんなにExcelが長けた人でもどこでエラーが発生するかは、読んでも分からない
・初めて来たというのに関わらず内輪コミュニティの内容を即座に把握せよという人もいる
・知恵袋で「ggれば?」、みたいな回答をする人がほとんど
という点に関して分かったのは良しとします

最終、そのだいそれたかたの手を煩わせず
自分で解決し、学校という建前上、自分で理解を深める形になって
良かったと思います
これにて私は失礼させていただきます
貴重なお時間頂きありがとうございます
(とある中古屋さん) 2016/09/22(木) 23:27


質問者さんはもう来られないかも知れませんが、遅ればせながら蛇足。

ここに限らず、プログラミング系のQA掲示板は、知恵袋と違い、これをやってみたら?、系の回答が多いです。それは、知恵袋なら知っている知識を書くだけですが、プログラムの場合、そのものずばりの回答をするためには、実際にある程度コーディングするという時間と手間がかかるためです。

また、ここの場合は特に「学校」という名を掲げているわけで、質問者が自分で学習するのを手助けするような回答が多くなります。これも、そのものずばりが少ない原因かと思います。 そのまま動くコード例が書かれている場合、それは多数の命令や組み方等、説明文を書くと長くなって読みにくくなり、意味が的確に通じず、コーディングが完成しないだろう、というようなケースです。コード例を挙げて、使っている命令を調べてもらうのが、一番理解しやすいだろう、という考えです。 自分で調べる事も、プログラムを作成するための大事な行動なのです。

話は変わって、γさんの疑問については、以下の例を試してみてください。インテリセンス機能もありますが、例えば、配列のn番目を取り出す、という使い方が、レイトバインディングだとエラーになります。

 Sub test()
'    Dim dic As Object
'    Set dic = CreateObject("Scripting.Dictionary")
    Dim dic As New Dictionary

    dic("a") = 1
    dic("b") = 2
    dic.Key("b") = "c"
    Debug.Print dic("c")
    Debug.Print dic.Items(0)
 End Sub
(???) 2016/09/23(金) 09:38

 ???さん ありがとうございました。
 そういうご指摘でしたか。承知いたしました。

 なお、そういう場合は、
     Debug.Print dic.Items()(0)
 と書くのかと思っていました。
 使えないというわけでもないのかなと思います。

 質問者さんへ。

 自己解決されたということでしたので、回答者さんのコメントに対して
 質問コメントをさせてもらったのですが、
 結果的に思わしくない方向に向かってしまったとすれば、
 申し訳なかったですね。

 Q/Aの延長線上にあるだろうと思って続けてコメントしたのですが、
 私の質問として別スレッドですべきだったでしょうか。(ちょっと迷いましたが)
 で、特に、質問者さんに対してコメントを求めたわけではなかったのですが、
 にもかかわらず、「機能差については、無いと思います」とコメントいただき、
 ありがとうございました。

 ところで、前半のやりとりを拝見しての印象を書かせて頂けば、
 別に「あやふやなものばかりで」とは思いません。
 Dictionaryを使うべきかどうかは判断の余地がある話であって、
 「必ず使うべきだ」というのも変ではないでしょうか。
 人生相談よろしく相談者の望むような回答を、
 回答者がするのが普通だ、いうわけでもありません。
 あなたが望む回答が直ちに得られなかったからといって憤慨なさるのも
 少し変かなあと思いました。言い過ぎでしたら失礼。

 また、???さんのご意見に同意します。
 ただ、回答者さんの中には違ったスタンスのかたもおられます。
 そうした多様性こそが貴重なものと認識しております。

 (余談:自己解決の省略として「自決」というのは普通なんですか?初めて見ました。
    「自決」って普通は、もっと別の深刻な意味で使うものと承知していましたが。)

(γ) 2016/09/23(金) 10:00


 2ちゃんの「思わず笑ったコピペ」から引用している言い回しではないかと思われます。

 129 名前:[名無し]さん(bin+cue).rar 投稿日:2007/05/04(金) 18:32:42
 すいません、動画が見れないんですけど何のコーディック入れたらいいんですか?

 130 名前:[名無し]さん(bin+cue).rar 投稿日:2007/05/04(金) 19:51:30

 自決しました

 131 名前:[名無し]さん(bin+cue).rar 投稿日:2007/05/04(金) 20:02:22
 待て!はやまるな!

 132 名前:[名無し]さん(bin+cue).rar 投稿日:2007/05/04(金) 20:03:56
 >>129-131
 モロタwwww

 133 名前:[名無し]さん(bin+cue).rar 投稿日:2007/05/04(金) 22:03:11
 ワロタだった・・・
 モロタって何をだよ・・・

 134 名前:[名無し]さん(bin+cue).rar 投稿日:2007/05/04(金) 22:07:25
 お命だろ

 (スレ汚しスミマセン。色々な意味で「面白い」スレだったのでつい)

(白茶) 2016/09/23(金) 12:07


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.