0

私の以前のタイトルはそこで少し混乱を引き起こしました...最近、VBAを使用してExcelとAccessをブリッジしているときにこの問題に遭遇しました。

Access データベースにインポートする必要があるテーブルを含むスプレッドシートがあります。この表は、次のような一般的なものです。

EmployeeNumber  Unused_Field2   Unused_Field3
1                    @@@              @@@
2                    @@@              @@@
3                    @@@              @@@

Access の一意のキーは EmployeeNumber に設定されています。

Excel の VBA コードは次のようになります。

Sub test()
    Dim con As ADODB.Connection
    Dim rst As ADODB.Recordset

    strcon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\temp\mydb.mdb;"
    strsql = "SELECT * FROM Table1"

    Set con = New Connection
    Set rst = New Recordset

    con.Open strcon
    rst.Open strsql, strcon, adOpenStatic, adLockOptimistic

    For i = 0 To n
        On Error GoTo Errhdl
        rst.AddNew Array("Field1", "Field2", "Field3"), Array(Range("A" & i), Range("B" & i), Range("C" & i))
        On Error GoTo 0
    Next

    Exit Sub

Errhdl:

    Debug.Print "Record" & i & "caused an error"
    Resume Next

End Sub

残念ながら、データは高品質ではないため、値が重複していて、常にキー違反が発生することがよくあります。Resume Next はエラーをクリアして、別の「AddNew」を実行できるようにしましたが、そうではありませんでした。1 つのキー違反の後に続くすべてのエントリは、同じエラーを返します。

だから私の質問は次のとおりです。

  1. レコードセットに関連付けられたエラーをクリアする方法はありますか? (レコードについては、「エラー コレクション」を取得しようとして、メソッド Errors.Clear を使用しました。それではうまくいきませんでした。エラー コレクションは、ADO オブジェクトに固有のプロパティです - MSDN エラー コレクション)
  2. これは、レコードセットを閉じて再度開かずに実行できますか?

さらに説明が必要な場合はお知らせください。

4

2 に答える 2

0

したがって、 Recordset.AddNew が発生してエラーが発生した場合の解決策を見つけました。トリックは CancelUpdate を使用することです - MSDN

Status プロパティを使用して、操作が成功したかどうかを確認することもできます。

サンプル コードは次のようになります。

Sub test()
    Dim con As ADODB.Connection
    Dim rst As ADODB.Recordset

    strcon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\temp\mydb.mdb;"
    strsql = "SELECT * FROM Table1"

    Set con = New Connection
    Set rst = New Recordset

    con.Open strcon
    rst.Open strsql, strcon, adOpenStatic, adLockOptimistic

    For i = 0 To n
        On Error GoTo Errhdl
        rst.AddNew Array("Field1", "Field2", "Field3"), Array(Range("A" & i), Range("B" & i), Range("C" & i))
        On Error GoTo 0
    Next

    Exit Sub

Errhdl:

    Debug.Print "Record" & i & "caused an error"
    If rst.Status <> 0 Then
        rst.CancelUpdate
    End If
    Resume Next

End Sub
于 2013-07-31T21:21:47.180 に答える
0

エラー処理は使用しませんが (ADO エラーの処理は面倒です)、検索を使用して、挿入を実行する前に、キーがまだ存在しないことを毎回確認します。キーがインデックス付きフィールドである場合(説明が示唆するように)Seek、大規模なデータセットに対してどちらがより効率的であるかを検討できます。(ただし、Seekクライアント カーソルでは機能しません - adUseClient。)

以下は、手順の概要を示したコードの断片です。

If Not .EOF Then
   .MoveFirst
   .Find "TPItemNbr='" & m_TPItemNbr & "'", , adSearchForward
End If
If .EOF Then
   .AddNew
   !TPItemVendorID = m_TPItemVendorID
   !TPItemNbr = m_TPItemNbr
   !TPItemEUOM = m_TPItemEUOM
   !TPItemUOMFactor = m_TPItemUOMFactor
   !TPItemPUOM = m_TPItemPUOM
   !TPItemDescription = m_TPItemDescription
   !TPItemUnitCost = m_TPItemUnitCost
   !TPItemUnitLabor = m_TPItemUnitLabor
   .Update

つまり、ループ内で毎回検索を実行します。EOF (ファイルの終わり) が true の場合、キーはまだテーブルにないため、挿入を実行できます。

複合キーに関する追加情報に応じて追加されました。Commandオブジェクトを作成して使用しますExecute。はい、文字列を作成する必要がありますが、キー違反のエラーをトラップして無視できます。

代替案は

  • 別の SQL ステートメントを実行して、重複リストのレコードセットを取得します
  • これをループして、値を配列に格納します
  • AddNewアレイをチェックするたびに実行します

これは、特に配列を検索するという点で、私には面倒に思えます。

  • コメントにリンクされている複数検索方法を追求します。
于 2013-07-26T19:31:52.697 に答える