VB6 のアプリケーションから COM コンポーネントのメソッドを呼ぶとき、引数が String 型の定数だとうまくいくのに、同じ String 型の変数にするとエラーになる、という例にあたった。
事実
まず、これはうまくいった。
WebBrowser1.Document.All("foo").Value = NewValue
定数にしても OK だった。
Const cFieldName As String = "foo" WebBrowser1.Document.All(cFieldName).Value = NewValue
ところが、変数にしてみたら、All メソッドが失敗する (ユーザ定義型のメンバになっている場合も同じ)。
Dim sFieldName As String sFieldName = "foo" WebBrowser1.Document.All(sFieldName).Value = NewValue
なんでだ。試しに CStr 関数をかませてみたら、うまくいった。
Dim sFieldName As String sFieldName = "foo" WebBrowser1.Document.All(CStr(sFieldName)).Value = NewValue
さらに、型を Variant にしてもうまくいった。
Dim vFieldName As Variant vFieldName = "foo" WebBrowser1.Document.All(vFieldName).Value = NewValue
推測
同じ変数なのに String 型だとダメで Variant 型 (内部型は String のハズ) だと OK だということは、All メソッドの引数は BSTR じゃなくて VARIANT でないといけないんじゃないか。
で、VB6 は、「変数の型」がある場合はそれを使って引数を組み立て、そうでない場合 (リテラルや定数、関数の返り値) はとりあえず Variant で渡すとか……?
上記の場合、WebBrowser1.Document まではコード補完が効いていて、All 以降は効いていなかったので、All メソッドの呼び出しはレイトバインディングでやってるはずだ。もしアーリーバインディングだったら、引数の型情報が利用できるからどれでもうまくいきそうな気がする。