Excel使うのに辞書なんか引いたことないが?
事務員さんにDictionaryって言ったらまず何が出てきます?
そう!辞書ですよね。
なんで表計算ソフトで辞書の話が出てくるんや!!!
え?もしかしてあの、よく書店で売ってる「300個のワザ!」みたいな辞書並の厚さした本のことですか!?
んな訳あるか〜い!!
こんにちは〜!「マクロの書ける事務員さん」です。
仕事納めましたか〜?私は納めました。よかった〜!
さて。
今回も経験に基づくオモシロポエムとして書いていくので、相変わらず間違いなどもあるかも。
というかこの時点での「事務員さん」はまだまだ未熟でぼんやりやっているのですぐ何かに役立つことはほぼ書いてありません。
同じような「事務員さん」達がわかるよ〜と握手をしてくれたり、
「事務員さん」が書いたマクロに苦しめられるIT課の方々が 「こういう経緯でこの闇が生まれてんのか……」 と頭を抱えたり、
そのくらいのことをしてくれればいいなと相変わらず思っています。
1はここ → 「マクロの書ける事務員さん」がC#に至る経緯 1
次はここ → 「マクロの書ける事務員さん」がC#に至る経緯 3
事務員さんの現在地が知りたい方はここ→note
操作をなぞるコードからの卒業
小さなスモールステップを踏んで、ある時突然天啓のように現れたのが、Scripting.Dictionaryでした。
どうにもVlookupを高速化するには最終的にコレを触らないといけないらしい。
でも突然今まで調べていたウェブページとは違う語彙が増え、事務員さんにはワケの分からない情報が増えてきます。
配列?連想配列?参照設定?……何それ?
つまりDictionary?辞書?辞書って何?自分いつもExcel使うときに辞書なんか引きませんけど?
困りましたね。突然デカい壁が立ちはだかってきました。
事務員さんは残念ながら事務員なので、誰かコードを書く先輩がいたりするワケではありません。
周りにマクロを使う人間は少しいたとしても、その人たちは記録マクロのちょっとした修正しかできませんでした。ちょっと範囲広げるとか。
あれ?これなんかどっかでもう見たかも……
そんなところはとっくに踏み越えてしまっているし、となると突然なんだか誰も助けてくれない……
アレレ?なんか沼に踏み込み過ぎたのでは?
気付いたときにはもう遅いんですけど。
配列操作への誘い
「Scripting.Dictionary、つまり連想配列の速度をフルに活かすには配列を一緒に使うのが一番です」
とか言われましても。
配列って何です?
WS上を直接取得してそのまま戻すんじゃ連想配列を使う意味がない?
じゃあ……配列?ってヤツ……使う?
まあ連想配列に入るまでも大変でしたね。
つまりただの配列をいじろうとしていた時代です。
配列をいじっていると思っていても、いかんせん事務員さんはRange(範囲)とRange(オブジェクト)の違いが分からないのでオブジェクトを指定しており結局セルの直接編集をしていたりします。
いや本当にアレよくないですよね。どっちもおんなじRangeなんだもん。 最初そんなん分からんわ。
あとなんですか?なんで配列の1個目の住所が0のときと1の時があるんだ?
本当に意味わかんないですよね。
1からスタートしたら1つ目のデータが入ってなかったり、
逆に0からスタートしたらそんなもんないわってエラーが出たり。
というかまずマス目の話ならExcelがやれやとも思うし。でも遅いし。
参照設定も謎ですよね。
なんかインターネットの海を漂流していると、あるサイトでは
「参照設定をしてからDim 辞書 as Dictionaryしろ」
って言われたり、
はたまた違うサイトに辿り着くと
「いやいや参照設定はやめろ!Dim 辞書 as ObjectしてからCreateObject("Scripting.Dictionary")しろ」
って言ってきたり。
結局何が違うんや!!
(ちなみに当時の事務員さんは結局参照設定していました。
インテリセンス効いて初心者にはすごく分かりやすいですしね。
入力しないといけない文字数も少ないし。
今は別の人間が使うマクロ書いてるのが主だったり、
目前に派遣期間の終わりが見えている都合上後任が困ったら可哀想なので
基本的に参照設定しないで遅延バインディングしています)
一回配列「処理範囲」に処理したい範囲を入れて?
Vlookupで言う検索対象範囲の一番左側に来る、探したいものがDictionaryのKeyで?
検索対象範囲の中で取ってきたいものになるのがItemなのね?
じゃあ「処理範囲」をi=Lbound(処理範囲) to Ubound(処理範囲)でループして、
DictionaryにAddしていきましょっか。
あ!Keyが被るとエラーが出るの〜!? 参ったなあ。
じゃあしょうがないからExistsで確認してから入れましょう。
で、探したいコードの一覧が入ってる範囲は「コード一覧」って名前の配列にでも入れときましょうか。
その結果を出力する、元来では数式を出力してたセルの代わりに
「結果出力配列」をRedimしてコード一覧と同じ大きさにしときましょ。
そしたらi= 1 to 行数 −1でループして、
(1行目はヘッダなんでしょうね……(笑))
結果出力配列にどんどんDictionaryから引き出して入れていきましょう。
それを対象範囲.value=結果出力配列すればいいんだ?
ふうん、そんなもんで早くなるワケ……あったんだが?
なんと突然コーヒーを飲む時間なんてなくなっちゃいました。
ボタンを押してから結果が返ってくるまでが、突然離席なんか出来る余地を失ってしまいました。
Scripting.Dictionaryさんはすごい。
気付いたら事務員さんの横で得意げにメガネをクイとやって言うのです。
「私めがこの作業、さっさとやっておきました」 と。
なんてことでしょう。
事務員さんの世界は全く変わってしまいました。
(ちなみに当時この時期の私は実際変数名に日本語を使っていました。
どれが変数なのかがぱっと見で分かりやすくて初心者的には良かったです。
まあこれが許されるのもVBAの寛容さとちょっとした悪さですね)
事務員さんあるある〜!
「Excelのことを聞かれるがいつもVBAでやってるせいでWS関数だけだとどうやるか分からない」
その作業?出来ますよ!
あ〜、関数使ってやりたい?出来ると思いますよ!
ええと……一回ググっていいですか?
次回予告
え〜こんなに早くて楽になるなんてScripting.Dictionary最強じゃ〜ん!すげ〜!
このまま自分の持ってる作業ぜ〜んぶ高速化してやろうぜ!
次回 「オートフィルタへの憎しみ」
おたのしみに〜!