tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルADOでの実行時のエラー
記事No7198
投稿日: 2008/03/17(Mon) 10:24
投稿者Yamada
以下のコードでのエラーが解消されないのですが、どなたかアドバイスを頂けないでしょうか、
よろしくお願いします

環境
WindowsXP
VB2005
NET Framework 2
Access2000

参照設定
Microsoft ActiveX Data Objects 2.8 Library
Microsoft ADO Ext 2.8 for DDL and Security
Microsoft DAO 3.6 Object Library

インポートされた名前空間
ADODB
ADOX
DAO

Sub syori()
        Dim dbs1 As New ADODB.Connection
        Dim dbs2 As New ADODB.Connection

        Dim workt1 As New ADODB.Recordset
        Dim workt2 As New ADODB.Recordset

        Dim wsql As String

        ' 接続を開く
        dbs1.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\DATA1.MDB"
        dbs1.Open()

        wsql = "SELECT * FROM data1;"
        workt1.Open(wsql, dbs1, CursorTypeEnum.adOpenDynamic, ADODB.LockTypeEnum.adLockOptimistic)

        ' 接続を開く
        dbs2.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\DATA2.MDB"
        dbs2.Open()

        wsql = "SELECT * FROM data2;"
        workt2.Open(wsql, dbs2, CursorTypeEnum.adOpenDynamic, ADODB.LockTypeEnum.adLockOptimistic)

        Do Until workt1.EOF
            workt2.AddNew()

◆◆◆ここでエラーが発生◆◆◆
'これだと cnt=0 の時から『要求された名前、または序数に対応する項目がコレクションに見つかりません』と実行時エラーが出てしまう。
            For cnt = 0 To 9
                workt2.Fields(cnt).Value = workt1.Fields(cnt).Value
            Next

'これだと問題なし。
            workt2.Fields(0).Value = workt1.Fields(0).Value
            workt2.Fields(1).Value = workt1.Fields(1).Value
            workt2.Fields(2).Value = workt1.Fields(2).Value
            workt2.Fields(3).Value = workt1.Fields(3).Value
            workt2.Fields(4).Value = workt1.Fields(4).Value
            workt2.Fields(5).Value = workt1.Fields(5).Value
            workt2.Fields(6).Value = workt1.Fields(6).Value
            workt2.Fields(7).Value = workt1.Fields(7).Value
            workt2.Fields(8).Value = workt1.Fields(8).Value
            workt2.Fields(9).Value = workt1.Fields(9).Value
            workt2.Update()

            workt1.MoveNext()
        Loop

        workt1.Close()
        workt2.Close()

        dbs1.Close()
        dbs2.Close()
End Sub

[ツリー表示へ]
タイトルRe: ADOでの実行時のエラー
記事No7200
投稿日: 2008/03/17(Mon) 11:33
投稿者魔界の仮面弁士
…そもそも何故、adOpenDynamic を使用されているのでしょう?

そもそも mdb では、動的カーソルをサポートしていませんので、
自動的に、別のカーソルモードに補正されてしまうはずです。
(Open 後に、workt1.CursorType の値を確認してみましょう)

もしサポートしていたとしても、扱いの難しいカーソルタイプですから、
十分に理解されていない限りは、別のカーソルを選択される事をお薦めします。
(キーセットカーソルとか、前方移動専用カーソルとか)


> 'これだと cnt=0 の時から『要求された名前、または序数に対応する項目がコレクションに見つかりません』と実行時エラーが出てしまう。
> For cnt = 0 To 9
変数 cnt が、Long 型(System.Int64)になっていませんか?
ADODB.Fields::Item の引数には、64bit 整数型(VT_I8)を指定できません。


> インポートされた名前空間
> ADODB
> ADOX
> DAO
DAO と ADO の混在ですか……しかも .NET で。


> 'これだと問題なし。
とはいえ、COM オブジェクトの解放漏れという点において、
別の意味で問題がありますけれどね。


> VB2005
> NET Framework 2
.NET からの ADODB の利用は避けましょう。
ADO.NET を使う事を 強く お薦めします。


何らかの事情で、ADODB を使わなければいけないのであれば、
以下の点に注意しておいてください。

 ・msado15.dll (msado2*.tlb) を参照設定すると自動生成される「Interop.ADODB.DLL」を
  使う事は避け、Program Files\Microsoft.NET\Primary Interop Assemblies もしくは
  グローバル アセンブリ キャッシュにある「ADODB.DLL」を参照設定して使うようにする。
 http://support.microsoft.com/kb/318559/ja

 ・データの取得後は、Recordset, Connection, Command をはじめとする COM オブジェクトを、
  Marshal.ReleaseComObject で解放するようにする。
 http://support.microsoft.com/kb/321415/ja

 ・Recordset からデータを取得する際は、MoveNext で列挙する代わりに、
  OleDbDataAdapter.Fill によって、DataSet から得ることを検討する。
 ・データの書き込みが必要な場合は、RS.Fields(n).Value への書き込みを行う代わりに、
  RS.Collect(n) への書き込みを使うようにする。

[ツリー表示へ]
タイトルRe^2: ADOでの実行時のエラー
記事No7202
投稿日: 2008/03/17(Mon) 13:03
投稿者Yamada
魔界の仮面弁士さま、ありがとうございます
教えていただいた注意点を確認してみます

.NETでのADO、DAO混在は工期も短く既存のVB6プロジェクトからの移行なので無理みたいです(プロジェクトリーダーの意向です。)

あとADO.NETでのDataReader、DataAdapter、DataSet、DataView、DataTableなどを使い分けや非接続型であることも関係しているそうです。

ありがとうございました。

[ツリー表示へ]