2

そこで、ADO オブジェクトの使用方法を説明している次のMSDN リソース ページに移動しました。私の問題は、それを機能させることができないことです。

私がやろうとしているのは、CSV ファイルを開いて行ごとに読み取り、SQL INSERT ステートメントを作成して、Access 2010 の既存のテーブルにレコードを挿入することです。これを行う簡単な方法を見つけようとしましたが、これが私の唯一の選択肢のようです。付属のツールでこれを行っていますが、これまでのところ、運がありません.

ここでの主な問題は、一貫性のない見出しを持つ CSV ファイルがあることです。5 つのファイルを同じテーブルにインポートしたいのですが、各ファイルは、どのフィールドにデータが含まれているかによって異なります。データが含まれていないフィールドは、抽出中に無視されました。これが、DoCmd.TransferText のようなものを使用できない理由です。

そこで、テキスト ファイルを開き、最初の行のヘッダーを読み取り、その特定のファイルの構成に応じて SQL INSERT ステートメントを作成するスクリプトを作成する必要があります。

問題へのアプローチ方法についてはうまく対処していると感じていますが、何を試しても、ADO を使用して動作させることができないようです。

どうすればこれを達成できるか誰か説明できますか?私のこだわりは、Access DB が ADO​​ 経由で CSV ファイルから情報を受け取るようにすることです。

4

2 に答える 2

3

CSV ファイルを 1 行ずつ読み取ってから各行で何かを行うのではなく、ファイルを ADO レコードセットとして開く必要があると思います。Access 宛先テーブルの DAO レコードセットを開きます。

その後、ADO レコードセットの各行のフィールドを反復処理し、それらの値を DAO レコードセットの新しい行に追加できます。宛先テーブルに、CSV フィールドと同じ名前で互換性のあるデータ型のフィールドが含まれている限り、これはかなりスムーズです。

Public Sub Addikt()
#If ProjectStatus = "DEV" Then
    ' needs reference for Microsoft ActiveX Data Objects
    Dim cn As ADODB.Connection
    Dim fld As ADODB.Field
    Dim rs As ADODB.Recordset
    Set cn = New ADODB.Connection
    Set rs = New ADODB.Recordset
#Else ' assume PROD
    Const adCmdText As Long = 1
    Const adLockReadOnly As Long = 1
    Const adOpenForwardOnly As Long = 0
    Dim cn As Object
    Dim fld As Object
    Dim rs As Object
    Set cn = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")
#End If
    Const cstrDestination As String = "tblMaster"
    Const cstrFile As String = "temp.csv"
    Const cstrFolder As String = "C:\share\Access"
    Dim db As DAO.Database
    Dim rsDao As DAO.Recordset
    Dim strConnectionString As String
    Dim strName As String
    Dim strSelect As String

    strConnectionString = "Provider=" & _
        CurrentProject.Connection.Provider & _
        ";Data Source=" & cstrFolder & Chr(92) & _
        ";Extended Properties='text;HDR=YES;FMT=Delimited'"
    'Debug.Print strConnectionString
    cn.Open strConnectionString

    strSelect = "SELECT * FROM " & cstrFile
    rs.Open strSelect, cn, adOpenForwardOnly, _
        adLockReadOnly, adCmdText

    Set db = CurrentDb
    Set rsDao = db.OpenRecordset(cstrDestination, _
        dbOpenTable, dbAppendOnly + dbFailOnError)

    Do While Not rs.EOF
        rsDao.AddNew
        For Each fld In rs.Fields
            strName = fld.Name
            rsDao.Fields(strName) = rs.Fields(strName).value
        Next fld
        rsDao.Update
        rs.MoveNext
    Loop

    rsDao.Close
    Set rsDao = Nothing
    Set db = Nothing
    rs.Close
    Set rs = Nothing
    cn.Close
    Set cn = Nothing
End Sub

これは、その手順を保存したモジュールの宣言セクションです。

Option Compare Database
Option Explicit
#Const ProjectStatus = "DEV" '"DEV" or "PROD"

これらの定数の値を変更して、システムでテストします。

Const cstrDestination As String = "tblMaster"
Const cstrFile As String = "temp.csv"
Const cstrFolder As String = "C:\share\Access"

フォルダー名には末尾のバックスラッシュが含まれていないことに注意してください。

ファイル名を定数として残すのではなく、パラメーターとして渡すようにその手順を調整する必要があります。また、CSV ファイルが複数のディレクトリに保存されている場合は、フォルダー名もパラメーターとして渡す必要があります。

うまくいけば、1 つのファイルに対してそれを行う方法を示すだけで十分であり、ここからすべての CSV ファイルを処理することができます。エラー処理の追加も検討してください。

于 2012-05-09T05:47:00.443 に答える