VB2005でMicorsoft Excel9.0 Object Libraryを使い
エクセルにデータを書き込むものを作ったのですが
WindowsXP上では問題なく起動するのですが
Winsows2000(.net Framework2.0インストール済み)で
起動するとエクセルに書き込む箇所で下記のエラーがでます。
-- エラー発生箇所 --
xlWks.Cells(W_I, Col_ResultRetsu).Value = Upd_Bikou
-- エラー内容 --
System.Runtime.InteropServices.COMException (0x80020008):
変数の種類が間違っています。
(Exception from HRESULT: 0x80020008 (DISP_E_BADVARTYPE))
上記のエラーを調べたところVBA,VB6でのLong型は4バイトで
.netのLong型は8バイトになっているために出るエラーで
上記エラー箇所の変数W_IとCol_ResultRetsuのLong型を
Integer型にすると上記エラーは発生しなくなったのですが
ではなぜWindows2000でエラーになってWindowsXPはエラーに
ならないのかが不明です。
ご教授下さい。
9.0 (Excel 2000) ですか…。また厄介なバージョンをお使いですね。
残念ながら、Office 2000 用の PIA は用意されていません。
XP(2002)/2003/2007 なら、問題は出にくいのですけれども。
ところで、実家環境にインストールされている Excel のバージョンは何ですか?
Excel のライブラリというのは、バージョン間のバイナリ互換性が
ありません。Sub メソッドであったものが、バージョンアップによって
Function メソッドになってみたり、バージョンによって引数の数が
変化したりするものもあります。
そのため、開発環境の Excel バージョンと実行環境のバージョンとを、
できる限り一致させておく必要があります。バージョン混在が必要なら
参照設定は諦めて、レイトバインドでの動作を検討する必要があるでしょう。
> xlWks.Cells(W_I, Col_ResultRetsu).Value = Upd_Bikou
提示された変数 xlWks/W_I/Col_ResultRetsu/Upd_Bikou は、
それぞれどのようなデータ型ですか?
で、ご存知かも知れませんが、そのような書き方が許されるのは、
VBA/VB6/VBScript の場合です。.NET の場合は、
Dim R1 As Excel.Range = xlWks.Cells
Dim R2 As Excel.Range = R1(W_I, Col_ResultRetsu)
R2.Value = Upd_Bikou
Marshal.ReleaseComObject(R2)
Marshal.ReleaseComObject(R1)
のように、個々の COM オブジェクトへの参照を変数にとり、明示的に
ReleaseComObject メソッドを呼び出す必要があります。そうしないと、
オブジェクトの開放漏れによって、Excel のプロセスが終了しなかったり、
連続実行時に、2回目以降の動作に不具合を生じたりしますので。
>ところで、実家環境にインストールされている Excel のバージョンは何ですか?
開発環境: Excel 2000 (9.0.3821 SR-1)
クライアント: Excel 2000 (9.0.4402 SR-1)
です
>提示された変数 xlWks/W_I/Col_ResultRetsu/Upd_Bikou は、
それぞれどのようなデータ型ですか?
Public xlWks As Excel.Worksheet
Private W_I As Long
Private Col_ResultRetsu As Long
Private Upd_Bikou As String
になっています。
>個々の COM オブジェクトへの参照を変数にとり、明示的に
>ReleaseComObject メソッドを呼び出す必要があります。そうしないと、
>オブジェクトの開放漏れによって、Excel のプロセスが終了しなかったり、
>連続実行時に、2回目以降の動作に不具合を生じたりしますので。
知りませんでした^^;
.NETのコードを変更したいと思います。
Office 2000 用の PIA がない為にWindows2000とXPの違いで
エラーが発生するのでしょうか?
> 開発環境: Excel 2000 (9.0.3821 SR-1)
> クライアント: Excel 2000 (9.0.4402 SR-1)
ということはおそらく、OS 自体が持つ OLE 関連 DLL の差によって
動作の違いが出ているのでしょう。本来はどちらであっても動くはずなので
どこかにコーディング上の問題があるのかも知れません。
> Private Col_ResultRetsu As Long
これが原因では無いかな…?
Long ということは、64bit 整数型ですよね。マズイと思いますよ。
Excel VBA は、64 bit 整数型をサポートしていませんので。
(VBA の Long 型は 32bit、VB.NET の Long 型は 64bit です)
ちなみに DISP_E_BADVARTYPE エラーとは、「無効なデータ型の変数です」のような意味です。
> 知りませんでした^^;
> .NETのコードを変更したいと思います。
下記に目を通しておかれることをおすすめします。
http://support.microsoft.com/kb/317109/ja
http://hanatyan.sakura.ne.jp/dotnet/Excel08.htm
http://jeanne.wankuma.com/tips/vb.net/programming/releasecom.html
> Office 2000 用の PIA がない為にWindows2000とXPの違いで
> エラーが発生するのでしょうか?
それはまた別の話だったりします。
Excel 2002 以上であれば、PIA を使うのが最良の策なのですが、
Excel 2000 向けに開発するなら、PIA はそもそも存在しないので、
IA を用いるか、レイトバインドするかの二択になります。
なお、自動生成されたOfiice 用の COM 相互運用機能アセンブリ(IA) は非公式とされており、
できる限り Ofiice 用にはプライマリ相互運用機能アセンブリ(PIA)を使うべきとされています。
[Office XP PIA]
http://support.microsoft.com/kb/328912/ja
[Office 2003 PIA]
http://www.microsoft.com/japan/msdn/office/office2003/OfficePrimaryInteropAssembliesFAQ.aspx
>> Private Col_ResultRetsu As Long
>これが原因では無いかな…?
>Long ということは、64bit 整数型ですよね。マズイと思いますよ。
>Excel VBA は、64 bit 整数型をサポートしていませんので。
>.(VBA の Long 型は 32bit、VB.NET の Long 型は 64bit です)
>ちなみに DISP_E_BADVARTYPE エラーとは、「無効なデータ型の変数です」
>のような意味です。
Private Col_ResultRetsu As Long を
Private Col_ResultRetsu As Integer に
するとエラーは発生しなくなるのですが
Windos200は64bitに対応していないから
エラーが発生するのでしょうか?
# 題名といい今回といい、"2000" が "200" になっているのが無性に気になる…。
> Windos200は64bitに対応していないから
> エラーが発生するのでしょうか?
Windows 2000 では、VT_I8 / VT_UI8 の Variant型がサポートされて
いないので、そのような結果になります。
ただし今回の件について言えば、XP で Long 指定で動いたと言っても、
それは OS の仕様変更によって、動くようになってしまったというだけで、
本来は、Excel オブジェクトに指定すべき型では無いかと。
そもそも Excel オブジェクトは、VBA からの利用を前提としており、
しかも VBA や VB6 では、Int64 相当の型を直接サポートしていないのですから
Long を指定したのは、コーディングミスに近い事かと思われます。
ちなみに、『MsgBox CCur("&H1234567890")』と書いたテキストを
拡張子 *.vbs として保存し、ダブルクリックしてみると、
Win2000 ではオーバーフローのエラーになりますが、
WinXP では、78187493520 の数値に変換される事を確認できます。
># 題名といい今回といい、"2000" が "200" になっているのが無性に気になる…。
すいません・・・
単なるタイプミスです。
いろいろと懇切丁寧なアドバイスありがとうございました。
解決&納得しました。