Byte配列と文字コード関数について
マクロVBAのデータ型にByte型がありますが、使う機会はかなり限られています。
バイト型は、8 ビット (1 バイト) の変数で、0~255の範囲の単精度の正の数値が格納されます。
今回はByte配列に文字列を入れることで、文字コードについて考察してみます。
文字コードとは面倒なものだなーと、それくらいの意識で読んでもらえれば良いと思います。
文字列をByte配列に入れる
Sub 文字列_Byte配列()
Dim aryByte() As Byte
aryByte = "Excelの神髄"
Stop
End Sub
バイト配列の宣言は、
Dim aryByte() As Byte
普通にByteを配列として宣言します。
配列の要素数は文字数に依存するので、今回は動的配列にしています。
このByte配列には、文字列(String)を直接代入できます。
この数値が文字コードになります。
ですが、文字コードは色々な種類があると聞いたことがある・・・
では、文字コードについて少し確認してみましょう。
文字コードについて
ASCIIコードは、数字、アルファベット、記号を1バイトで表現
JISコードは、ASCIIコードに日本語(全角)を追加した文字コード
Shift_JISは、半角はJISコードのまま、全角文字をJISコードからシフトした文字コード
Unicodeは、符号化文字集合で、文字コードの国際的な業界標準
UTF-8,UTF-16は、Unicodeを実装した符号化方式です。
Windowsで作成したcsvなら、ほとんどがShit-JISでしよう。
メモ帳で保存時には、「ANSI」になります。
マクロでShift_JIS文字コードか判定する
BOM無しはUTF-8Nと言われたりします。
VBAでWEB関係のCSVを扱う時に必要となりますが、VBAでUTF-8を扱う場合はADODB.Streamを使います。
CSVの読み込み方法(改の改)
ビッグエンディアンとリトルエンディアンがあります。
メモ帳でも保存時の、
「Unicode」は、UTF-16のリトルエンディアン
「Unicode big endian」は、UTF-16のビッグエンディアン
上位側から順に並べ「30 42」とするのがビッグエンディアン、
下位側から「42 30」のように並べるのをリトルエンディアンと呼びます。
UTF-16のビッグエンディアンを、UTF-16BE
UTF-16のリトルエンディアンを、UTF-16LE
このように表記されたりします。
エンディアンの詳細について知りたい場合は別途検索してください、詳しく説明しているページが多数存在します。
つまり、先に掲載したローカルウインドウのaryByteの中身は、UTF-16LEだという事です。
ローカルウインドウでは、この文字コードが10進で表示されています。
VBEで使われているShift-JISとVBAで使われているUTF-16LEについて、
マクロVBAでByte配列と関数を使って少し詳しく見ていきます。
文字列をByte配列に入れて、文字列に戻す
Sub 文字列_Byte配列_文字列()
Dim aryByte() As Byte
aryByte = "Excelの神髄"
Dim str As String
str = aryByte
Debug.Print str
End Sub
このように、Byte配列は単純に文字列(String)に入れることができます。
VBAでは、暗黙の型変換が行われるので、
Debug.Print aryByte
これだけでも正しく元の文字列が表示されます。
文字列をByte配列に入れて、自力で文字列に戻す
何をしているのか、なんだかよく分かりません。
そこで、自力でByte配列を文字列に戻してみましょう。
Sub 文字列_Byte配列_自力文字列()
Dim aryByte() As Byte
aryByte = "Excelの神髄"
Dim str As String: str = ""
Dim i As Long
For i = 0 To UBound(aryByte) - 1 Step 2
str = str & ChrW(aryByte(i + 1) * 256& + aryByte(i))
Next
Debug.Print str
End Sub
VBAでは、UTF-16LEが使われています。
つまり、aryByteの中の順番は、
2バイト(1文字)ごとに、順番が入れ替わっています。
aryByte(0) aryByte(1)
これは、aryByte(1) aryByte(0)の順として文字コードを見る必要があります。
1バイトの数値は256なので、2バイトで1つの数値とするには、
aryByte(i + 1) * 256& + aryByte(i)
これで、2バイトの文字コードを10進に変換できることになります。
256&の&はLong型の型宣言文字になります。
この&がないと、オーバーフローが発生します。
aryByteも256も、どちらもInteger型なので、掛け算の結果もInteger型になってしまう為に発生します。
いずれかがLong型であれば結果もLongになるので、256&としています。
ChrW関数は、指定したUTF-16文字コードに対応する文字を返します。
文字列をSJISに変換してからByte配列にいれて、自力で文字列に戻す
Shift-JISのBYTE型に変換するには、StrConvのvbFromUnicodeを使います。
?StrConv("Excelの神髄", vbFromUnicode)
といれてEnterしてみると、
Shift-JISなら正しく表示されそうですが、、、
VBEはShift-JISですが、VBAはUTF-16LEです。
つまり、StrConvでShift-JISになっているものを、UTF-16LEとして判断されている為に文字化けしています。
StrConvでShift-JISになっているものを、UTF-16LEに戻してみましょう。
Sub 文字列_SJIS_Byte配列_自力文字列()
Dim aryByte() As Byte
aryByte = StrConv("Excelの神髄", vbFromUnicode)
Stop '←ここでローカルウインドウで確認
Dim str As String: str = ""
Dim i As Long: i = 0
Do
If (aryByte(i) >= 128 And aryByte(i) <= 159) Or _
(aryByte(i) >= 224 And aryByte(i) <= 255) Then
str = str & Chr(aryByte(i) * 256& + aryByte(i + 1))
i = i + 2
Else
str = str & Chr(aryByte(i))
i = i + 1
End If
If i > UBound(aryByte) Then Exit Do
Loop
Debug.Print str
End Sub
Stop時点でローカルウインドウでみてみると、
aryByte = "Excelの神髄"
とした時とは、配列の要素数が違うようです。
UTF-16LEでは、全て2バイトでしたが、
Shift-JISでは、半角は1バイト、全角は2バイトとなっています。
つまり、
(0)~(4)は半角文字で1バイトで1文字、
(5)~(10)は全角文字で2バイトで1文字ということです。
Shift-JISの半角が1バイトであることは、
VBAにおいて、文字列中の半角文字数の判定に使う事が出来ます。
Shift-JISの文字コードは、半角文字(1バイト)は以下のように割り当てられています。
下位4ビット | |||||||||||||||||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | ||
上 位 4 ビ ッ ト |
0 | NUL | SOH | STX | ETX | EOT | ENQ | ACK | BEL | BS | HT | LF | VT | FF | CR | SO | SI |
1 | DLE | DC1 | DC2 | DC3 | DC4 | NAK | SYN | ETB | CAN | EM | SUB | ESC | FS | GS | RS | US | |
2 | SP | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / | |
3 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? | |
4 | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | |
5 | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ | |
6 | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | |
7 | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | DEL | |
8 | |||||||||||||||||
9 | |||||||||||||||||
A | 。 | 「 | 」 | 、 | ・ | ヲ | ァ | ィ | ゥ | ェ | ォ | ャ | ュ | ョ | ッ | ||
B | ー | ア | イ | ウ | エ | オ | カ | キ | ク | ケ | コ | サ | シ | ス | セ | ソ | |
C | タ | チ | ツ | テ | ト | ナ | ニ | ヌ | ネ | ノ | ハ | ヒ | フ | ヘ | ホ | マ | |
D | ミ | ム | メ | モ | ヤ | ユ | ヨ | ラ | リ | ル | レ | ロ | ワ | ン | ゙ | ゚ | |
E | |||||||||||||||||
F |
つまり、最初の1バイトが上表の黄色部分なら全角文字だという事になります。
10進で表現した時は、128~159,224~255の範囲という事です。
この範囲の時は、次の1バイトと合わせて2バイトで全角1文字になるという事です。
最後に
ましてや、Windowsを使っているとUnicodeを意識することはほとんどないでしょう。
私も普段はほとんど意識することはありません。
従って、本記事もいろいろ確認しながら書いたものになります。
現在においては負の遺産と言っても良いかもしれません。
いずれ全く意識する必要がなくなる日が来るとは思います。
しかし現在はまだまだこれを考慮しなければならない場面も出てきますので、
IT知識の一端として紹介したものになります。
同じテーマ「マクロVBA技術解説」の記事
Excelアドインの作成と登録について
VBAでのタイマー処理(SetTimer,OnTime)
マクロでShift_JIS文字コードか判定する
Byte配列と文字コード関数について
Applicationを省略できるApplicationのメソッド・プロパティ一覧
PowerQueryの強力な機能をVBAから利用する方法
ShapesとDrawingObjectsの相違点と使い方
新規挿入可能なシート名の判定
VBAにおける配列やコレクションの起点について
VBAのマルチステートメント(複数のステートメントを同じ行に)
クリップボードに2次元配列を作成してシートに貼り付ける
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.条件分岐(Select Case)|VBA入門
10.ブック・シートの選択(Select,Activate)|VBA入門
- ホーム
- マクロVBA応用編
- マクロVBA技術解説
- Byte配列と文字コード関数について
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。