• 締切済み

CSVファイル読み込みでズレがおきる

お世話になります。 Windows XP SP3、Access2003 で CSVファイルをインポートする処理をつくっています。 読み込むCSVファイルが大きく、必要ないフィールドが多いのですが、 下記のようにLine Input で全部読み込んで Splitでカンマ区切りでバラしてvarData(Variant型)にいれて レコードセット(インポート先の既存テーブル)に入れる時に、 必要に応じてデータ型を変更して フィールド指定ししていれるようにしています。 ところが、CSVファイルの中のデータで数件ほど ちゃんと読み込めないものがあり、 レコードセットにいれるときにエラーでとまってしまいます。 調べてみると、フィールドで取得した値がずれており、 前の方の複数のフィールドでNull値があった場合?に ずれ込むことがあるようです。 どうしたらこの現象はなおせるのか教えてください。 それとも・・・ このようにフィールド指定してレコードセットに入れ込むよりも 一度CSVファイルの全レコードを他のテーブルにインポートして、 そこからインポート先の既存の本テーブルにいれたほうがいいのでしょうか? よろしくお願いいたします。 Open ---- For Input As---- Line Input #lngFileNum, strData インポート先のテーブルをレコードセットで開く DAO、トランザクション使用 Do Until EOF(lngFileNum) Line Input #lngFileNum, strData 'データを配列へ varData = Split(strData, ",") With rs .AddNew !番号 = CLng(varData(0)) !名称 = varData(1) !受付日 = DateValue(varData(8)) !種別 = varData(10), "" !登録番号 = CLng(varData(11))           (以下略)

みんなの回答

  • piroin654
  • ベストアンサー率75% (692/917)
回答No.5

No4です。 No4の続きとして。 フィールド名は質問の通りの抜き出し番号になっていませんが、 リンクしたCSVをT1、追加先テーブルをT2として、以下のようなクエリ で追加。 INSERT INTO T2 ( 番号, 名称, 受付日, 種別, 登録番号 ) SELECT CLng([フィールド1]) AS F1, T1.フィールド2, DateValue([フィールド3]) AS F3, T1.フィールド4, CLng([フィールド5]) AS F5 FROM T1; あるいは、 >前の方の複数のフィールドでNull値があった場合 この意味が分かりづらいのですが、もしかしたら、 インポートしようとしているフィールドにNullデータ が存在する、という意味ならば、 INSERT INTO T2 ( 番号, 名称, 受付日, 種別, 登録番号 ) SELECT IIf(IsNull([フィールド1]),Null,CLng([フィールド1])) AS F1, IIf(IsNull([フィールド2]),Null,[フィールド2]) AS F2, IIf(IsNull([フィールド3]),Null,DateValue([フィールド3])) AS F3, IIf(IsNull([フィールド4]),Null,[フィールド4]) AS F4, CLng(Nz([フィールド5])) AS F5 FROM T1; これで対応できるものかな、というところですかね。

  • piroin654
  • ベストアンサー率75% (692/917)
回答No.4

CSVをリンクテーブルとしてはどうですか。 「外部データの取り込み」から「テーブルのリンク」 を選択し、「ファイルの種類」を「テキストファイル」 とし、ファイルのあるフォルダを選択し、当該ファイルを クリックするとウィザードが表示されます。 そこで、設定を選択し、フィールド区切り記号、 文字列の引用符を設定し、フィールドの情報で、 必要のないフィールドにチェックを入れてスキップ を設定し、OKとして最後まで進み、リンクを設定します。 あとは、普通のテーブルとして別テーブルに 追加クエリなりでデータを移し変えて加工するなり、 そのまま参照テーブルとして使用することも できます。

  • layy
  • ベストアンサー率23% (292/1222)
回答No.3

前述のリンクです。 http://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_110_030.html >前の方の複数のフィールドでNull値があった場合?に >ずれ込むことがあるようです。 原因がはっきりしていないので、はっきりさせること。 インポート機能は、あくまでも標準機能。 ちょっとイレギュラー、不正データがあると対応できないものも多いです。 カンマ区切りがどうしてもダメなら 1行単位で読み込むとか一時的にスペース等にして代替処理、 別のアプローチも検討です。

  • nicotinism
  • ベストアンサー率70% (1019/1452)
回答No.2

今の方向で進めるなら・・・ Ubound(varData) で確認して×ならレコードセットに入れないで エラー行として別のテキストファイルに書き込んでから 次の行に進むとか。 varDataの要素を一個ずつチェックするのは面倒ですねぇ。 ん~後は何だろ。 別案を検討されていますが、こちらでも テキストを Access にインポートした際に 区切り位置がずれる場合の対処方法 http://support.microsoft.com/default.aspx?scid=kb;ja;882221 などがありますので、『前門の狼、後門の虎』かもしれない。 試してみる価値は大いにありそうですけどね。 インポートさえ出来てしまえば、あとは焼くなと煮るなとこっちの勝手気まま (^^ゞ 具体的に何処のステップで止まってしまうのか。 (エラールーチンはコメントアウトして)エラー番号。 エラーになる実際のstrDataの内容とかが分かれば識者から回答があるかもしれない。

  • layy
  • ベストアンサー率23% (292/1222)
回答No.1

参考 エクセルでお仕事 のサイト、VBA応用を参考 ズレるなら それを使わない手でやる か それでやってもいいように仕向ける 怪しいと思われる,,を,"",に変えても同じですか。

関連するQ&A

  • 【Access2003】VBAでタブ区切りテキストファイル読込

    はじめまして。 【Access2003】を使用し、タブ区切りのテキストファイル読込をVBAで行っています。 カンマ区切りはわかるのですが、タブ区切りの方法がわからないので教えていただけませんか? TransferTextを使用したかったのですが、読み込んだデータ1件1件に対して必須と桁数確認を行い、エラーがあった場合はテキストファイルにそのデータ1行を書き込み、エラーがない場合は1行テーブルに書き込みというように処理を分けたいからなのです。 とりあえず今のところカンマ区切りのCSVファイルを読み込むというようにしており、読み込む前にタブ区切りテキストファイルをカンマ区切りCSVファイルに変換する処理を入れようと思っています。 しかしタブ区切りテキストファイルをそのまま読むことができれば一番いいのですが。 ソースは以下の通りです。 '出力元CSVファイルを開く lngFileNum = FreeFile() 'データ読込 Open strJsnFol & "\\" & strIriInf For Input As #lngFileNum 'CSVファイルの最初の行を読み込む 'CSVファイルより1件分を読み込み Line Input #lngFileNum, strData 'カンマで区切って配列に代入 varData = Split(strData, ",", , vbTextCompare) 'データ種別のチェック If varData(0) <> "XXX" Then MsgBox "ファイルエラーです。", vbInformation + vbOKOnly intErrFlg = 1 Exit Sub End If 'タイムスタンプチェック strSQL = " SELECT CREATE_TIME FROM TB WHERE    CREATE_TIME = '" & varData(1) & "'" 'SQLを実行 If DBAC.ExecSelect(strSQL) = 0 Then '同じ処理時間のデータがなければ、タイムスタンプを取得 strCreateTime = varData(1) Else MsgBox "すでに処理済です。", vbInformation + vbOKOnly intErrFlg = 1 Exit Sub End If 'テーブルを開く Set dbs = CurrentDb Set rst = dbs.OpenRecordset("IF_TB") 'CSVファイルの全レコードを読み込むループ Do Until EOF(lngFileNum) 'CSVファイルより1件分を読み込み Line Input #lngFileNum, strData 'カンマで区切って配列に代入 varData = Split(strData, ",", , vbTextCompare) 'データチェック If varData(0) = "" Or Len(varData(0)) > 12 Then intChkErr = 1 End If If varData(1) = "" Or Len(varData(1)) > 12 Then intChkErr = 1 End If If Len(varData(2)) > 1 Then intChkErr = 1 End If 'エラーがあればエラーファイルに書き込み If intChkErr <> 0 Then strFileName = strJsnFol & "\\" & "ERR.csv" lngFileNum2 = FreeFile() Open strFileName For Append As #lngFileNum2 End If Print #lngFileNum2, "ERR1," & strData Close #lngFileNum2 Else '各フィールドデータをテーブルに追加 With rst .AddNew !K_NO = varData(0) !S_NO = varData(1) !CD = varData(2) !CREATE_TIME = strCreateTime .Update End With End If intChkErr = 0 Loop rst.Close Close #lngFileNum Exit Sub 何かいい方法があれば教えていただけませんか? よろしくお願いいたします。

  • AccessでCSVをインポートしたい(VBA)

    お世話になります。AccessVBA暦2週間の初心者です。 AccessでCSVをインポートできたらいいなと思い ↓下のサイトにあるVBAサンプルを参考にして以下のようにプログラミングをしました。 http://memo.bz/access/advance/csvinpsam Public Function SplitTest() On Error GoTo myError Dim dbs As Database Dim rst As Recordset Dim varData As Variant Dim lngFileNum As Long Dim strData As String Dim xSQL As String FileName = TestGetFileName '入力元CSVファイルを開く lngFileNum = FreeFile() Open FileName For Input As #lngFileNum 'テーブルを開く Set dbs = CurrentDb Set rst = dbs.OpenRecordset("Data") 'CSVファイルの全レコードを読み込むループ Do Until EOF(lngFileNum) 'CSVファイルより1件分を読み込み Line Input #lngFileNum, strData 'カンマで区切って配列に代入 varData = Split(strData, ",", , vbTextCompare) '各フィールドデータをテーブルに追加 With rst .AddNew ![Code1] = varData(0) ![Code2] = varData(1) ![TS] = varData(2) ![PM] = varData(3) ![金額] = varData(4) ![摘要] = varData(5) ![メモ] = varData(6) .Update End With Loop rst.Close Close #lngFileNum MsgBox "データの取り込みが終了しました" Exit Function myError: MsgBox "ファイル名を指定してください" End Function 'CSVファイル選択 Function TestGetFileName() 'ファイル選択 Const ENABLE_WIZHOOK = 51488399 Const DISABLE_WIZHOOK = 0 Dim strFile As String Dim intResult As Integer WizHook.Key = ENABLE_WIZHOOK ' WizHook 有効化 intResult = WizHook.GetFileName( _ 0, "", "", "", strFile, "", _ "すべてのファイル (*.*)|*.*", _ 0, 0, 0, True _ ) WizHook.Key = DISABLE_WIZHOOK ' WizHook 無効化 TestGetFileName = strFile End Function ダイアログは普通に開けるのですがインポートが出来ず「ファイル名を指定してください」 というメッセージボックスが出ます。 弄っている部分は ![フィールド1] = varData(0)を ![Code1] = varData(0)にしているぐらいです。 何が悪いのか皆目見当がつきません。 こんな初心者でございますがご教授のほどよろしくお願いします。 (ヒントでも構いません) 説明不足等ございましたらご指摘のほどよろしくお願いします。

  • CSVファイルの読み込み

    お世話になります。 VBAでCSVファイルを読み込んで処理をしたいのですが、 たとえば下記のようなCSVファイルの場合 2つめの項目が金額セットされており、あらかじめ通貨編集(カンマ編集) がされていて 金額を1つの項目として読み込む事が出来ません。 金額は""でくくってあるのですが、 カンマ区切りのデータと""でくくってあるデータを うまく区別して3つの項目をそれぞれ抽出する事は可能でしょうか? -----以下CSVの内容------ 日付,金額,データ 2007/03/09,"1,200",TEST1 2007/03/09,"12,200",TEST2 2007/03/09,"76,00",TEST3 2007/03/09,"4,5600",TEST4 --------------------------- ちなみに現在はこのようにカンマ区切り指定でデータを抽出してるので うまく出来ません。   'FileNameにはオープンするファイル名がセットされています   Open FileName For Input As   'textlineに1行を読み込む   Line Input #ch1, textline   csvline() = Split(textline, ",") VBAがまだ不慣れな為質問やサンプルが分かりずらいと思いますが よろしくお願いします。

  • CSVファイルインポート時の制限について

    AccessVBAでcsvファイルをインポートするマクロを作っています。 現在、インポート定義を利用して、データ型を指定したインポートができているのですが、1点だけ問題があり、質問します。 インポートするcsvファイルのA列にIDが入力されています。 そのA列の末尾に、ID(数値型)ではない「<b>32</b><br />」という値が入っています。 Accessのテーブルでは、このIDのフィールドは数値型で管理している為、この1レコードだけ エラーとなり、エラーテーブルが作られ、また、インポート先のテーブルには空のレコードができてしまいます。 この末尾の行については、IDではない「<b>32</b><br />」以外は何もデータが入っていない為、 インポートする必要がありません。 もし可能であれば、csvファイルのA列(Accessテーブルでは数値型のIDというフィールド)が数値ではない場合、 その行のインポートをスキップするような処理がVBAで作成できるとよいのですが、可能でしたら教えてください。

  • csvファイルのインポート

    Accessでcsvファイルをインポートさせようとしています。しかし、「F1フィールドがありません」のようなエラー表示が出て、できません。私の予想では、テーブルの型とcsvファイルの型が違うのではないかと思っています。テーブルには、数値型、テキスト型、日付/データ型があります。 保存したcsvファイルをExcelで開くと日付がApr-01や、2001/06/26となったりしていました。どこかで型変換のようなことをするのでしょうか?csvのことはよく分かりません。どうか、よろしくお願いします。

  • BCPでCSVファイルをインポート(MSDE)

    EXCELで作成したCSVデータをMSDEへインポートする方法を勉強しています。 インポートにはBCPを使用しています。 簡単なテーブルへのインポートはできたのですが、次の方法がわかりません。 1. あるフィールドにはMSDEのNEWID()関数でユニークデータをセット 2. 他のフィ-ルドにはCSVから読み込んだデータをセット 1と2を同時に行うことは、BCPで可能なのでしょうか? よろしくお願いします。

  • VBAでインポート元ファイルの読込可否を判別するには?

    AccessVBAであるCSVファイルをインポートして処理を行っています。 インポート元であるCSVファイルは2分毎に更新されており、データ量が多い関係上書込みに十数秒掛かっています。 この間にAccessからCSVファイルのインポートを掛けると 「ほかのユーザーが排他的に開いているか、データを読み取る権限がありません。」 と出てしまいます。 このことから、 1.ファイル読込の可否を判別し、可能ならテーブルのレコードを削除しインポートを行う 2.不可ならテーブルにある既存のデータを用い集計を行う という一文をIf関数を用いた形で追加したいのですが、インポート元のファイルの読込可否を判別する方法はありますでしょうか? 識者の方アドバイスの程よろしくお願い致します。

  • Access VBA CSVファイルのインポート

    お世話になります。 VBAにてCSVファイル(タブ区切り)をインポートするのに、 以下のように記述してますが、エラーとなります。 なお、インポート先のtempテーブルはインポートするCSVファイルの フィールドと同じ並びで予め作成したものです。 DoCmd.TransferText acImportDelim, , "temp", path, True 「実行時エラー2391 貼り付け先のtempテーブルには、'フィールド1_ フィールド2_フィールド3'フィールドがありません。」 このエラーを見る限り、フィールド1~3が一つのフィールドとして 認識されているように見受けられます。 タブ区切りなのか、カンマ区切りなのかを指定するようなパラメタは あるのでしょうか。 なお、当該CSVファイルをウィザードより手動でインポートする分には 問題無くインポート出来ます。 ************** インポートするCSVファイルはユーザーにより見出し(フィールド)の 並びが異なる場合がある為、インポート定義を予め作っておくことが できない状況です。 ご教授の程、宜しくお願い致します。

  • c#で(",")区切りのcsvファイルから読み込みを行うには?

    駆け出しの初心者です。 以前c言語を少々勉強していてcsvファイルの読み込み、書き出しを練習していたのですが、最近c#を使うようになり、その便利さに圧倒されております。 今回c#で読み込みたいcsvファイルは以下のようになっております "abc","123","あいうえお" ただのカンマ区切りであれば読み込みは簡単ですが、 上記のようにダブルクオーテーションでそれぞれの文字列が囲まれている場合に文字列だけを読み込み、配列に代入していくのに何かスムーズな方法はありませんでしょうか? ちなみに現在単純にカンマ区切りのcsvファイルを読み込むコードを 書いた所ですので、載せておきます これをいじってスムーズにいければうれしいのですが、いかがでしょうか? private void LoadData() { string path = "Data.csv"; string delimStr = ",";//区切り文字 char[] delimiter = delimStr.ToCharArray(); string[] strData;//分解後の文字用変数 string strLine;//1行分のデータ Boolean fileExists = System.IO.File.Exists(path); if (fileExists) { System.IO.StreamReader sr = new System.IO.StreamReader( path, System.Text.Encoding.Default); while (sr.Peek() >= 0) { strLine = sr.ReadLine(); strData = strLine.Split(delimiter); DataSet.DataTable.AddDataTableRow( DateTime.Parse(strData[0]), strData[1],    strData[2], int.Parse(strData[3]), strData[4]); } sr.Close(); } } いつも丁寧な回答で協力してくれる皆様には心から感謝しております。 どうぞよろしくお願いします。

  • Access2000 csvファイルのインポート

    Access2000のVBAを使用してcsvファイルを用意されたテーブルにインポートをしたいのですが、 やっかいな条件があります。 ある決められたフォルダに複数のファイルが存在している、そこから全てのCSVファイルを読み込み、3フィールド目(1行目はタイトル行)の値が「"3"」のものだけインポートする。 あるフィールドには、255文字以上のフィールド(改行文字あり)があります。このフィールドはインポートしてもしなくてもよい 今までは、インポート定義を設定してインポートしていたのですが、csvファイルを判別して、インポート前にフィールドの判別をする方法がわかりません。また、255文字以上の対応もうまくいきません。