トップ «前の日記(2007-11-14) 最新 次の日記(2007-11-18)» 編集

十日日記


2007-11-15

Link 連想配列にCollectionを使わない理由

Joel Spolskyは「はじめてのBillGレビューのこと」(青木靖訳)の中で、Excelのためのマクロ言語(現在のExcel VBA)を設計するためにVisual Basicに導入した機能4つを述べている。

私は自分のお気に入りの機能を4つBasicにどうにか付け加えた。ひとつはVariant型だ。……(中略)……それからレイトバインディングを追加してもらった。……(中略)……それからお気に入りの言語構文を2つ、cshからもらってきたFor Eachと、PascalからもらってきたWithだ。

この部分を読んで、Excel VBAで便利な部分のかなりをJoelに負っているのだなあと驚いたことがある。またWith文はともかく、残りの3つは密接に関連している。For Each構文ではVariant型しか使えないし、実行時結合のおかげでobjectをVariant型に代入すると色々なことが行なえる。

さて、Visual Basicの配列周辺の実装が現代的な言語にくらべて貧相なことは知られたことだ。対処法もいくつかあって、自分でクラスを定義する方法もあれば、本来はオブジェクトの配列であるCollectionクラスを動的配列に使用する向きもあるし、ADOのRecordsetを流用する手もあれば、.NET FrameworkのArrayListクラスを引っ張り出してくることもできる。私自身は、Excel VBAに最初から備わっているCollectionクラスを使うことが多い。

.NET Frameworkの利用について付け加えたい。こちらについては、検索エンジン以外の方法で辿り着けたことがないMicrosoft TechNet 2007年1月号の「Hey, Scripting Guy!」に詳細が掲載されている。簡単にまとめると、.NETのクラスの一部はCOM相互運用機能が実装されているけれども、その一覧はないから自分で調べてくれ、という話だ。こんなふうにVB[AS]?から.NETへアクセスして機能拡張を図る試みとしては、たとえばWSHのSendKeysで日本語を入力するを参照。

しかし、COMではメソッドの上書きはサポートされていない。たとえばStringBuilderクラスのAppendメソッドなどはリンク先のようにオーバーロードされているのだが、これらを型によって使い分けなくてはならない。Of Kings and Cabbageの「Marvels of COM .NET interop」を参考に総当たりで調べてみると、String型に対応するメソッドは「Append_18」のようである。だからWSHで

Option Explicit
Dim sb: set sb = CreateObject("System.Text.StringBuilder")
Dim i
For i = 0 To 10000
    sb.Append_18 CStr(i)
Next
WScript.Echo sb.Length

のように使用できるわけだ。なお、dotNet Fireの「Late-bound COM calls to overloaded .NET method need decorated names?」によれば、VS 2005のOleView.exeを使えばメソッドのオーバーロード順がわかるというのだが、使い方がわからない。

話を配列に戻す。このまえCollectionを見ていたら、AddメソッドにItemだけでなくKeyがあるのに気がついた。Keyもあるなら連想配列としても使えるわけで、それならMicrosoft Scripting RuntimeのScripting.Dictionaryを使う必要もないではないか。

ところが現実は甘くはない。Collectionには、そのキーが配列に存在するかどうかを確認するためのメソッド(DictionaryならExists)が存在しないのだ。だからOn Error GoToで対処しなくてはならず、これはさすがに面倒極まりない。.NETにしたいならSystem.Collections.Hashtableが使えるが、そんな酔狂な人はいないだろう。素直にDictionaryを使うのが一番のようだ。

Tags: Excel
本日のツッコミ(全1件) [ツッコミを入れる]
Link 通りすがり (2019-09-20 14:06)

> Collectionには、そのキーが配列に存在するかどうかを確認するためのメソッド(DictionaryならExists)が存在しないのだ。だからOn Error GoToで対処しなくてはならず、これはさすがに面倒極まりない。 <br> <br>Containsというメソッドがあります。 <br>vbaで.Netを避けるのは.Netインストールが必須になるからで、これは理由にはなりませんよね。

[]


プロフィール

渡辺 慎太郎(na@10days.org)

分野別表示

Admin | Client | Dev | Excel | Linux | PC | PDA | Web | iPad | web | 家電 | 文具 | | 英語 | 言語 | | 音楽

月別表示

1999|07|
2003|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|

最近の記事

雨量情報 dictionary.com Yahoo google Yahoo! 路線情報 東京アメッシュ l-mura l-aka l-momo 目次 r-mura r-aka r-daidai r-kiiro asahi.com nogulabo r-sora r-midori r-midori r-momo