- ベストアンサー
Access VBA CSVファイルのインポートエラーと解決方法
- AccessのVBAを使用してCSVファイル(タブ区切り)をインポートしようとすると、エラーが発生します。インポート先のテーブルに指定したフィールドが存在しないというエラーメッセージが表示されます。このエラーの原因は、CSVファイルのフィールドが1つのフィールドとして認識されていることです。タブ区切りかカンマ区切りかを指定するパラメータは存在するのでしょうか。
- ユーザーが作成したCSVファイルのフィールドの並びが異なる場合、事前にインポート定義を作成することができない状況です。そのため、この問題を解決する方法を教えてください。
- また、ウィザードを使用して手動でCSVファイルをインポートする場合には、問題なくインポートできることが確認されています。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
csvがタブ切りなのですね。それならば一旦ファイルを変換して 変換したファイルをインポートするようになりますね。 手動でするか、VBAで、変換し、ファイルをインポートするかの 差はありますが。 >インポートするCSVファイルはユーザーにより見出し(フィールド)の >並びが異なる場合がある為、インポート定義を予め作っておくことが >できない状況です。 これに目がいってとんちんかんな回答しました。カンマ切りならば フィールドの順序が違っていても、 DoCmd.TransferText acImportDelim, , "temp", path, True でOKですね。 失礼しました。
その他の回答 (4)
- piroin654
- ベストアンサー率75% (692/917)
No3です。訂正。 >'Accessファイルへの接続(現在のAccessファイル) >strPath = strPath = CurrentProject.FullName >cn2.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strPath のところで、 >strPath = strPath = CurrentProject.FullName を、 strPath = CurrentProject.FullName にしてください。余計なものがくっついていました。
- piroin654
- ベストアンサー率75% (692/917)
処理時間は少しかかりますが。 べたな方法です。トランザクション処理を省いていますが、 たぶん大丈夫でしょう。 設定は、そちらの環境に合わせてください。 Dim cn1 As New ADODB.Connection Dim cn2 As New ADODB.Connection Dim rs1 As New ADODB.Recordset Dim rs2 As New ADODB.Recordset Dim strPath As String Dim strSQL As String 'CSVへの接続 cn1.Provider = "Microsoft.Jet.OLEDB.4.0" cn1.Properties("Extended Properties") = "Text;HDR=YES" cn1.ConnectionString = CurrentProject.Path cn1.Open 'Accessファイルへの接続(現在のAccessファイル) strPath = strPath = CurrentProject.FullName cn2.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strPath 'レコードセットへの接続 strSQL = "SELECT * FROM [A.csv]" rs1.Open strSQL, cn1, adOpenStatic, adLockReadOnly 'テーブル接続 rs2.Open "temp", cn2, adOpenDynamic, adLockOptimistic 'テーブルへの書き込み Do Until rs1.EOF rs2.AddNew rs2!フィールド1 = rs1!フィールド1 rs2!フィールド2 = rs1!フィールド2 rs2!フィールド3 = rs1!フィールド3 rs2.Update rs1.MoveNext Loop rs1.Close: Set rs1 = Nothing rs2.Close: Set rs2 = Nothing cn1.Close: Set cn1 = Nothing cn2.Close: Set cn2 = Nothing
お礼
Proin654さま いつもご回答ありがとうございます。 結局、インポートする対象のCSVファイルをタブ区切りから カンマ区切りに変換するようにし、そのファイルをインポートすることで エラーが解消されました。 ありがとうございました。
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
>予め、フィールド名とそれぞれが何列目にあるかを何らかの >方法で取得し、後で自動的に付けられたフィールド名を本来の >フィールド名に修正する処理が必要になります。。 VBAで色々書かないと無理でしょう。 VBAで、以下のようにプログラミングして下さい。 1.1行目のみを文字列として取り込む Dim buf Open path For Input As #1 Line Input #1, buf Close #1 2.取り込んだ文字列を、フィールド名として分割する 上記のbufの中身を色々と処理する。 読み込んだbufを元に「"フィールド名1 TEXT,フィールド名2 TEXT,フィールド名3 TEXT"」みたいな文字列を作ります(この例では、フィールド3つで、全部テキスト型) 3.分割したフィールド名を元に、SQL文を組み立てて「テーブル作成クエリ」を作る dim SQLStr as String SQLStr = "CREATE TABLE temp (" & bufを加工した物 & ");" 4.テーブル作成クエリを実行してテーブルを作る(予め同名のテーブルを削除しておく) '存在しないテーブルを削除しようとしてもエラーにしない On Error Resume Next '既存のtempテーブルがあれば削除 DoCmd.DeleteObject acTable, "temp" 'エラー処理を取り消す On Error Goto 0 'テーブル作成クエリを実行する RunSQL SQLStr 5.HasFieldNames:=trueでDoCmd.TransferTextして、作成したテーブルにインポートする '1行目をフィールド名としてpathファイルをtempテーブルにインポート DoCmd.TransferText acImportDelim, , "temp", path, True
お礼
度々のご回答ありがとうございます。 あれから結局、インポートする対象のCSVファイルをタブ区切りから カンマ区切りに変換するようにし、そのファイルをインポートすることで エラーが解消されました。 ありがとうございました。
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
>インポートするCSVファイルはユーザーにより見出し(フィールド)の並びが異なる場合がある為、インポート定義を予め作っておくことができない状況です。 そういう状況を一切無視して、取り合えずのインポート定義を作っておいて、どんな中身になってようが、構わずに「取り合えずのインポート定義を無理矢理に適用して、ゴリ押しする」が正解。 もちろん、インポート定義は「1行目を見出しにする」にはしないでおいて「1行目も無理矢理にデータとして取り込む」のがキモ。そして、後で1行目を捨てれば良い。 必ず数値が来るフィールドがあるなら、インポート定義で、そのフィールドを「数値」にしておくと良い。そうすると、1行目を無理矢理データとして取り込んだ時に、フィールドの型が食い違って、見出し行が自動的に捨てられるようになるから、自分で後から1行目を捨てる処理も不要になる。
お礼
chie65535様 早速のご回答ありがとうございます。 >そして、後で1行目を捨てれば良い。 ということですが、単純にインポートするだけならよいのでしょうが 実際にはインポートしたデータを使って集計を行なったりします。 なので、フィールド名は必要です。 予め、フィールド名とそれぞれが何列目にあるかを何らかの 方法で取得し、後で自動的に付けられたフィールド名を本来の フィールド名に修正する処理が必要になります。。 その辺を踏まえて何かよい方法はございませんでしょうか。
お礼
いえいえとんでもないです。 コチラも色々試しながらなので、質問自体もフワッとした感じになってしまい すみません。 タブ区切りだとNG、カンマ区切りならOK・・・なんてことがあるんですね。 勉強になりました。