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

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

診断(3)
ユーザー入力のデータに全角と半角の数字が混在して困る

「ゲール君,ついにやったぞ!」
「どうしたんですか先生。そんなに興奮して」
「これが興奮せずにおられるか」
「新薬の開発にでも成功したんですか?」
「何を言っておるゲール君。新薬なんぞ,腹の足しにならん」
「じゃあどうしたんですか?」
「年無しじゃよ,苦節15年。ついに52センチのチヌを釣り上げたんじゃ」
「美味しそう…じゃあ,今夜は鍋ですね」
「いや,そうではなくて,大きさじゃよ。50センチ・オーバーのチヌ。男のロマンじゃよ」
「はいはい,大きいですね。次の方,どーぞー」

今月の相談
「インプットボックスを使って,ユーザーに住所を入力させています。番地などの数字に半角と全角が混在すると,表が見づらくなるので,半角で入力するように注意書きをしているのですが,さっぱり効果がありません。全角の数字を拒否するような対策はないでしょうか?」(図1

図1●ユーザーに入力を求めるインプットボックス
図1●ユーザーに入力を求めるインプットボックス

「ん~…」
「先生,どうしたんですか?」
「インプットボックスには2種類ある。InputBox関数ではダメじゃが,InputBoxメソッド(Application.InputBox)ならTypeオプションで,ある程度入力するデータを制御できる。しかし,全角数字の制限は…」

 Application.InputBoxでは,Typeオプションで入力するデータを制御できます(リスト1)。


myRES = Application.InputBox("性別を選んでください" & _
  Chr(13) & "1 女" & _
  Chr(13) & "2 男" _
  , "性別", Type:=1)
リスト1●入力を文字列に制限するInputBoxメソッドの使用例

 例えば,Typeオプションに「1」を指定すると,数値以外のデータを受け付けません。また,Typeオプションに「8」を指定すると,ユーザーが選択したセルの絶対アドレスを取得できます(表1)。

表1●nputBoxメソッドのTypeオプションに指定する値とその意味
意味
0数式
1数値
2文字列 (テキスト)
4論理値 (True または False)
8セル参照 (Range オブジェクト)
16#N/A などのエラー値
64数値配列

「そうかぁ,さすがの先生もグリコ(お手上げ)なんですね」
「な,なにを言うか…そうじゃ!逆転の発想じゃ!」
「逆転の発想?」
「うむ,入力で制限できないのなら,入力された全角の数字を半角にしてしまえばよい」

 ユーザーに入力をさせるプログラムでは,必ずしも開発者が意図した通りのデータを入力してくれるとは限りません。想定外のデータが入力された場合は,エラー・メッセージを表示して正しいデータの入力を促すのが一般的です(図2)。しかし,プログラムで対処できるのであれば,それがベストです。

図2●対象外のデータが入力された場合はエラー・メッセージを出すのが一般的
図2●対象外のデータが入力された場合はエラー・メッセージを出すのが一般的

 今回のケースは,StrConv関数で問題を解決できます。これは,指定した方法で文字列を変換する関数です。入力を制限するのではなく,入力されたデータの全角の数字を半角に変換すれば,ユーザーに二度手間をかけることもなく,データも希望通りになります。

 リスト2を見てください。(1)でユーザーにデータの入力を要求するインプットボックスを表示します。Typeオプションに「3」を指定しているので,文字列型のデータを要求します。数値が入力された場合は,それを文字(数字)として受け入れます。ユーザーがセルを選択した場合,インプットボックスには,そのセルの代入式が表示され,戻り値は選択したセルの値になります。


Sub JYUUSYO_IN()
  Dim myRES As String

  myRES = Application.InputBox("住所を入力してください", _
    "住所", Type:=3)

  Select Case myRES
    Case ""
    Case "False"
    Case Else
      ActiveCell.Value = StrConv(myRES, vbNarrow)
  End Select
End Sub
リスト2●全角の数字を半角に変換してセルに代入するマクロ

 ユーザーが何も入力しないで[OK]ボタンをクリックした場合,戻り値は文字数ゼロの文字列となります。この場合は,(2)のステートメントで何もしないでマクロを終了します。

 [キャンセル]ボタンをクリックした場合,戻り値は「False」になります。したがって,(3)の分岐条件にとび,やはり何もしないでマクロを終了します。

 (2)(3)以外の場合,つまり,何らかのデータが入力された場合は,(4)の分岐条件に合致し,(5)を実行します。具体的には,入力された文字列データのうち,(半角のキャラクタが存在する)全角のキャラクタを半角に置換して,アクティブセルに代入します。その際,数字だけでなく,アルファベットや記号も半角に置換されます。これにより,セルに代入される数字は半角に統一されます。

 このほかにもStrConv関数は,第2引数(conversion引数)を選択することで,いろいろな変換ができます(表2)。例えば,ふりがなをカタカナに統一したい場合は「vbKatakana」を,ひらがなに統一したい場合は「vbHiragana」を指定するとよいでしょう。「いろいろな変換.xls」で体験してください(図3)。

表2●StrConv関数のconversion引数に指定する値とその意味
引数 意味
vbHiragana ひらがなに変換
vbKatakana カタカナに変換
vbLowerCase 小文字に変換
vbNarrow 半角(1バイト文字)に変換
vbProperCase 先頭の1文字だけ大文字に変換
vbUpperCase 大文字に変換
vbWide 全角(2バイト文字)に変換

図3●いろいろな変換を試せるマクロの画面
図3●いろいろな変換を試せるマクロの画面

 すでに,入力されたデータを半角変換するのであれば,リスト3のようなマクロを作ればよいでしょう。


Sub HENKAN()
  Dim R As Range

  For Each R In Selection
    R.Offset(0, 1).Value = StrConv(R.Value, vbNarrow)
  Next R

  Set R = Nothing
End Sub
リスト3●全角を半角に変換してセルに代入するマクロ

 このマクロは,選択されたセルの値を取得し,全角のキャラクタを半角に変換して隣のセルに代入します。

 なお,Excelのバージョン(古いもの)によって,StrConv関数が実装されていないものがあります。その代わりに,UCase(小文字を大文字に変換)やLCase(大文字を小文字に変換)といった文字列変換の関数がありました。これらは現在のバージョンでも,互換性を保つために実装されていますが,StrConv関数がある以上,いずれサポートは終わると思います。今後のために,大文字小文字の変換をしたい場合でも,なるべくStrConv関数を使うようにしましょう。

「どうじゃな,ゲール君。解決したじゃろ?」
「先生,お見事です。逆転の発想かぁ,なるほど。これは,先生を操るのにも使えそうですね」
「なんじゃと?」
「先生,今日はどんどん仕事して早く終わらせた方がいいですよ。タバコ屋のミーちゃんが今夜は暇だって言ってました」
「本当? 次の方,ど~ぞ~!!」