Excel VBA(エクセルマクロ)でブックを開く操作は「Workbooks.Open」でフルパスファイル名を指定するだけですが、Excelの制約をいろいろとかいくぐることを考えないと、マクロが異常終了するリスクだらけです。
自分だけで使っている分にはよいのですが、誰かにも使ってもらおうと思った場合には、エラーは極力発生しないようにしたいものです。
作業手順を想定しながら、効率よく処理が進むように考えました。
ダイアログで指定してもらったファイル(ブック)を開きます。
今回の環境は、Windows 10 Pro、Excel 2010/2016 です。(動作確認した環境が左記です)
チェックしておきたいこと
ダイアログでブックが指定されたかどうかは、まあまあシンプルに確認できます。
同名のブックがすでに開いているかどうかの確認が、今回の重点課題でした。
Excelでは、同名のブックを開こうとするとエラーになります。
今回の処理対象ブックは、ほいほい複製するようなものでもなかったので、展開中のブック名を確認することにしました。
サンプルコード
実際に書いたコードのデフォルメ版は以下です。
この状態でも、標準モジュールに貼り付ければ動きます。
Sub Macro01()
Dim strFileName As String
Dim strBookName As String
Dim wbkWorkBook As Workbook
strFileName = Application.GetOpenFilename("Microsoft Excelブック,*.xls*")
If strFileName <> "False" Then
' 同名ブック確認
strBookName = Mid(strFileName, InStrRev(strFileName, "¥") + 1)
For Each wbkWorkBook In Workbooks
If wbkWorkBook.Name = strBookName Then
' 同名ブックは処理対象にする
' 【処理1】
End If
Next wbkWorkBook
' 【処理2】
' 同名ブックがなければ開く
Workbooks.Open Filename:=strFileName, UpdateLinks:=0
' 【処理3】
Else
' ファイルが指定されなければ処理終了
MsgBox "ファイルが指定されませんでした。", vbExclamation
' 【処理4】
End If
' 【処理5】
End Sub
今回のコードの思想
処理対象になるブックは、もともとマクロや関数が設定されていて、長い歴史のあるものでした。
今さら手を入れられないほどにブラックボックス化しているもので、重要度は高く、編集途中で閉じてしまうとユーザーの気分が大変なことになります。。
作業手順を考慮すると、処理対象のブックを開いたままで、今回のマクロを実行する可能性が非常に高いのです。
このため、処理対象のブックをすでに開いている場合には、「処理1」の部分でオブジェクト化し、直後にGoTo文を入れて「処理5」まで飛ばすかたちにしました。
コードの見とおしや見栄えは、非常によろしくないものになってしまいました。。
また、処理対象のブックでは、関数で外部ファイルの内容を参照しているため、開くたびに他のデータソースへのリンクを更新するかどうかの確認メッセージが表示されます。
これを避けるために、ブックを開く際には「UpdateLinks:=0」を指定して、更新しないように設定しています。
残課題
サンプルコードには、本当に処理したい対象のファイル(ブック)なのかどうかの判定は入っていません。
実際に書いたコードでは、ファイル名に特定の文字列(プレフィックス)を含んでいるかどうかを判定する処理を「処理2」の位置に入れました。
他にも確認しなくてはならないことや、考慮が必要なことがあれば、相応の場所に相応の処理が必要です。
ご意見やご感想などお聞かせください! コメント機能です。