tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルアプリケーションのコンポーネントで…例外が
記事No10932
投稿日: 2012/10/02(Tue) 13:23
投稿者タダシ
Visual Basic 2010
アクセスデータベースのあるテーブルからSUM関数を使用してデータの合計を表示させるPGを作っています。そこで以下のようなエラーが発生します。

アプリケーションのコンポーネントでハンドルされていない例外が発生しました。
[続行]をクリックすると、アプリケーションはこのエラーを無視し、続行しようとします。
[終了]をクリックすると、アプリケーションは直ちに終了します。

アセンブリ'AS受入管理システム, Version=1.0.0.8, Culture=neutral,
PublicKeyToken=null'から型
'ADODB.Fields ToInternal Fields Marshaler'を読み込めませんでした。

というエラーメッセージが出てきます。

コードは
lsSqlSum = "SELECT Sum(数量) AS 数量の合計 FROM TMP_AS受入検査品一覧"
lrsSum.Open(lsSqlSum, godDb, ADODB.CursorTypeEnum.adOpenDynamic,
ADODB.LockTypeEnum.adLockReadOnly)

If lrsSum.BOF = True Then
lblSuryo.Text = "数量: 0"
Else
lblSuryo.Text = "数量:" & Format(NzLng(lrsSum.Fields("数量の合計").Value), "#,##0")
End If

lrsSum.Close()

エラーが発生している部分は「lrsSum.Fields("数量の合計").Value」この部分になります。

自分の開発環境では特に問題なく動作するのですが、
インストールディスクを作成して、他のパソコンにインストールし、動作させるとこのエラーが発生します。

色々調べたのですが、よくわかりません。
誰かご存知の方がいらしたら教えて下さい。

[ツリー表示へ]
タイトルRe: アプリケーションのコンポーネントで…例外が
記事No10933
投稿日: 2012/10/03(Wed) 03:56
投稿者魔界の仮面弁士
アプリケーションが x86ビルドになっているかどうかを確認しておいてください。
また、実行環境に目標バージョンの ADO がインストールされているのかどうかも。

> インストールディスクを作成して、他のパソコンにインストールし、動作させるとこのエラーが発生します。

初めてみるエラーですが、ざっと検索してみると、国内外で
同様の事例が多数報告されているようですね。それも .NET 4 環境で。
http://www.vbfrance.com/forum/sujet-PROBLEME-EXECUTION-APPLIC-CREEE-SUR-W7-64B-AVEC_1546171.aspx
http://www.tech-archive.net/Archive/German/Entwicklung/microsoft.public.de.german.entwickler.dotnet.datenbank/2010-10/msg00000.html
http://stackoverflow.com/questions/5666265/adodbcould-not-load-type-adodb-fieldstointernalfieldsmarshaler-from-assembly

2010 以降での報告が多いという事は、COMタイプの埋め込み機能の障害かもしれません。
ソリューションエクスプローラから、参照設定\ADODB のプロパティで、
[相互運用型の埋め込み]を True から False に変更してみるとどうなりますか?
また、上記を False にした状態で、[ローカルコピー]を False から True にした場合は?


というのも、PIA 版の ADODB ライブラリの場合、Recordset や Field は
COM オブジェクトのまま公開されていますが、Fields コレクションは COM ではなく、
マネージオブジェクトにカプセル化された状態で公開されているためです。
そのため、相互運用型の埋め込みが期待動作していないのでは無いか…と想像しています。


> エラーが発生している部分は「lrsSum.Fields("数量の合計").Value」この部分になります。
「lrsSum.Collect("数量の合計")」にした場合はどうでしょうか?


---- 以下、本題とは関係のない話 ----

> lrsSum.Open(lsSqlSum, godDb, ADODB.CursorTypeEnum.adOpenDynamic, ADODB.LockTypeEnum.adLockReadOnly)
うん? JET Provider は、adOpenDynamic カーソルをサポートしていませんよ。
(そもそも、adOpenDynamic を採用するということ自体がかなり特殊な状況な気が…)

恐らく、.NET 化する以前のコードから間違っているものと推測します。
それでエラーになるわけではないので、間違いに気が付きにくいのですけれどね。

以下、カーソルタイプの違いについて:

adOpenForwarsOnly(前方スクロールタイプカーソル:規定値)
  ・カーソルの後戻り(MovePrevious)が出来ない
  ・プロバイダによって、MoveFirstができるものとできないものがある
  ・ほとんどのDBMSでは、ReadOnly指定のとき、このカーソルがもっともパフォーマンスが高い
adOpenKeyset(キーセットカーソル)
  ・カーソルの移動は自由
  ・他のユーザーによる更新、削除を検知する
  ・他で新しく追加されたレコードは検知しない
adOpenStatic(静的カーソル)
  ・カーソルの移動は自由
  ・他のユーザーによる更新、削除を検知する
  ・他のユーザーによる追加レコードを検知する
 ・adUseClient モードでは常にこれが採用される
adOpenDynamic(動的カーソル)
  ・カーソルの移動は自由
  ・ほかのユーザーによる追加、変更、削除を検知する
 ・完全にサポートしているプロバイダは少ない


その他、Format 関数を使っているところを見ても、VB.NET になり切れていない
レガシーなコードになっているのが非常に気にかかりますが…とりあえず、
VB.NET から ADODB を使う場合の参考資料として幾つかあげておきます。

http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1294960232
http://bbs.wankuma.com/index.cgi?mode=al2&namber=7478&KLOG=19
http://hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?mode=allread&no=7198&page=0
http://support.microsoft.com/kb/248287/ja
http://support.microsoft.com/kb/318559/ja

ADO だと ReleaseComObject の手間も考えねばなりませんので、
基本的には、ADO.NET への移行をお奨めしています。

とはいえ、編集可能なカーソルなどを使いたいなどの理由から、ADO.NET では
機能不足という事情が発生することはあるのですが…その場合はせめて、
DAO を採用した方がパフォーマンス面でも望ましいかと。

[ツリー表示へ]
タイトルRe^2: アプリケーションのコンポーネントで…例外が
記事No10934
投稿日: 2012/10/03(Wed) 10:24
投稿者タダシ
魔界の仮面弁士殿

色々と調査していただきありがとうございました。

自分はVB6.0しか使用したことが無く、最近VB2010を使用し始めたのでまだまだ
プログラムのレベルは3級ですし、仕事でも使用しないんで中々うまくいかないことが多々あります。

今回のエラーはlrsSum.Fields("数量の合計").ValueをlrsSum.Collect("数量の合計")に
したら解消されました。

大変助かりました。m(__)m

[ツリー表示へ]