【第13回Excelマクロ】ファイル操作のエラー対策【ほぼfor/if文】

前回、ファイル操作についてまとめました。ファイル操作をする場合、

  • ファイルの存在の確認
  • 既に開いているか確認

を確認します。例えば、ファイルを開く場合、

  • 開くファイルがそもそも存在していない
  • 既に同名のファイルを開いている

とエラーの原因になります。今回はそのエラー対策についてまとめます。

ファイルの存在の確認

Dir関数にファイルのパス+ファイル名を渡し、もしそれが見つからなければ長さ 0 の空白 (“") が返されます。そのDir関数の特性を利用して、ファイルの存在の確認をします。

Dir関数の詳細は以下のリンク参照。

Dir関数について

以下のコードをベースとして、If文内に様々な処理を記述していきます。

Dim fullName As String  'マクロファイルのパス+マクロのファイル名
fullName = "C:\VBA\test.xlsx"
Dim fileName As String   'ファイル名を格納する
fileName = Dir(fullName) '「ファイルのパス+ファイル名」からファイルの存在を確認

'===============ファイルの有無の存在確認===============
If fileName <> "" Then  'ファイルが存在する場合
    
Else    'ファイルが存在しない場合
    
End If
'===================================================

既に同名ファイルを開いているか確認

For文を使って、開いているファイルにこれから開く同名のファイルがないかを確認します。開かれていれば「既に開いています」とメッセージが出ます。このコードをベースとして、if文内に処理を記述していきます。

Dim fileName As String   'ファイル名を格納する
fileName = Dir(fullName) '「ファイルのパス+ファイル名」からファイル名を取得

'===============既に同名ブックを開いていないか確認===============
Dim wb As Workbook  '開いているブックを格納するオブジェクト変数
For Each wb In Workbooks    '開いている全てのブックから同じ名前をFor文で探す
    If wb.Name = fileName Then   'ファイル名と同じブックがある場合
        MsgBox fileName & "は既に開いています"

    End If
Next wb
'==============================================================

エラー対策の例(ファイルを開く場合)

ファイルを開く場合のエラー対策の例を以下に載せました。

既に開いているかを確認し、さらにファイルの存在の有無を確認します。もし、エラーが起こりそうであれば「Exit Sub」でマクロを終了させます。

Dim fileName As String   'ファイル名を格納する
fileName = Dir(fullName) '「ファイルのパス+ファイル名」からファイル名を取得

'===============既に同名ブックを開いていないか確認===============
Dim wb As Workbook  '開いているブックを格納するオブジェクト変数
For Each wb In Workbooks    '開いている全てのブックから同じ名前をFor文で探す
    If wb.Name = fileName Then   'ファイル名と同じブックがある場合
        MsgBox fileName & "は既に開いています"
        Exit Sub    'マクロを終了する
    End If
Next wb
'==============================================================

'===============ファイルの有無の存在確認===============
If fileName <> "" Then  'ファイルが存在する場合
    Workbooks.Open (fullName)  'ファイルを開く
Else    'ファイルが存在しない場合
    MsgBox ("ファイルが存在しません")
    Exit Sub    'マクロを終了する
End If
'===================================================

同名シートの存在の確認

シートに関しても同名のシートは作成できません。よって、こちらも以下のようなエラー対策が必要です。同名シートがあればマクロを終了します。

Dim ws As Worksheet 'ワークシートを格納するオブジェクト変数
Dim wb As String    '別のファイル名を格納する変数
wb = "test.xlsx"

Dim shName As String    'シート名を格納する変数
shName = "Sheet1"
'===============同名シートの有無の存在確認===============
For Each ws In Workbooks(wb).Worksheets '同名のシートをFor文で探す
    If shName = ws.Name Then    '同名のシートが存在している場合
        MsgBox "同名のシートが存在しています"
        Exit Sub    'マクロを終了する
    End If
Next
'=====================================================

関数を使ったエラー対策

ファイル操作をするたびに同様のコードを書くのはちょっと手間ですよね。VBAでも自分で関数を作ってそれを使用することができます。

以下がその関数を使ったコードになります。使い方ですが、まずファイルが開かれているかどうか確認する関数が「IsFileOpened」になります。こちらにファイルのパス+ファイル名を渡して使います。開かれていればTrue、開いていなければFalseを Boolean型で返します。

そして、ファイルの存在の確認をする関数が「IsFileExist」になります。こちらにもファイルのパス+ファイル名を渡します。ファイルがあればTrue、なければFalseをBoolean型で返します。

コピペして使ってみてください。

Sub test()

Dim filePath As String  'マクロファイルのパス
filePath = ThisWorkbook.Path

Dim fullName As String  '確認するファイルのパス+ファイル名
fullName = filePath & "\test.xlsx"

Dim FileOpenFlag As Boolean '関数を変数に格納してもOK
FileOpenFlag = IsFileOpened(fullName)

If FileOpenFlag = True Then
    MsgBox "既にファイルを開いています"
End If

If IsFileExist(fullName) = True Then  '関数をそのまま条件式に使ってもOK
    MsgBox "既にファイルが存在しています"
End If

End Sub

Function IsFileOpened(ByVal fullName As String) As Boolean    '開いているブックに同名がないかを確認(True:開いている)
IsFileOpened = False    '初期値をFalseに設定
Dim fileName As String   'ファイル名を格納する
fileName = Dir(fullName) '「ファイルのパス+ファイル名」からファイル名を取得
Dim wb As Workbook  '開いているブックを格納するオブジェクト変数
For Each wb In Workbooks    '開いている全てのブックから同じ名前をFor文で探す
    If wb.Name = fileName Then   'ファイル名と同じブックがある場合
        IsFileOpened = True
    End If
Next wb
End Function

Function IsFileExist(ByVal fullName As String) As Boolean    'ファイルの存在確認(True:ファイルが存在する)
IsFileExist = False '初期値をFalseに設定
Dim fileName As String   'ファイル名を格納する
fileName = Dir(fullName) '「ファイルのパス+ファイル名」からファイル名を取得
If fileName <> "" Then  'ファイルが存在している
    IsFileExist = True
End If
End Function

「Function~End Function」に記述されているのが関数です。下のように「Sub~End Sub」内には記述せず、別に記述して使います。

次に、同名のシートを確認する関数になります。使い方ですが、関数「IsSheetExist」に同名シートを確認するファイル名と確認するシート名を渡して使用します。

例えば、変数wbに同名シートを確認するファイル名、変数shNameに確認するシート名を代入したとき、関数には「IsSheetExist(wb, shName)」というように「ファイル名,シート名」の順で関数に渡して使います。この順番が違うとエラーになりますので注意してください。シートが既にあればTrue、なければFalseをBoolean型で返します。

Sub test()
Dim ws As Worksheet 'ワークシートを格納するオブジェクト変数
Dim wb As String    '別のファイル名を格納する変数
wb = "test.xlsx"

Dim shName As String    'シート名を格納する変数
shName = "Sheet3"

If IsSheetExist(wb, shName) = True Then
    MsgBox "同名のシートが存在しています"
End If
End Sub

Function IsSheetExist(ByVal wb As String, ByVal shName As String) As Boolean    'シートの存在確認(True:同名シートが存在する)

IsSheetExist = False    '初期値をFalseに設定
For Each ws In Workbooks(wb).Worksheets '同名のシートをFor文で探す
    If shName = ws.Name Then    '同名のシートが存在している場合
        IsSheetExist = True
    End If
Next

End Function

以下は、上記で紹介した3つの関数だけを記述したコピペ用コードです。

Function IsFileOpened(ByVal fullName As String) As Boolean    '開いているブックに同名がないかを確認(True:開いている)
IsFileOpened = False    '初期値をFalseに設定
Dim fileName As String   'ファイル名を格納する
fileName = Dir(fullName) '「ファイルのパス+ファイル名」からファイル名を取得
Dim wb As Workbook  '開いているブックを格納するオブジェクト変数
For Each wb In Workbooks    '開いている全てのブックから同じ名前をFor文で探す
    If wb.Name = fileName Then   'ファイル名と同じブックがある場合
        IsFileOpened = True
    End If
Next wb
End Function

Function IsFileExist(ByVal fullName As String) As Boolean    'ファイルの存在確認(True:ファイルが存在する)
IsFileExist = False '初期値をFalseに設定
Dim fileName As String   'ファイル名を格納する
fileName = Dir(fullName) '「ファイルのパス+ファイル名」からファイル名を取得
If fileName <> "" Then  'ファイルが存在している
    IsFileExist = True
End If
End Function

Function IsSheetExist(ByVal wb As String, ByVal shName As String) As Boolean    'シートの存在確認(True:同名シートが存在する)

IsSheetExist = False    '初期値をFalseに設定
For Each ws In Workbooks(wb).Worksheets '同名のシートをFor文で探す
    If shName = ws.Name Then    '同名のシートが存在している場合
        IsSheetExist = True
    End If
Next
End Function

最後に

今回触れたエラー対策ですが、ファイルを開くときだけではなく、削除するときや新しくファイルを作成するときなど、様々な場面で必要になります。ファイルを開くときのエラー対策の例を参考にして、コードを訂正して使ってみてください。

ExcelExcelマクロ

Posted by プーレ