したいこと
ExcelでSJISを取得・表示したい
VBAでSJISの値を得たい
エクセルの関数では?
エクセルの関数では、CODE関数、UNICODE関数があります。
- CODE関数はJISのコード返します
- UNICODE関数 UTF16のコードを返します
これらは文字を入力して、コード(数字)を返す関数です。
こういう場合必要になるのが、10進数を16進数に変換する関数です。こちらはDEC2HEX()関数を用います。(10)は10進数表記、(HEX)は16進数表記です。
VBAの関数では?
VBAの関数では、Asc関数、AscW関数があります。
- Asc関数はSJISのコードを返します。
- AscW関数でUTF16のコードを返します。
これらは文字を入力して、コード(数字)を返す関数です。
ですが、使用に関して何点か注意点が、知っていれば問題ありませんが、
エクセル関数 vs VBA関数
エクセル関数とVBA関数がかなり違って混乱しました。
- CODE関数(エクセル)とAsc関数(VBA)が返すコードが異なる。(JIS vs SJIS)
- エクセル側にもASC関数(エクセル)があるが、VBAのAsc関数(VBA)とは機能が全く異なる。
VBAを本格的に触り始めて初めての件でしたが、これはかなり注意しないと。。
じゃあ、ExcelでSJISが欲しい場合は?
方法としては、JIS->SJISへの変換式や表が多数公開されてますので、
- 方法1. Excelのセル内にIf文で書く。
- 方法2. VBAで変換関数を,エクセルで作成・使用する。
- 方法3. ネットで調べる。
で対応可能かと思いますが、方法1. はありえない。VBAでやってみたいので、方法2.を採用します。方法3.では私はこちらを使用します。
VBAの変換関数を作成
これらの関数を使用して以下のようなソースコードで、変換関数を作成しました。1文字での使用を想定しています。4桁の文字にして、XXYYのXXとYYを別々に取り出します。そして、Asc_SJIS関数にて、XX*256+YYを出力します。
'****************************************************************** ' SJISのコード番号を取得します。 ' ( 通常のAsc関数では 漢字等の2バイト文字は) ' ( -32768 ~ 32767 で表現されるのでこのような工夫が必要。) '****************************************************************** Public Function Asc_SJIS(val) As Long Dim c1 As Long Dim c2 As Long c1 = GetFirstByteOfSJIS(val) c2 = GetSecondByteOfSJIS(val) Asc_SJIS = CLng(c1 * 256) + c2 End Function '****************************************************************** '2バイト文字の 1バイト目を取り出します '****************************************************************** Public Function GetFirstByteOfSJIS(val) As Long Dim high As Long Dim str As String str = Hex(Asc(val)) 'シフトJISコードの上位バイトを取り出します high = CLng("&h" & Mid(str, 1, 2)) GetFirstByteOfSJIS = high End Function '****************************************************************** '2バイト文字の 2バイト目を取り出します '****************************************************************** Public Function GetSecondByteOfSJIS(val) As Long Dim low As Long Dim str As String str = Hex(Asc(val)) 'シフトJISコードの下位バイトを取り出します low = CLng("&h" & Mid(str, 3, 2)) GetSecondByteOfSJIS = low End Function '******************************************************************' ' SJISのコード番号を文字列で取得します。 '****************************************************************** Public Function Asc_SJIS_Str(val) As String Asc_SJIS_Str = Hex(Asc_SJIS(val)) End Function '****************************************************************** ' Asc_SJIS_Str関数を登録します。 '(関数一覧のツールチップや、関数入力時のインテリセンスは、) '(ユーザー定義関数については表示することはできません。) ' 参考URL https://blogs.msdn.microsoft.com/office_client_development_support_blog/2017/11/21/udf-help/ '****************************************************************** Sub Register_Asc_SJIS_Str() Application.MacroOptions Macro:="Asc_SJIS_Str", _ Description:="引数の文字列のSJISコードを取得します", _ Category:="文字列操作", _ ArgumentDescriptions:=Array("引数 1 : 文字列"), _ HelpFile:="" End Sub
TDD(Ariawase)でテスト
AriawaseのClass_Test(コード)部分に以下のコードを追加して、テストを行っています。
テストコード
Sub Convert_SJIS変換テスト_Test() Call Assert.AreEqual("8E64", Hex(Asc("仕"))) Call Assert.AreEqual("8E", Hex(GetFirstByteOfSJIS("仕"))) Call Assert.AreEqual("64", Hex(GetSecondByteOfSJIS("仕"))) Call Assert.AreEqual("3B45", Hex(SJIS_To_JIS("仕"))) Call Assert.AreEqual("8E64", Asc_SJIS_Str("仕")) End Sub
テスト結果
“But was”が表示されていないので、成功です。
VBAの関数をエクセルから呼び出した結果
なぜ、あぶらそばでテストしたかはまた別途書くとして、得た結果としては満足をしています。
確認環境
下記の環境で動作確認しました。
- Windows 10
- Excelバージョン 1804 (ビルド9226.2126 クイック実行)
追記
こちらで使用するために作成しました。組み込み機器でもSJISが利用されていたりして、良い実例になりました。下記の記事のなかで使用したエクセルは関数名を変更しています。Asc_SJIS_StrをGet_SJIS_Strに変更。本記事も暇を見つけて改定する予定です。(2018.06.29)