■JRA-VANデータの読み込み方法 その2
前回は、JRA-VANデータをExcelに取り込んだときに、大きな問題が発生すると述べました。その問題とは「全角文字が含まれていると桁ずれを起こす」です。何故、桁ずれを起こすのかをまとめると以下の様になります。
【問題点】
- VBでは文字コードは全てUnicodeとして扱われる。
- Unicodeは1文字を2バイトとして扱う(半角英数字も)。
- VBの文字列操作命令は文字数で処理される(半角は1文字、全角も1文字として処理)。
- JRA-VANデータはバイト指定で定義されている。
- VBでも文字の取り扱い方法と、JRA-VANデータの文字取り扱い方法の相違点が問題。
JRA-VANデータが取り扱っている文字コードは、C言語やDelphi(Pascal)などで扱う場合は都合がよいのですが、VBでは文字列操作命令がバイト単位で指定できないため、どうしても桁ずれは免れません。1つ考えられる回避策としては、VB用にJRA-VANデータフォーマットを直すことでしょうか。でも、それでは効率も悪いし、永遠と1文字の違いに頭を抱えることになるでしょう。
■バイトデータとして処理する
VBの文字列操作命令で、バイト単位のデータが扱えないのであれば、はじめからバイトデータで取り扱えばよろしい。至極簡単な結論です。でも、具体的な突破口を見いだせずに文字列操作命令に戻ってしまう人が結構いるのではないでしょうか?
これからVBにおけるバイト操作のポイントを解説しますので、文字列操作命令のことは頭の隅に追いやって下さい。
【バイト操作の基本】
- バイト単位で扱う場合は、変数を文字列型(String)ではなく、バイト型(Byte)として宣言する。
- ファイルを読み込むときにもInputモードではなく、Binaryモードで開く。
- 1バイトは0〜255までの数値で表現される。半角英数字などは、ASCIIコード表に基づき変換する。
- 必要なバイト数のバイト型配列変数として格納する。
- 読み込むデータの位置は、配列変数の配列番号を指定する。
これだけです。こう書くと難しく感じるかも知れませんが、プログラムコードにすると意外にあっさりしています。
List1.JRA-VAN出馬表読み込み(バイトデータ)
Private Sub LoadDenma() Dim FN As Integer Dim Dt(1 To 1462) As Byte 'データを格納する領域(1462Byte)
FN=FreeFile 'ファイル番号取得
Open "JracDen1.dat" for Binary As #FN '出馬表読み込み(Binaryモード)
Do While (Not Eof(FN)) 'ファイルの終端まで読み込み
Get #FN, ,Dt() 'データ読み込み
Loop
Close #FN 'ファイルを閉じる
End Sub
|
以前にテキスト形式でデータを取り込んだ物との相違点は、OpenステートメントのモードがBinaryになっている点と、データの読み込みがGetステートメントになっている点です。上記の例だと、1462Bytesずつデータが読み込まれます。
尚、読み込んだバイトデータを取り出したい場合は、Dt(n)とすれば、nバイト目のデータが1バイト取り出せます。
■読み込んだバイトデータを文字列や数値に直す
バイトデータは0〜255までの数値で表現されます。これはPC内部メモリのデータの形式であり、そのままでは人間が読みとることは出来ません(20年くらい前のパソコン利用者の中には、このバイト文字列から意味のある命令に変換できる強者がいましたが…笑)。意味のある文字列や数字とは、0〜9までの数字、A〜Zまでの文字など、通常我々が使う文字のことです。バイトデータはASCII文字コード表などを利用して、人間が分かる文字に変換しなければなりません。
バイトデータを1つ1つASCIIコード表で変換していくのは手間が掛かります。そこで、Chr()関数を使います。Chr()関数はASCIIコードを意味のある文字に変換してくれます。ただし、変換できるのは1文字ずつであるため、1つ1つ変換する必要があります。
半角英数字を変換するには以下の様に行います。
List2.Asciiコードを文字に変更する
Dim szTxt as String,i as Long
szTxt="" '変数を初期化する
For i=1 to 8
szTxt=szTxt+Chr(Dt(i)) 'ASCIIコードを文字に変換
Next
|
List2のプログラムは、バイトデータの1〜8バイト目までをASCIIコードから文字に変換し、文字列変数szTxtに格納しています。
この方法でJRA-VANデータのほとんどのデータが利用可能となりますが、全角文字を含むレース名や馬名などを処理することは出来ません。ASCIIコード表を見ても分かりますが、0〜127までしか利用されていないうえ、この中には日本語文字列が確認できません。そこで、全角漢字を扱う場合には、別の変換方法を利用する必要があります。
■全角文字列に変換する
全角文字に変換したい場合は、レース名や馬名に相当するバイトデータを別のバイトデータに格納し、VBで使われているUnicodeに変換する必要があります。
【変換手順】
- 別のバイト型配列変数に、必要なデータを切り出す
- StrConv()関数を使い、バイトデータをUnicodeに変換する
- 文字列に含まれる不要なゴミを削除する
では、実際にやってみましょう。
List3.ASCIIコードを全角文字列に変換
Dim szTxt as String '全角文字を格納する文字列変数 Dim Tmp(1 To 28) as Byte '変換用作業領域(28byte) Dim i as Long
For i=1 To 28
Tmp(i)=Dt(i+20) 'JRA-VANデータの必要な部分をTmp()変数に切り出す
Next
szTxt=StrConv(Tmp(),vbUnicode) 'バイトデータをUnicodeに変換
If Instr(szTxt,Chr(0))>0 Then
szTxt=Left$(szTxt,Instr(szTxt,Chr(0))) '不要なゴミを取り除く
End If
|
ここでポイントとなるのは、StrConv()関数です。この関数の詳しい説明はVBAのヘルプに譲りますが、入力されたデータを所定の文字コード、大文字小文字などに変換するための物です。
また、バイトデータの場合、何もデータの含まれていないところはNull文字になってしまいます。NullはASCIIコード0番のことで、C言語ではデータの区切りなどに利用されていますが、VBでは利用されていないのでその部分にゴミがつきます。
【まとめ】 |
今回はより実践的なテクニックを中心に解説しました。中には初めて聞く言葉ばかりで知恵熱を出している方がおられるかも知れませんね(笑)。最後にまとめを書きますので、サンプルコードを動かしながら少しずつ理解を深めて下さい。おまけとして、シンプルぱっとで使っている、JRA-VANの出馬表の読み込み関数を添付します。こちらを利用してみて下さい。
- 全角文字が含まれるデータは、バイト文字で読み込むと桁ずれを起こさない
- バイトデータとして読み込む場合は、Binaryモードで読み込む
- 読み込んだバイトデータはASCIIコードになる
- バイトデータから半角英数字に変換する場合はChr()関数を使う
- バイトデータから全角文字に変換する倍は、StrConv()関数を使う
|
|