VB6: COM 経由での文字列渡しに CStr を使う例

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 メソッドの呼び出しはレイトバインディングでやってるはずだ。もしアーリーバインディングだったら、引数の型情報が利用できるからどれでもうまくいきそうな気がする。