プチIT化

マクロでファイル選択をキャンセル、2回聞かれてエラーとなる現象

こんにちは、わたあめです。今日は、Excel VBAマクロのファイル選択ダイアログについての記事です。

ファイルを選択するダイアログ(application.filedialog(msofiledialogfilepicker))を使うExcel VBAマクロ。ファイル選択をキャンセルしても終了せず、以下の挙動となりました。

  • [参照]ダイアログでファイルを選択せずに[キャンセル]ボタンをクリック
  • キャンセルしたにも関わらず同じ[参照]ダイアログが出る
  • もう一度、ファイルを選択せずに[キャンセル]ボタンをクリック
  • その後のマクロ処理が進んで、エラーが出る

読み込んだファイルがある前提で処理が進むので、処理データがなく以下のようなエラーが出たりしました。

実行時エラー'6'オーバーフローしました。
実行時エラー'1004'このコマンドにはデータソースが2行以上必要です。

この現象について記事にまとめています。他「実行時エラー'1004'申し訳ございません。が見つかりません。」についても最後の方に記載しています。

それでは、いってみましょう!

原因

原因は処理の中で、".Show"メソッドを2回書いていたからでした。

.Showメソッドとは

".Show"はファイル選択ダイアログを表示してくれるメソッドです。基本構文は以下のように書きます。

Application.FileDialog(msoFileDialogFolderPicker).Show

ファイル選択ダイアログ表示した後、ユーザがファイルを選択したかどうかが"戻り値"として返ってきます。これがファイルを選択したかどうかの判定に必要な値です。

戻り値について

Application.FileDialog(msoFileDialogFilePicker).Showは、ファイルを選択したか否かの処理に応じて以下の値となります。

ファイルを選択した場合-1,True
ファイルを選択しなかった場合(キャンセルボタン)0,False

※「-1」や「0」、「True」や「False」どちらでも意味合いは同じ、好きな書き方でOKです。

わたあめ
わたあめ
これらの知識を念頭において、失敗したサンプルコードをみてみましょう。

失敗サンプルコード

キャンセル後もう一度ダイアログが表示されてしまうコードは以下です。

With Application.FileDialog(msoFileDialogFilePicker)
  .Filters.Clear
  .Filters.Add "Excelファイル", "*.csv"
  If .Show = True Then
    SelectedFile = .SelectedItems(1)
  ElseIf .Show = False Then
    End
  End If
End With

キャンセルボタンを押すことにより、「If .Show = True」と「ElseIf .Show = False Then」と、2つの.Showを通過することになるます。よって2回ダイアログが表示されてしまう。ファイルが選択された場合は「If .Show = True」のみで、If文を抜けるので、2回表示されることはなかったということです。

わたあめ
わたあめ
では、どうしたらいいのか?!次の章に対処を記載します。

対処

ElseIfをElseに変更しました。上記コードを以下のように変更しています。".Show"が2回書かれていないので、2回ファイル選択ダイアログが表示されることはなくなりました。

With Application.FileDialog(msoFileDialogFilePicker)
  .Filters.Clear
  .Filters.Add "Excelファイル", "*.csv"
  If .Show = True Then
    SelectedFile = .SelectedItems(1)
  Else
    End
  End If
End With

もっとスマートに書くなら、「もしキャンセルボタンを押したら処理終了する」という処理だけで良い気がしています。サンプルコードは以下です。

With Application.FileDialog(msoFileDialogFilePicker)
  .Filters.Clear
  .Filters.Add "Excelファイル", "*.csv"
  If .Show = False Then
    End
  End If
  SelectedFile = .SelectedItems(1)
End With

このように、.Showの回数=ダイアログ表示回数ということを考えて、マクロを作成すれば良いですね。(きっと)

余談:.Showの判定文がない場合

キャンセルボタンがクリックされたときの処理(.Show=False)が省略されていた場合、キャンセルボタンでファイルを選択しないと以下のエラーが出ました。

実行時エラー'1004'申し訳ございません。が見つかりません。名前が変更されたか、移動や削除が行われた可能性があります。

上記エラーが出るキャンセル処理が書かれていないサンプルコードは以下です。

With Application.FileDialog(msoFileDialogFilePicker)
  .Filters.Clear
  .Filters.Add "Excelファイル", "*.csv"
  If .Show = True Then
    SelectedFile = .SelectedItems(1)
  End If
End With

ファイルを選択した場合(True)の処理は書かれていますが、ファイルを選択しない場合(False)の処理が全く書かれていないのでエラーとなりました。

わたあめ
わたあめ
キャンセルの時の処理は忘れないように書かなくては…!

さいごに

今日はVBAのファイル選択ダイアログについてのエラー記事でした。前任者の書いたコードだったのですが、何か意図があったのかなー?と思いつつ、修正しちゃいました。

それでは、また!

flier(フライヤー)