古庄 潤(ふるしょう じゅん)

本業はエンジニア。ICに様々な機械をつなぎ,電流やら電圧を測定する。もちろん,これらの測定器もVBAでコントロールし,取り込んだデータもマクロで処理する。人呼んで、マクロの鬼軍曹!。

診断(2)
メッセージボックスの文字列を改行する

「先生,起きてください!」
「一富士,二鷹,三茄子,四扇,五煙草…むにゃむにゃ」
「先生っ,もう,起きてください!!」
「ん~」
「初夢に縁起がいいものを唱えながら寝たんですか?」
「そうなんじゃ,おかげでスゴい夢を見たぞ」
「どんな夢だったんですか?」
「それは,内緒じゃ」
「…。次の方,どーぞー」

今月の相談
「メッセージボックスに表示する文字列を複数行に分けたいのですが,どうしてもできません。文字列の途中でEnterキーを押したり,Alt+Enterを試してみたんですが,無駄でした。もともと,無理なんでしょうか?」(図1

図1●文字列を改行していないメッセージボックス
図1●文字列を改行していないメッセージボックス

「ふむ,これは文字列に制御コードを埋め込めば可能じゃ。このようになる」(図2

図2●文字列を改行したメッセージボックス
図2●文字列を改行したメッセージボックス

「先生,前回にも出てきましたけど,制御コードってなんですか?」
「うむ,制御コードと言うのは,キャラクタの一部で特殊な働きをするものじゃ」
「キャラクタ?」
「そう,画面に表示される文字や記号を総称してキャラクタと呼ぶんじゃ。コンピュータは,人間と違って文字は認識できん。したがって,すべての文字や記号に番号(文字コード)が振り分けられておる。文字コードにもいろいろあるが,代表的なものにASCIIコード(アスキーコード)がある。ASCIIコードでは,例えば,大文字の『A』は65番(10進コード。以下同じ),数字の『0』は48番,大文字の『O』は79番という具合に番号が割り当てられている。見分けがつきにくい『0』(数字)と『O』(英字)もこの番号で見れば一目瞭然じゃ」
「なるほど。じゃあ,漢字やひらがな,かたかなもそうなんですか?」
「おぉ,ゲール君,鋭いじゃないか。じっくり説明しよう」

 ASCIIコードは,1文字を7ビットで表す文字コード体系です(実際には最上位ビットを0にした8ビット=1バイトで取り扱われます)。7ビットですから,128種類のキャラクタしか表現できません。したがって,ASCIIコードが割り当てられているのはアルファベットと記号などで,数千種類もある漢字などに割り当てることは無理なのです。

 そこで,日本規格協会は,日本工業規格でJISコードを定めました。これが日本語用の文字コードです。初期のパーソナルコンピュータ(以後PC)では,この文字セットを漢字ROMで実装していたので,日本製のPCは,ソフトもデータも,海外のPCと互換性はありませんでした。

 やがて,ハードウエアが高速化し,文字コードを画面に表示できるデータに変換する作業がソフトウエアで実現可能なレベルに達すると,DOS/Vマシン(DOSの進化形であるDOS/Vを搭載したPC)が出現し,海外性のPCでも日本製のOSをインストールすれば,日本語PCとして使えるようになりました。このころのDOSやWindowsでは,米Microsoft社が開発したシフトJISコードが使われていました。

「へぇ~,文字コードも進化しているんですね」
「そうじゃ,DOS/Vマシンが出現して,同じPCが様々な国で使えるようになったのじゃが,国によって文字は様々。その国独自の文字コードも相変わらず存在する。そこで考え出されたのがUnicode。これは,元々は2バイト(16ビット)のコードを使って,世界中の文字を表現しようと考えたもの。だから,日本語のPCでも,文字フォント・セットさえインストールすれば,中国語やアラビア語のデータが表示できるんじゃ」
「で,肝心の制御コードは?」
「おぉ,そうじゃった。ちょいと横道にそれたな」

 先に説明したASCIIコードに話を戻します。ASCIIコードの一部には,見えない(表示されない)キャラクタがあります(図3)。これらは一般にハードやソフトの制御に使われるため,制御コードと呼びます。

図3●ASCIIコード表
図3●ASCIIコード表
[画像のクリックで拡大表示]

 例えば,10番(LF:ラインフィード)と13番(CR:キャリッジリターン)は,改行コードとして使われることが多いです。この二つは,もともとタイプライタ用の制御コードで,LFはロールを1行分回転させる,CRはロールを右に移動して印字する位置を紙の左端にする役割を持っていました。

 ちなみに,ExcelのセルでAlt+Enterキーを押した場合,LFが入力されます。もう一つ余談ですが,RS-232CやGPIBといった制御系通信インタフェースを使うプロトコルでは,LFやCRをデリミネータ(通信文の最後を示すキャラクタ)として使っています。

「なるほど,で,その制御コードはどうやって入力するんですか?」
「うむ,Chr関数を使って入力するんじゃ」

 リスト1のERRHANDLER_1を見てください。メッセージボックスのプロンプト(メッセージボックスに表示する文字列)に,Chr関数を使って制御コードCRを埋め込みます。これによって,文字列は改行され,複数の行に分かれて表示されます。


Sub FILE_OPEN()
  Dim myPATH As String
  Dim myFILE_NAME As String
  Dim myFILE_NAME_FULL As String
  Dim myBOOK As Workbook
  Dim myRESS As Integer

  myPATH = "C:\DATA\"
  myFILE_NAME = "Overall_Sales.XLS"
  myFILE_NAME_FULL = myPATH & myFILE_NAME

  On Error GoTo ERRHANDLER_1
    Set myBOOK = Workbooks.Open(myFILE_NAME_FULL)
  On Error GoTo 0

  ' 中略

  myBOOK.Close SaveChanges:=False

Exit Sub
ERRHANDLER_1:
  myRESS = MsgBox("フォルダ「" & myPATH & "」に ファイル「" _
    & myFILE_NAME & "」がありません。" _
    & Chr(13) _
    & "自分でファイルを探しますか", vbYesNo + vbQuestion)

  If myRESS = vbYes Then
    myFILE_NAME_FULL = Application.GetOpenFilename
    If Not myFILE_NAME_FULL = "False" Then
      Resume
    End If
  End If

  MsgBox "処理を中断します", vbInformation
End Sub
リスト1●あるプロシジャのエラー処理(ERRHANDLER_1)で,メッセージボックスの文字列を改行して表示している

「先生,ASCIIコードにあるキャラクタは表で調べるとして,漢字とかのコードも表があるんですか?」
「そうじゃな,コード表はもちろんあるが,数が多いので探すのは大変じゃ。Asc関数を使うと,それを調べることができる。こんな具合じゃ」

 リスト2は,Asc関数を使って文字コードを表示するプロシジャです。インプットボックスにコードを調べたい文字や記号を入力して[OK]ボタンをクリックすると,メッセージボックスにコードが表示されます。


Sub VIEW_ASCII_CODE()
  Dim mySTR As String
  Dim myMSG As String
  Dim i As Integer

  mySTR = InputBox("文字コードに変換する文字を入力してください")

  For i = 1 To Len(mySTR)
    myMSG = myMSG & Asc(Mid(mySTR, i, 1)) & Space(2)
  Next i

  myMSG = RTrim(myMSG)

  MsgBox myMSG
End Sub
リスト2●文字コードを表示するプロシジャ

「コードを調べる場合,数字やアルファベット,記号のように半角と全角の両方が存在するキャラクタは注意しなければならん」
「なるほど,同じ『A』でも,半角は65番,全角は-3216番なんですね」
「そうじゃ。文字列処理において,全角と半角の両方が存在するキャラクタの処理はちょいと複雑になる。それについては,また次回じゃな」