【VBA】ファイルやフォルダの確認・名前を取得する(Dir関数)

Excel・VBA

今回はDir関数の使い方を説明です。Dir関数は、ファイルやフォルダの有無を確認したり、名前を取得することが可能な関数です。ワイルドカードと組み合わせて利用すると便利です。

【今回の内容】
1.Dir関数の書式
2.Dir関数を使用してファイルの有無を確認する
3.Dir関数を使用してファイル名を取得する
4.Dir関数を使用してフォルダ名を取得する

Dir関数の書式

Dir関数の書式は次の通りです。

《Dir関数の書式》
 Dir( pathname [, attributes ]
 ※[, attributes ]は省略可能。省略時は標準ファイルを取得
 ※Dir関数で取得する値(戻り値):文字列型(String)

pathnameへは、対象の絶対パスを指定します。(C:\○○\○○\ファイル名など)

attributesは取得するファイルの属性を指定します。

定数 属性
vbNormal 0 標準ファイル(既定)
vbReadOnly 1 読み取り専用ファイル
vbHidden 2 隠しファイル
vbSystem 4 システムファイル
vbVolume 8 ボリュームラベル
vbDirectory 16 フォルダ

attributesの指定は、取得するファイルの属性の値の合計値もしくは、属性を「And」,「Or」や「+」で繋ぎ、組み合わせて指定します。

Dir関数を使用してファイルの有無を確認する

Dir関数の戻り値は、次の通りです。

《Dir関数の戻り値》
 ファイルが存在する:ファイル名
 ファイルが存在しない:””(長さ0の文字列)

またファイルの存在を調べるケースとして次の2通りが想定されます。
 1.特定のファイルの存在を調べる
 2.ファイルがあるかどうかを調べる

1のケースは絶対パスを指定できますが2のケースの場合は、ファイル名が不明なためパスの指定ができません。このような場合は、ワイルドカードを利用します。ワイルドカードの種類と特性は次の通りです。

文字 内容
* 0文字以上の文字列を表す
? 1文字を表す
# 0~9の半角数字を表す

サンプルコード(ファイルの有無を確認する)

【ファイル名が既知の場合】
 Sub dir_sample()
  Dim fname As String

  fpath = ThisWorkbook.Path
  fname = "Sample.xlsx"

  If dir(fpath & "\" & fname) = "" Then
   MsgBox ("ファイルがありません")
  Else
   MsgBox (fname & "は存在します。")
  End If
 End Sub

このコードでは、マクロを実行しているファイルと同じ場所に”Sample.xlsx”というファイルが存在しているかを調べています。ファイルがなければ”ファイルがありません”、ファイルが存在していれば”Sample.txtは存在します”をと表示します。

【ファイル名が未知の場合】 
 Sub dir_sample()
  Dim fpath As String
  Dim fname As String
  Dim ct As Integer

  ct = 0
  fpath = ThisWorkbook.Path
  fname = "*.xlsx"
  dir (fpath & "\" & fname)

  Do Until dir() = ""
   If dir() <> "" Then ct = ct + 1
  Loop

このコードでは、拡張子”.xlsx”を持つファイルが何個あるかを調べています。もし拡張子に関係なくファイルが何個あるかを調べる場合は、fname=”*.*”としてください。(拡張子を”*”に変更する)

サンプルコードでは、 Do Loopの部分で記載しているDir関数の引数pathnameを省略しています。Dir関数では引数を省略した場合は、前回の設定した値が適用されます。

Dir関数を使用してファイル名を取得する

Dir関数では、引数pathnameを省略可能です。省略した場合は、前回の設定した値が適用されます。この特性とワイルドカードを利用して特定のフォルダ内に存在するファイル名を取得することが可能です。

サンプルコード(ファイル名を取得する)

次のコードでは、このコードを実行したファイルと同じフォルダ内の”.xlsx”を拡張子にもつファイルの名前を取得します。

Sub dir_sample()
  Dim fpath As String
  Dim fname As String
  Dim namaehairetsu() As String
  Dim dummy As String
  Dim ct As Integer
  Dim namae As String 
  
  ct = 0
  fpath = ThisWorkbook.Path
  fname = "*.xlsx"
  dummy = dir(fpath & "\" & fname)
  
  Do Until dummy = ""
   ct = ct + 1
   dummy = dir()
  Loop
  
  ReDim namaehairetsu(1 To ct, 1 To 1)
  dummy = dir(fpath & "\" & fname)
  
  For i = 1 To ct
   namaehairetsu(i, 1) = dummy
   namae = namae & dummy & vbCrLf
   dummy = dir()
  Next
  MsgBox (namae)
 End Sub 

このサンプルコードの説明は次の通りです。

サンプルコードの説明

Dir関数を使用してフォルダ名を取得する

Dir関数では、引数 attributesの値にフォルダの属性(vbDirectory)を指定することでフォルダ名を取得可能です。ただし、問題が二つあります。
まず一つ目は、属性値をフォルダのみに指定することができないことです。

これは標準ファイルの属性値が0なため、どの値を指定しても必ず含まれてしまうことが原因です。

《属性の値》
 フォルダの属性値   vbDirectory :16
 標準ファイルの属性値 vbNormal :0

引数 attributesは定数の値の合計値で判断するので、値が0であるvbNormalは記載がなくても、指定されていると認識されてしまうのです。

二つ目は、フォルダを検索している場所の名前が”.”、一つ上の親フォルダ名が”..”として取得されます。

これらの解決し、フォルダ名を取得するには、
1.戻り値の属性を調べ、フォルダであるものを取得する
2.戻り値のうち、”.”と”..”は取得しない

まず1つめの対策としては、 GetAttr関数を利用します。 GetAttr関数は、ファイルの属性値を整数で返します。返す整数の意味は、Dir関数の属性値と同じです。

なおGetAttr関数の引数にファイル・フォルダ名を指定する際には、絶対パスでの指定した方がエラーが起きにくいです。

《GetAttr関数の書式》
  GetAttr( pathname

GetAttr関数の戻り値がフォルダを表す16であれば取得すればよいことになります。

サンプルコード(フォルダ名を取得する)

また2つ目の対策は、IF関数を利用して、 “.”と”..” でなければ取得するようにします。これらを踏まえてフォルダ名を取得するサンプルコードは次のようになります。

Sub directory_sample()
  Dim dirname As String
  Dim dirpath As String
  Dim dummy As String

  dirpath = ThisWorkbook.Path & "\"
  dummy = dir(dirpath, vbDirectory)

  Do Until dummy = ""
   If GetAttr(dirpath & dummy) = 16 And dummy <> "." And dummy <> ".." Then
    dirname = dirname & dummy & vbCrLf
   End If
   dummy = dir()
  Loop
  MsgBox (dirname)
 End Sub

このコードのポイントは次の通りです。

コメント

タイトルとURLをコピーしました