はじめに
VBAでフォルダの判定方法を探していた時にこんな条件式を見かけた。
If (GetAttr(filepath) And vbDirectory) > 0 Then
どうやらvbDirectory
はファイルの属性を表す定数で、整数値の16
を意味するらしい。
GetAttr(filepath)
は引数のファイルパスを調べ、vbDirectory
などのファイル属性を表す整数値を返すようだ。
ということは、仮に引数file
がフォルダでGetAttr(file)
が16を返したとするとこうなる。
If (16 And 16) > 0 Then
一瞬戸惑ってしまうが、どうやら16 And 16
の部分はビット演算の論理積を計算しているようだ。
ちなみにOr
演算子は論理和。
VBAでは論理演算子とビット演算子が同じらしい。本当に紛らわしい・・・
GetAttr
本題からはそれるが、GetAttr
は引数に指定したパスの属性を調べて、該当した属性の定数(数値)を合計して返してくれる関数らしい。
公式ドキュメントより定数を抜粋したものが下記
定数 | 値 | 説明 |
---|---|---|
vbNormal | 0 | 標準 |
vbReadOnly | 1 | 読み取り専用。 |
vbHidden | 2 | 非表示。 |
vbSystem | 4 | システム ファイル。 Macintosh では使用できません。 |
vbDirectory | 16 | ディレクトリまたはフォルダー |
vbArchive | 32 | 前回のバックアップ以降にファイルが変更されています。 Macintosh では使用できません。 |
vbAlias | 64 | 指定されたファイル名はエイリアスです。 Macintosh でのみ使用できます。 |
なぜ論理積のビット演算を使う?
調べたいビット位置に1
を仕込めば、対象のデータを拾ってこれるという論理積の性質を使用している。
(例) 読み取り専用のシステムファイルが非表示か調べたいときは、
vbReadOnly + vbSystem And vbReadOnly > 0
→ 1 + 4 And 2 > 0
→ 5 And 2 > 0
という条件式になる。
2進数4桁にすると5 → 0101
、2 → 0010
となり、論理積
を計算すると0000
になるので、条件式はFalse
、非表示属性を持っていないことがわかる。
8の位 | 4の位 | 2の位 | 1の位 |
---|---|---|---|
0 | 1 | 0 | 1 |
0 | 0 | 1 | 0 |
↓ | ↓ | ↓ | ↓ |
0 | 0 | 0 | 0 |
終わりに
論理演算子とビット演算子が同じ言語を初めて見た気がする。紛らわしいなあ。