Windows200とXPの違いについて

解決


fumo  2008-09-24 17:09:28  No: 140508  IP: 192.*.*.*

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はエラーに
ならないのかが不明です。
ご教授下さい。

編集 削除
魔界の仮面弁士  2008-09-25 03:08:03  No: 140509  IP: 192.*.*.*

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回目以降の動作に不具合を生じたりしますので。

編集 削除
fumo  2008-09-25 11:02:03  No: 140510  IP: 192.*.*.*

>ところで、実家環境にインストールされている 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の違いで
エラーが発生するのでしょうか?

編集 削除
魔界の仮面弁士  2008-09-25 14:06:26  No: 140511  IP: 192.*.*.*

> 開発環境: 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

編集 削除
fumo  2008-09-25 18:48:17  No: 140512  IP: 192.*.*.*

>> 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に対応していないから
エラーが発生するのでしょうか?

編集 削除
魔界の仮面弁士  2008-09-25 19:35:23  No: 140513  IP: 192.*.*.*

# 題名といい今回といい、"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 の数値に変換される事を確認できます。

編集 削除
fumo  2008-09-26 07:57:03  No: 140514  IP: 192.*.*.*

># 題名といい今回といい、"2000" が "200" になっているのが無性に気になる…。

すいません・・・
単なるタイプミスです。

いろいろと懇切丁寧なアドバイスありがとうございました。
解決&納得しました。

編集 削除