更新日:、 作成日:
VBA ビット演算やビットシフトする
はじめに
Excel VBA マクロでビット演算やビットシフトする方法を紹介します。
ビット演算とは、数値を 2 進数で考えて各桁に対して論理演算することです。
値 Or フラグ のようにして、フラグを立てられます。
値 And フラグ のようにして、フラグを取得できます。
値 And Not フラグ のようにして、フラグを下ろせます。
値 * (2 ^ 桁数) のようにして、左シフトできます。
値 \ (2 ^ 桁数) のようにして、右シフトできます。
2進数とは
2進数とは 0 と 1 だけで数値を表したものです。1 の次は桁が繰り上がって 10 で 2 を表します。
各桁が 0 なら 0。1 なら 1, 2, 4, 8 … のように桁が増えるごとに 2 の倍数で繰り上がっていきます。
ビット演算する
ビット演算とは論理演算子を数値に対して使うことです。数値を 2 進数で考えて、各桁ごとに 0 を False、1 を True として処理をします。
演算子 | 演算名 | 使用例 | 結果 |
And | 論理積 | 1 And 1 1 And 0 0 And 0 | 1 0 0 |
Or | 論理和 | 1 Or 1 1 Or 0 0 Or 0 | 1 1 0 |
Not | 論理否定 | Not 1 Not 0 | 0 1 |
Xor | 排他的論理和 | 1 Xor 1 1 Xor 0 0 Xor 0 | 0 1 0 |
値 演算子 フラグ のように入力します。
Const Red As Integer = 1 ' 001、1 桁目が Red
Const Green As Integer = 2 ' 010、2 桁目が Green
Const Blue As Integer = 4 ' 100、3 桁目が Blue
Const Black As Integer = 0 ' 000
Const White As Integer = 7 ' 111
Dim color1 As Integer
color1 = White And Red ' 111 And 001、ビット演算 フラグを取得する
Debug.Print(color1) ' 1 (001)、White に Red が含まれている
Dim color2 As Integer
color2 = Black Or Green ' 000 Or 010、ビット演算 フラグを立てる
Debug.Print(color2) ' 2 (010)、Black に Green を追加する
このように各桁の単位で論理演算が行われます。この各桁を「フラグ」と言います。詳しく紹介していきます。
フラグを立てる
値 Or フラグ のように入力します。Or 演算子を使ってそのフラグを立てられます。Or は 1 なら必ず 1 になるため、どんな値でも必ずそのフラグを立てられます。
Const Red As Integer = 1 ' 001
Const Green As Integer = 2 ' 010
Const Blue As Integer = 4 ' 100
Dim color As Integer ' 空の値
' Red フラグを立てる
color = color Or Red ' 000 Or 001
Debug.Print(color) ' 1 (001)、Red が含まれている
' Green フラグを立てる
color = color Or Green ' 001 Or 010
Debug.Print(color) ' 3 (011)、Red と Green が含まれている
' Blue フラグを立てる
color = color Or Blue ' 011 Or 100
Debug.Print(color) ' 7 (111)、Red と Green と Blue が含まれている
フラグを取得する
値 And フラグ のように入力します。And 演算子を使ってそのフラグを取得できます。And は 1 と 1 のときだけ 1 になるため、値にそのフラグが立っているときだけそのフラグを取得できます。
Const Red As Integer = 1 ' 001
Const Green As Integer = 2 ' 010
Const Blue As Integer = 4 ' 100
Const Yellow As Integer = Red Or Green ' 011
Dim color As Integer
' Red フラグを取得する
color = Yellow And Red ' 011 And 001
Debug.Print(color) ' 1 (001)、0 以外ならそのフラグが含まれている
' Green フラグを取得する
color = Yellow And Green ' 011 And 010
Debug.Print(color) ' 2 (010)、0 以外ならそのフラグが含まれている
' Blue フラグを取得する
color = Yellow And Blue ' 011 And 100
Debug.Print(color) ' 0 (000)、0 はフラグが立っていない
フラグを下ろす
値 And Not フラグ のように入力します。Not 演算子でフラグを反転してから And 演算子でフラグ以外をすべて取得します。反転させると 001 は 110 になります。そのフラグだけ 0 になり、それ以外は 1 なので And でフラグだけ 0 にできます。
Const Red As Integer = 1 ' 001
Const Green As Integer = 2 ' 010
Const Blue As Integer = 4 ' 100
Const White As Integer = Red Or Green Or Blue ' 111
Dim color As Integer
' Red フラグを下ろす
color = White And Not Red ' 111 And 110
Debug.Print(color) ' 6 (110)
' Green フラグを下ろす
color = White And Not Green ' 111 And 101
Debug.Print(color) ' 5 (101)
' Blue フラグを下ろす
color = White And Not Blue ' 111 And 011
Debug.Print(color) ' 3 (011)
Enum フラグ
上記の例ではフラグに Const を使っていますが、実際は Enum を使うことがよくあります。これによりフラグ同士の関連性がわかりやすくなります。
Enum Color
Black = 0 ' 000
Red = 1 ' 001
Green = 2 ' 010
Blue = 4 ' 100
White = 7 ' 111
End Enum
例えば、セルの上下左右の罫線を Top, Bottom, Left, Right のようにフラグにするなどです。
スポンサーリンク
ビットシフトする
ビットシフトとは各桁を 1 桁左や右にずらすことです。VBA にはそのような演算子はありませんが次のようにしてできます。
左シフト
値 * (2 ^ 桁数) のように入力します。桁数に指定した数だけ左にずれます。^ はべき乗です。
Const Three As Long = 3 ' 00000011
Dim bit As Long
bit = Three * (2 ^ 1) ' 1 桁左へシフト
Debug.Print(bit) ' 6 (00000110)
bit = Three * (2 ^ 2) ' 2 桁左へシフト
Debug.Print(bit) ' 12 (00001100)
bit = Three * (2 ^ 3) ' 3 桁左へシフト
Debug.Print(bit) ' 24 (00011000)
右シフト
値 \ (2 ^ 桁数) のように入力します。桁数に指定した数だけ右にずれます。
Const Twentyfour As Long = 24 ' 000011000
Dim bit As Long
bit = Twentyfour \ (2 ^ 1) ' 1 桁右へシフト
Debug.Print(bit) ' 12 (00001100)
bit = Twentyfour \ (2 ^ 2) ' 2 桁右へシフト
Debug.Print(bit) ' 6 (00000110)
bit = Twentyfour \ (2 ^ 3) ' 3 桁右へシフト
Debug.Print(bit) ' 3 (00000011)
どちらの場合でも数値型の範囲を超えると「エラー 6 オーバーフローしました。」が発生するので注意してください。