【VBA】論理演算でビットからデータを取得する
<機能>
(1)ビット単位で効率的に格納されているデータを取り出してみる
(2)VBAで論理積(AND演算)、シフトを使ってみる
(3)論理和(OR演算)、排他的論理和(XOR演算)、論理否定(NOT演算)もサンプルを掲載
<使い方>
適当なところにソースを張り付けて「論理演算()」を呼び出してください
<サンプルデータ構造>
データの数値は厚生労働省の病院報告(平成27年9月分概数)より引用
http://www.mhlw.go.jp/toukei/saikin/hw/byouin/m15/09.html
<イメージ>
イミディエイトウィンドウに論理演算の実行結果を出力
※ウィンドウが表示されていない場合はVBEの 表示 → イミディエイトウィンドウ で表示できます
'********************************************
'VBAで論理演算をやってみるサンプルプログラム
'********************************************
Sub 論理演算()
Dim i As Integer
Dim cd As Long
Dim patient As Long
'VBAで論理演算をやってみるサンプルプログラム
'********************************************
Sub 論理演算()
Dim i As Integer
Dim cd As Long
Dim patient As Long
'//全て(数式、文字列、書式、コメント、アウトライン)クリア
Cells.Select
Selection.Clear
Selection.Font.Name = "MS ゴシック"
Selection.Font.Size = 12
Columns("A").ColumnWidth = 20
Columns("B").ColumnWidth = 20
Columns("C").ColumnWidth = 20
Range("A1").Select
Cells(1, 1) = "都道府県コード"
Cells(1, 2) = "都道府県名"
Cells(1, 3) = "1日平均外来患者数(病院)"
Cells.Select
Selection.Clear
Selection.Font.Name = "MS ゴシック"
Selection.Font.Size = 12
Columns("A").ColumnWidth = 20
Columns("B").ColumnWidth = 20
Columns("C").ColumnWidth = 20
Range("A1").Select
Cells(1, 1) = "都道府県コード"
Cells(1, 2) = "都道府県名"
Cells(1, 3) = "1日平均外来患者数(病院)"
'//47都道府県の「病院の1日平均外来患者数」データ
Dim gairai() As Variant
Dim gairai() As Variant
'//4バイトのLong型変数の先頭0固定(符号なしとする)とする
'//続く6ビットが都道府県コード、25ビットが1日平均外来患者数
'//6ビットで表現できる数値は0〜63、25ビットで表現できる数値は0〜33554431である
'//データは厚生労働省の病院報告(平成27年9月分概数)より引用
'//http://www.mhlw.go.jp/toukei/saikin/hw/byouin/m15/09.html
gairai() = Array(&H14A422, &H2012C7F, &H400375D, &H600331F, &H8005201, _
&HA0032E5, &HC002F60, &HE004DFB, &H100075F7, &H12004D2D, _
&H14004D6A, &H1600F476, &H1800E7AF, &H1A0227F5, &H1C012999, _
&H1E00624D, &H20003592, &H22003B65, &H2400299A, &H2600254C, _
&H280063D2, &H2A0053B0, &H2C00773B, &H2E010849, &H3000414D, _
&H320034B2, &H34007AC4, &H3601703D, &H3800D856, &H3A003AEB, _
&H3C002D17, &H3E001AE5, &H40001CF4, &H42006539, &H44007CAB, _
&H46003ED2, &H48002AB6, &H4A00393F, &H4C004A12, &H4E0030FE, _
&H5000E0E1, &H5200293B, &H540043F3, &H560054C5, &H58003AF3, _
&H5A003330, &H5C0051DB, &H0)
'//続く6ビットが都道府県コード、25ビットが1日平均外来患者数
'//6ビットで表現できる数値は0〜63、25ビットで表現できる数値は0〜33554431である
'//データは厚生労働省の病院報告(平成27年9月分概数)より引用
'//http://www.mhlw.go.jp/toukei/saikin/hw/byouin/m15/09.html
gairai() = Array(&H14A422, &H2012C7F, &H400375D, &H600331F, &H8005201, _
&HA0032E5, &HC002F60, &HE004DFB, &H100075F7, &H12004D2D, _
&H14004D6A, &H1600F476, &H1800E7AF, &H1A0227F5, &H1C012999, _
&H1E00624D, &H20003592, &H22003B65, &H2400299A, &H2600254C, _
&H280063D2, &H2A0053B0, &H2C00773B, &H2E010849, &H3000414D, _
&H320034B2, &H34007AC4, &H3601703D, &H3800D856, &H3A003AEB, _
&H3C002D17, &H3E001AE5, &H40001CF4, &H42006539, &H44007CAB, _
&H46003ED2, &H48002AB6, &H4A00393F, &H4C004A12, &H4E0030FE, _
&H5000E0E1, &H5200293B, &H540043F3, &H560054C5, &H58003AF3, _
&H5A003330, &H5C0051DB, &H0)
'//データの最後"沖縄"は0となっていますが都道府県コード=47、外来患者数=14265をセットしてみます
'//1ビット:0固定
'//2〜7ビット:47(沖縄県)
'//8〜32ビット:14265(1日平均外来患者数)
'//1ビット左シフトするには2を掛ければばよいため、都道府県コードを25ビットシフトするには2の25乗を乗算する
Dim okinawa As Long
okinawa = (47 * (2 ^ 25)) + 14265
gairai(47) = okinawa
'//47都道府県の「病院の1日平均外来患者数」データを表示してみる
For i = 0 To UBound(gairai)
'//32ビット(4バイト)の値の上位7ビット(都道府県コード)を取得する
'//1ビット右シフトするには2で割ればよいため、25ビットシフトするには2の25乗で除算する
'//cdには上位7ビットがセットされる
cd = gairai(i) ¥ (2 ^ 25)
For i = 0 To UBound(gairai)
'//32ビット(4バイト)の値の上位7ビット(都道府県コード)を取得する
'//1ビット右シフトするには2で割ればよいため、25ビットシフトするには2の25乗で除算する
'//cdには上位7ビットがセットされる
cd = gairai(i) ¥ (2 ^ 25)
'//32ビット(4バイト)の値の下位25ビット(外来患者数)を取得
'//論理積(AND演算)にて下位25ビットを取り出す
'//Long型の変数に対して&H01FFFFFF(0000 0001 1111 1111 1111 1111 1111 1111)で論理積をとる
'//0で論理積をとったビットがマスクされる
patient = gairai(i) And &H1FFFFFF
'//論理積(AND演算)にて下位25ビットを取り出す
'//Long型の変数に対して&H01FFFFFF(0000 0001 1111 1111 1111 1111 1111 1111)で論理積をとる
'//0で論理積をとったビットがマスクされる
patient = gairai(i) And &H1FFFFFF
'//取り出した情報をシートに表示
Cells(i + 2, 1) = "'" & cd
Cells(i + 2, 2) = GetPrefectureName(cd)
Cells(i + 2, 3) = patient
Next
Cells(i + 2, 1) = "'" & cd
Cells(i + 2, 2) = GetPrefectureName(cd)
Cells(i + 2, 3) = patient
Next
'//ここからおまけコードです
'//ビット演算のおさらい
Dim a As Integer, b As Integer
'//ビット演算のおさらい
Dim a As Integer, b As Integer
'//(1)論理和のおさらい
'//あるビットを強制的に1にすることができます
a = 15782
Debug.Print "a=" & a
'//変数a(偶数か奇数かわからない)を強制的に奇数にする
b = a Or &H1
Debug.Print "b=" & b
'//あるビットを強制的に1にすることができます
a = 15782
Debug.Print "a=" & a
'//変数a(偶数か奇数かわからない)を強制的に奇数にする
b = a Or &H1
Debug.Print "b=" & b
'//(2)論理積のおさらい
'//あるビットを取り出すことができます
a = &H3DA6
Debug.Print "a=&H" & Hex(a)
'//上位1バイトを取り出します(1111 1111 0000 0000でマスクして右に8ビットシフト)
b = (a And &HFF00) ¥ 256
Debug.Print "b=&H" & Hex(b)
'//あるビットを取り出すことができます
a = &H3DA6
Debug.Print "a=&H" & Hex(a)
'//上位1バイトを取り出します(1111 1111 0000 0000でマスクして右に8ビットシフト)
b = (a And &HFF00) ¥ 256
Debug.Print "b=&H" & Hex(b)
'//(3)論理否定のおさらい
'//ビットを反転させる(1→0、0→1)ことができます
a = &H3DA6
Debug.Print "a=&H" & Hex(a)
'//各ビットが装置のON/OFFとなっているようなケースでON/OFFの切り替えを行います
'//&H3DA6(0011 1101 1010 0110)→&HC259(1100 0010 0101 1001)
b = Not a
Debug.Print "b=&H" & Hex(b)
'//ビットを反転させる(1→0、0→1)ことができます
a = &H3DA6
Debug.Print "a=&H" & Hex(a)
'//各ビットが装置のON/OFFとなっているようなケースでON/OFFの切り替えを行います
'//&H3DA6(0011 1101 1010 0110)→&HC259(1100 0010 0101 1001)
b = Not a
Debug.Print "b=&H" & Hex(b)
'//(4)排他的論理和のおさらい
'//部分的にビットを反転させる(1→0、0→1)ことができます
a = &H3DA6
Debug.Print "a=&H" & Hex(a)
'//各ビットが装置のON/OFFとなっているようなケースで上位バイトのみON/OFFの切り替えを行います
'//&H3DA6(0011 1101 1010 0110)→&HC2A6(1100 0010 1010 0110)
b = a Xor &HFF00
Debug.Print "b=&H" & Hex(b)
'//部分的にビットを反転させる(1→0、0→1)ことができます
a = &H3DA6
Debug.Print "a=&H" & Hex(a)
'//各ビットが装置のON/OFFとなっているようなケースで上位バイトのみON/OFFの切り替えを行います
'//&H3DA6(0011 1101 1010 0110)→&HC2A6(1100 0010 1010 0110)
b = a Xor &HFF00
Debug.Print "b=&H" & Hex(b)
End Sub
'********************************************
'都道府県コードから都道府県名を取得
'********************************************
Function GetPrefectureName(ByVal idx As Integer) As String
Dim prefecture As Variant
'都道府県コードから都道府県名を取得
'********************************************
Function GetPrefectureName(ByVal idx As Integer) As String
Dim prefecture As Variant
'//都道府県コードはprefectureのインデックスとなります
'//都道府県コードは1から始まるためインデックス0には"全国"をセットします
'//例)1:北海道 13:東京 47:沖縄
prefecture = Array("全国", "北海道", "青森", "岩手", "宮城", "秋田", "山形", "福島", "茨城", "栃木", "群馬", _
"埼玉","千葉", "東京", "神奈川", "新潟", "富山", "石川", "福井", "山梨", "長野", "岐阜", "静岡", "愛知", _
"三重","滋賀", "京都", "大阪", "兵庫", "奈良", "和歌山", "鳥取", "島根", "岡山", "広島", "山口", "徳島", _
"香川","愛媛", "高知", "福岡", "佐賀", "長崎", "熊本", "大分", "宮崎", "鹿児島", "沖縄")
'//初期値をセット
GetPrefectureName = ""
'//都道府県コードは1から始まるためインデックス0には"全国"をセットします
'//例)1:北海道 13:東京 47:沖縄
prefecture = Array("全国", "北海道", "青森", "岩手", "宮城", "秋田", "山形", "福島", "茨城", "栃木", "群馬", _
"埼玉","千葉", "東京", "神奈川", "新潟", "富山", "石川", "福井", "山梨", "長野", "岐阜", "静岡", "愛知", _
"三重","滋賀", "京都", "大阪", "兵庫", "奈良", "和歌山", "鳥取", "島根", "岡山", "広島", "山口", "徳島", _
"香川","愛媛", "高知", "福岡", "佐賀", "長崎", "熊本", "大分", "宮崎", "鹿児島", "沖縄")
'//初期値をセット
GetPrefectureName = ""
'//インデックスチェック(0〜47)
If idx > UBound(prefecture) Or idx < 0 Then Exit Function
If idx > UBound(prefecture) Or idx < 0 Then Exit Function
'//都道府県名を返す
GetPrefectureName = prefecture(idx)
End Function
GetPrefectureName = prefecture(idx)
End Function
よろしければポチッと押してください