エラー処理のやり方がこんなにある
そんなにはないです。自分がやっている処理を正確に把握して、適切にチェックしないと不慮の事態が発生します。やり方はたいてい決まった形になるでしょう。エラー処理は難しいとされるゆえんですね
書き方ならいくつかあります
Dim インポート成功 As Boolean
On Error Resume Next
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, tblname, f.Path, True, sname
インポート成功 = Err.Number = 0
On Error GoTo 0
If インポート成功 Then
CurrentDb.Execute "UPDATE T2 SET ファイル名 = '" & f.Name & "'" & _
" WHERE ファイル名 Is Null;", dbFailOnError
On Error Resume Next
fso.MoveFile f.Path, destinationFolder 'ファイル移動
If Err Then
'//ファイル移動失敗
Debug.Print f.Name & " " & Err.Number & ":" & Err.Description
End If
On Error GoTo 0
Else
'//"インポート失敗"
Debug.Print f.Name & " " & Err.Number & ":" & Err.Description
End If
かなりくどいですが、エラーが発生しうる処理それぞれに絞ってエラー処理を組み込んでいます。コードの記述ミスに対して強い書き方でしょう
くどいですが、よくあるOn Error Resume Next
の乱用問題を起こすよりはよっぽどマシです
ちなみに上記処理では、CurrentDb.Execute
の処理にエラートラップが掛かっていません。当然、何か処理を行えばエラーが発生する可能性があるので、ここも十分に検討が必要なポイントになります
>> 14のコードを見直してみましょう
tblname = "テーブル名"
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, tblname, f.Path, True, sname
CurrentDb.Execute "UPDATE T2 SET ファイル名 = '" & f.Name & "'" & " WHERE ファイル名 Is Null;", dbFailOnError
インポート処理では「テーブル名」テーブルを指定しているのにファイル名の書き込み処理では「T2」テーブルを指定しています
まぁ、ただの記述ミスなんでしょうが、実際に記述ミスがされていたとして、どうプログラムが動くのか考えてみてください。原因不明の問題に悩まされることでしょう
これについてはhatenaさん指摘の通り、エラートラップ処理を入れる前に正常な動作をするプログラムかどうかを確認すべきということです
やり方ということであれば、エラーがなかった時だけ続きの処理をやる=エラーが発生したら中断する方向で処理を組むというのは考えられます
Dim f As File
For Each f In fl.Files
If fso.GetExtensionName(f.Path) = "xlsx" Then
インポート処理 tblname, f, sname, fso, destinationFolder
End If
Next
Sub インポート処理(tblname As String, fsoFile As Object, sname As String, fso As Object, destinationFolder As String)
On Error GoTo ErrLabel
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, tblname, fsoFile.Path, True, sname
CurrentDb.Execute "UPDATE " & tblname & " SET ファイル名 = '" & f.Name & "'" & " WHERE ファイル名 Is Null;", dbFailOnError
fso.MoveFile fsoFile.Path, destinationFolder
On Error GoTo 0
Exit Sub
ErrLabel:
Debug.Print fsoFile.Name & " " & Err.Number & ":" & Err.Description
On Error GoTo 0
End Sub
中断がさせやすい(分かりやすい)ように処理を専用の関数に独立させてエラートラップをしています
(関数にしなくても、Resume line
(Resume ステートメント)で同じことはできますが、ジャンプ処理はオススメしません)
入れ子構造が深くなったり、Err.Number
のチェックが繰り返されるよりはだいぶわかりやすい処理になっていると思います。ここまでするのは関数を作るコストもあるので一概に良いとは言えませんがエラー処理が複雑化する(させる)ならOn Error GoTo Label
を使った方法を考えたほうがいいと思います