Microsoft Access 掲示板

VBAでインポート処理ができたエクセルファイルのみ別フォルダへ移動したい / 16

21 コメント
views
4 フォロー
16
hiroton 2023/01/12 (木) 11:02:48 f5a37@f966d

エラー処理のやり方がこんなにある

そんなにはないです。自分がやっている処理を正確に把握して、適切にチェックしないと不慮の事態が発生します。やり方はたいてい決まった形になるでしょう。エラー処理は難しいとされるゆえんですね

書き方ならいくつかあります

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 lineResume ステートメント)で同じことはできますが、ジャンプ処理はオススメしません)

入れ子構造が深くなったり、Err.Numberのチェックが繰り返されるよりはだいぶわかりやすい処理になっていると思います。ここまでするのは関数を作るコストもあるので一概に良いとは言えませんがエラー処理が複雑化する(させる)ならOn Error GoTo Labelを使った方法を考えたほうがいいと思います

通報 ...