はじめに
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 |
終わりに
論理演算子とビット演算子が同じ言語を初めて見た気がする。紛らわしいなあ。