• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Access インポート時のエラー処理)

Access インポート時のエラー処理

このQ&Aのポイント
  • Access2010でCSVファイルをインポートするツールを作成しました。インポート時にデータ変換エラーが発生した場合のエラー処理方法について相談です。
  • インポート時にデータ変換エラーが発生し、エラーメッセージも表示されずに処理が進んでしまいます。Access Runtimeを使用しているため、エラーテーブルの中身を確認することができません。エラーコードからエラーメッセージを取得する方法を教えてください。
  • インポート後に作成されるエラーテーブルの有無をチェックする方法は分かりますが、エラーの内容を確認するためにはエラーテーブルを開く必要があります。Access Runtimeを使用している場合、エラーテーブルの中身が確認できません。エラーコードを取得してそれに対応するエラーメッセージを表示する方法を教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

>質問に書いているように、どのような内容のエラーなのかを拾うことは >そもそも出来ないってことなのでしょうか。 インポートエラーの「詳細内容」は拾えます。 「xxxxxx_インポート エラー」のテーブルの中に、エラーの内容、どのフィールドがエラーになったのか、どの行でエラーになったのかが書き込まれています。 但し、エラーは「1つとは限らない」ので、注意が必要です。添付画像のように、複数のエラーが1度に発生します。場合によっては「何百行も1度に発生する」可能性があります。 以下のようにして下さい。 Public Sub csvのインポート() Dim 所定のパス As String Dim FileName As String Dim ExistFlag As Boolean Dim ErrorMessage As String Dim DB As DAO.Database Dim RS As DAO.Recordset On Error GoTo 0 所定のパス = "C:\~~~~~\~~~.csv" FileName = Dir(所定のパス) If InStr(1, FileName, ".") > 0 Then FileName = Left(FileName, InStrRev(FileName, ".") - 1) End If On Error Resume Next DoCmd.RunSQL "DROP TABLE [" & FileName & "_インポート エラー]" On Error GoTo 0 DoCmd.TransferText acImportDelim, , "temp", 所定のパス, True On Error Resume Next ExistFlag = CurrentDb.TableDefs(FileName & "_インポート エラー").Name = FileName & "_インポート エラー" If ExistFlag = True Then Set DB = CurrentDb() Set RS = DB.OpenRecordset(FileName & "_インポート エラー", dbOpenTable) ErrorMessage = "インポートでエラーが発生しました。処理を中断します。" + vbCrLf Do Until RS.EOF ErrorMessage = ErrorMessage & RS!行 & "行目のフィールド「" _ & RS!フィールド & "」で「" & RS!エラー & "」が発生" & vbCrLf RS.MoveNext Loop Set RS = Nothing Set DB = Nothing MsgBox ErrorMessage Exit Sub End If On Error GoTo 0 'インポートが成功した場合の続きの処理をここに書く (略) End Sub これで、エラーメッセージは、添付画像のようになります。 但し、上記のプログラムは「エラーが何百個もあった場合を想定してない」ので、そういうcsvを読み込ませた場合は、エラーメッセージが正しく表示されないでしょう。

naoto0216
質問者

お礼

詳細なご説明ありがとうございます。 当該ツールでは数万行を読み込むこととなり、今回は 5万行ほどデータ変換エラーになった次第です。 仰る通り、インポート時にいろんなエラーが同時にありえ ますね。。全く考慮してませんでした。 エラーテーブルが作成された=データ変換エラーって訳では ないんですもんね。 そう考えると、とりあえず「何かしらの原因でエラーが あった」ってだけでも良いように思えてきました。 もしくは、エラーテーブルの「エラー」フィールドを グループ化して、それだけ表示してもよさそうですね。 大変勉強になりました。 ありがとうございました。

その他の回答 (2)

回答No.2

>On Error GoTo 0 >On Error Resume Next >が肝かと思うのですが、解説して頂けると幸いです。 「On Error GoTo 0」は「エラーが起きたら、VBAの標準のエラー処理をしなさい」という意味です。つまり「普通のエラーメッセージを出して停止しろ」って意味です。 「On Error Resume Next」は「エラーが起きても、無視して、次の行から再開しなさい」という意味です。 On Error GoTo 0 所定のパス = "C:\~~~~~\~~~.csv" FileName = Dir(所定のパス) If InStr(1, FileName, ".") > 0 Then FileName = Left(FileName, InStrRev(FileName, ".") - 1) End If ここまでは「どこかでエラーになったら止まって欲しい」つまり「『所定のパス』の内容に何か問題があったらエラーで止まって欲しい」ので「On Error GoTo 0」を実行しています。 On Error Resume Next DoCmd.RunSQL "DROP TABLE [" & FileName & "_インポート エラー]" ここでは「既存のインポートエラーのテーブルを削除」するのですが「DROP TABLEは、テーブルが無かったらエラーで止まってしまう」のでエラーで止まって欲しくはありません。つまり「もともと無かった場合は何もしなくて良い」ので、エラーを無視させる必要があります。 On Error GoTo 0 DoCmd.TransferText acImportDelim, , "temp", 所定のパス, True ここでは「インポートで、tempテーブルが無いとか、ファイルの内容が不正だとか、色々な理由でエラーが起きた場合は、エラー表示して停止して欲しい」ので「On Error GoTo 0」を実行しています。 On Error Resume Next ExistFlag = CurrentDb.TableDefs(FileName & "_インポート エラー").Name = FileName & "_インポート エラー" ここでは「インポートエラーのテーブルが生成されていたらExistFlagがTrueになり、生成されていない場合はエラーが発生」しますが、目的は「インポートエラーのテーブルが自動生成されたのかどうか知りたい」だけなので「エラーが発生した場合は、エラーを無視する」と言う目的で「On Error Resume Next」にしています。 If ExistFlag = True Then MsgBox "インポートでエラーが発生しました。処理を中断します。" Exit Sub '処理を強制終了してSubから抜ける End If ここは「インポートエラーが発生した場合、メッセージを出してから処理を中断している部分」です。 'インポートが成功した場合の続きの処理をここに書く (略) ここの「(略)」と書かれた場所に処理が移って来た場合は、インポートがエラーなしで成功しています。 なお、ここに来た時点では「エラーが起きても無視」になっているので、この「(略)」と書かれた場所より下でエラーが起きても、エラーで停止しません。 「この状態では困る」という場合は「(略)」と書いた場所に「On Error Goto 0」という行を足して下さい。

naoto0216
質問者

お礼

chie65535さま 解説ありがとうございます。 とりあえず、 DoCmd.TransferText acImportDelim, , "temp", 所定のパス, True の直前に On Error GoTo 0 を入れて試してみましたが、ここで停止することなく処理が進みました。 もちろん「On Error GoTo 0」を入れておいた方がよいかとは 思いますが、今回のエラー(データ変換エラー)は拾えないようです。 で、エラーテーブルが作成されたので、このテーブル有無をチェックし 存在していたらエラーメッセージ&強制終了ってことかと思いますが。。 ただ、この方法だと「インポート時に何かしらの原因でエラーになった」 ってことしか分からないんですね。 質問に書いているように、どのような内容のエラーなのかを拾うことは そもそも出来ないってことなのでしょうか。 エラーにも色んなケースがあるかと思うので、その全てのエラーに 対してメッセージを用意する必要は無いかと思いますが、せめて データ変換エラーかそれ以外でエラーメッセージを出したいところです。

回答No.1

Public Sub csvのインポート() Dim 所定のパス As String Dim FileName As String Dim ExistFlag As Boolean On Error GoTo 0 所定のパス = "C:\~~~~~\~~~.csv" FileName = Dir(所定のパス) If InStr(1, FileName, ".") > 0 Then FileName = Left(FileName, InStrRev(FileName, ".") - 1) End If On Error Resume Next DoCmd.RunSQL "DROP TABLE [" & FileName & "_インポート エラー]" On Error GoTo 0 DoCmd.TransferText acImportDelim, , "temp", 所定のパス, True On Error Resume Next ExistFlag = CurrentDb.TableDefs(FileName & "_インポート エラー").Name = FileName & "_インポート エラー" If ExistFlag = True Then MsgBox "インポートでエラーが発生しました。処理を中断します。" Exit Sub '処理を強制終了してSubから抜ける End If 'インポートが成功した場合の続きの処理をここに書く (略) End Sub

naoto0216
質問者

お礼

chie65535さま 度々のご回答ありがとうございます。 教えて頂いた内容を自分なりに調べてみましたが、いまいち 理解できず。。 >On Error GoTo 0  エラー処理ルーチンを無効? >If InStr(1, FileName, ".") > 0 Then > FileName = Left(FileName, InStrRev(FileName, ".") - 1) >End If  ここでは所定のパスからファイル名を取得しているんだと  思ってます。 >On Error Resume Next  エラーが発生するとエラーの発生した行から処理続行? >DoCmd.RunSQL "DROP TABLE [" & FileName & "_インポート エラー]"  ここではSQLでエラーテーブルを削除しているんだと思います。 >On Error GoTo 0  エラー処理ルーチンを無効? >DoCmd.TransferText acImportDelim, , "temp", 所定のパス, True  ここでcsvファイルをインポート >ExistFlag = CurrentDb.TableDefs(FileName & "_インポート エラー").Name = FileName & "_インポート エラー"  これは??? >If ExistFlag = True Then > MsgBox "インポートでエラーが発生しました。処理を中断します。" > Exit Sub '処理を強制終了してSubから抜ける >End If  フラグが立っていたらエラーってことでエラーメッセージ表示後  処理を抜けているんだと思います。 On Error GoTo 0 On Error Resume Next が肝かと思うのですが、解説して頂けると幸いです。 勉強不足で大変恐縮ですが、宜しくお願い致します。