更新日:、 作成日:

VBA ビット演算やビットシフトする

はじめに

Excel VBA マクロでビット演算やビットシフトする方法を紹介します。

ビット演算とは、数値を 2 進数で考えて各桁に対して論理演算することです。

値 Or フラグ のようにして、フラグを立てられます。

値 And フラグ のようにして、フラグを取得できます。

値 And Not フラグ のようにして、フラグを下ろせます。

値 * (2 ^ 桁数) のようにして、左シフトできます。

値 \ (2 ^ 桁数) のようにして、右シフトできます。

2進数とは

2進数とは 0 と 1 だけで数値を表したものです。1 の次は桁が繰り上がって 10 で 2 を表します。

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 オーバーフローしました。」が発生するので注意してください。