2025/04/11

入力チェック:全角/半角の判定と Nomad

Nomad は、Notes クライアントで使用していたアプリケーションをそのまま利用できることが特徴で、労せずモバイル対応できてしまう素晴らしいシステムです。

とはいっても、プラットフォームが違うわけですから、再現率は 100% ではありません。画面サイズや縦横比の違い、Excel  に帳票を出力するなど Windows の機能を利用するアプリなど一部に制約があります。

今回紹介する現象は、もっと細かな話になります。私の思慮が足りなかっただけといえばそれまでですが、全く想定していなかったことなので紹介いたします。


発生した現象

一部のアプリケーションで入力された文字の全角/半角チェックをする機能がありました。その判定ロジックは、Len で文字数を取得、LenBP でその文字列のバイト数を取得、文字数 = バイト数なら半角、文字数 x 2 = バイト数なら全角と判定していました。

判定のための関数は次の通りなのですが、これが Nomad で正常に動作しなかったのです。

◇ すべて半角文字かチェック

Public Function IsZenkaku(ByVal vsTarget As String) As Boolean
   Dim iLen As Integer
   Dim iLenBP As Integer

   iLen = Len(vsTarget)
   iLenBP = LenBP(vsTarget)
   If (iLen * 2) = iLenbp Then
      '文字数の 2 倍がバイト数(= すべて全角文字)
      IsZenkaku = True
   Else
      '文字数の 2 倍がバイト数ではない(= 半角文字が混入)
      IsZenkaku = False
   End If
End Function

◇ すべて全角文字かチェック

Public Function IsHankaku(ByVal vsTarget As String) As Boolean
   Dim iLen As Integer
   Dim iLenBP As Integer

   iLen = Len(vsTarget)
   iLenBP = LenBP(vsTarget)

   If iLen = iLenbp Then
      '文字数とバイト数が同じ(= すべての文字が半角)
      IsHankaku = True
   Else
      '文字数とバイト数が違う(= 全角文字が混入)
      IsHankaku = False
   End If
End Function


文字列の長さ

LotusScript で文字列の長さを取得する関数には Len、LenB、LenBP の 3 種類があります。デザイナーヘルプをまとめると次のような機能です。

関数 機能
Len 文字列の文字数
LenB 文字列の長さを示すバイト数
LenBP 文字列の長さを示すバイト数(プラットフォーム固有の文字セット)

簡単なテストフォームを作成し、それぞれの関数の挙動をチェックします。

結果は次の通りでした。この結果すぐに気が付きました。全角や半角カナが 3 バイトとなっているので、Nomad iOS は Unicode で動作していると思われます。

文字 ノーツ(Windows) Nomad iOS
Len LenB LenBP Len LenB LenBP
(全角) 1 2 2 1 2 3
A(半角英字) 1 2 1 1 2 1
(半角カナ) 1 2 1 1 2 3

LenB 関数はどういった機能を提供してくれているのか今一つ理解できませんが、Len 系の関数だけで全角/半角の判定は難しそうです。


対策

◇ すべて半角文字かチェック

半角から全角文字の変更は必ずできます。全ての文字が全角であるかチェックするには、これを利用すれば簡単です。文字列を全角に変換して、元の文字列と一致するか確認するだけです。変化があれば半角文字が混ざっていたということですね。

Public Function IsZenkaku(ByVal vsTarget As String) As Boolean
   Dim sZen As string
   Dim v As Variant

   v = Evaluate(|@Wide("| & vsTarget & |")|)    '半角から全角に変換
   sZen = v(0)

   If sZen = vsTarget Then
      '全角に変換しても変化がないのですべて全角文字
      IsZenkaku = True
   Else
      '全角に変換すると変化したので半角文字が混入
      IsZenkaku = False
   End If
End Function

◇ すべて全角文字かチェック

全て半角であるかについては少し厄介です。漢字など半角に変換できない文字があるからです。まず、全角/半角変換の関係を整理します。

チェックする文字 半角に変換 全角に変換 備考
(全角) (全角) (全角) 半角にできない全角
(全角) A(半角) (全角) 半角にできる全角
(半角) (半角) (全角) 半角にしても変化なし

この関係を利用して関数を作成します。1 文字ずつ上表に当てはめて判定します。1 文字でも全角文字を発見したら、判定を終了し False 返しています。

Public Function IsHankaku(ByVal vsTarget As String) As Boolean
   Dim sSrc As String
   Dim sHan As String
   Dim sZen As String
   Dim v As Variant
   Dim i As Integer

   IsHankaku = True
   '1 文字ずつ確認
   For i = 1 To Len(vsTarget)
      sSrc = Mid(vsTarget, i, 1)
      '全角から半角に変換
      v = Evaluate(|@Narrow("| & sSrc & |")|)
      sHan = v(0)
      '半角から全角に変換
      v = Evaluate(|@Wide("| & sSrc & |")|)
      sZen = v(0)

      If sSrc = sHan And sSrc = sZen Then
         '全角(半角にできない全角文字)
         IsHankaku = False
         Exit For
      ElseIf sSrc <> sHan And sSrc = sZen Then
         '全角(半角に変換できる全角文字)
         IsHankaku = False
         Exit For
      Else
         '半角(全角でなく、半角に変換しても変化しない)
         '→ 処理を継続して次の文字をチェック
      End If
   Next
End Function


おわりに

今回は、全角/半角のチェックを例に Nomad 利用時に発生した課題を紹介しました。

私は長年 Notes クライアント用のアプリばかりを作っています。Web 化や XPages 化も詳しくありません。Windows アプリばかりだったせいもあり、文字コードには無頓着だったということですね。Nomad ≒ Notes クライアントではあるのですが、ところどころ落とし穴があるので注意が必要です。

ところで、紹介したコードでは、全角/半角の変換に Evaluate 関数を介た@関数を利用していますが、これには理由があります。LotusScript の関数 StrConv はノーツクライアントと Nomad 環境で結果が変わり、判定に使用できなかったからです。この点も Nomad 運用時には注意が必要です。

Notes は複数の言語をサポートしており、開発の自由度も高いです。歴史が長いこと幅が広いことで混乱することもありますが、探せば回避策が見つかるところはありがたいといえます。宝さがしみたいで面白いですね。


0 件のコメント:

コメントを投稿