DoF Tableのユーザフィードバックで得た貴重な学びを備忘録。「とりあえず英語対応しておけば欧米ユーザの多くは使えるだろう」と思っていたのだけれど、少し甘かった。というのも、iPhoneの数値入力用キーボードレイアウト(UIKeyboardTypeDecimalPad; 電卓のように数字を入力するのに適している)で入力可能な文字は言語圏によって違うことに気付いていなかった。
DoF Tableの被写界深度の詳細計算画面では各パラメータを数値で直接入力できる。そこで入力すべきは距離等の数値なので、入力しやすいよう前述の数値入力用キーボードを表示させるよう設定している。さて、ここでの入力結果を解釈する処理ではロケールを意図的に指定せず、常にピリオドを小数点区切りとする処理にしていた。というのも日本語でも英語でも数値表記はピリオド区切りで同じだから。日本語と英語だけを対応言語としている以上、何も問題は無いと思い込んでいた。
しかし、iPhoneのドイツ語キーボード(の数値入力用レイアウト)では、日本語や英語のそれでいうところの「ピリオド」のキーが「カンマ」になっている…そりゃあそうだ、ドイツ語では小数点をカンマで区切るのだから。そしてiPhoneではキーボードのレイアウトとアプリの言語設定は独立している(例:英語限定のアプリで日本語キーボードを使って文字入力できる)。なので、ドイツ語にiPhoneを設定しているユーザがDoF Tableの入力欄にアクセスすると、「ピリオドの無い」ドイツ語用の数値入力キーボードが表示される。したがって、ドイツ語圏のユーザはDoF Tableで小数点を入力できない状況になっていた。もちろん、この話はドイツ語に限った話ではなく、小数点区切りがピリオドでない言語圏すべてで問題になってくる。
さて、どうしようかな。もちろん各国語にちゃんと対応するのが最善だけれど、自分は日本語と英語しか使えないし。翻訳発注するのも手だけれど。しかし、インチ・フィート表記で小数点区切りがカンマになったりすることはあるのだろうか?ていうか桁区切りが「’」(アポストロフィ)なロケールでインチ・フィート表記はムリだよなぁ…。
いずれにせよ、あるべき姿をキチンと考えてから対応を進めないといけないと思う。
業務の合間にプログラムを書いている、素人です。
5年ほど前に、英語版のプログラムを公開していたら、ドイツ人の方からメールがあり、何を言われているのかわからなかったのですが、2、3回やり取りしているうちに、小数点記号としてドイツではカンマ(,)を使っていることが分かりました。そこで、英語版のプログラムで小数点記号がカンマでもOKのバージョンを作り、それを利用してもらっていました。ところが、英語版で2つのバージョンが必要になりますし、最近ポルトガル語系の人も利用するようになったので、1つのバージョンで対応できないかと考え、次のようなことをしました。これで、日本語版のWindowsでロケールをポルトガル語にしても、日本語にしても同じ処理をしてくれるようになりました。
プロの方から見て、いかがでしょうか。
プログラム言語は、素人なので、ExcelのVBAです。
入力データから数値を取り出すために、数値から構成される文字列sujiを定義しました。
VBAのVal関数は、カンマを数値の一部と解釈しません。
(VBAのヘルプより) Val 関数は、ピリオド (.) だけを有効な小数点の記号として認識します。
文字列中に数字以外の文字が見つかると、Val 関数は読み込みを中止します。円記号 (\) やカンマ (,) など、通常は数値の一部とみなされる記号や文字も、Val 関数は数値として解釈しません。ただし、Val 関数は基数を示すプリフィックス &O (8 進数) や &H (16 進数) は認識します。
以上です。
失礼します。
OISHIさん
こんばんは。
コード中の”2.3″は、実際にはユーザが入力した文字列になる…という理解で良いでしょうか?その前提でコメントさせていただきますね。
考え方的には、ユーザ環境のロケールを見て判断するのではなくユーザ入力値を見て判断している点に少し懸念を感じました。具体例を挙げますと、ドイツ語圏では小数点区切り記号がカンマであると同時に桁区切り記号がピリオドになりますので、ドイツ語圏のユーザが「1.000」(10^3)などと書いた場合、「1」と解釈してしまう恐れがあるのでは、と思いました。入力データが1000を超えることは無い、あるいは桁区切り記号の入力は禁止されている、という話であれば何も問題は無いのですが、そうでなければ対策した方が良いかもしれません。
対策としては、Val関数の代わりにCDbl関数やCInt関数などを使えるようであれば、それが一番早いかと思います。これらの関数はVal関数と異なり、ユーザのロケールに応じて小数点記号などを切り替えてくれる(らしい)ので。もしCDblやCIntで代替不可であれば、話がややこしくなります。というのも、ある数値を表した文字列があったとき、それだけを見て小数点区切り記号と桁区切り記号をプログラム的に判別することは不可能だからです。ユーザのロケールを知らなくては判別できませんから、面倒(らしい)な手順でロケール情報を取得して、現在のユーザ向けの適切な小数点区切り記号を得て使うことになります。ただ、正直なところ「そこまでやるか」感があります。
個人的には、CDblやCIntで代替できるならそれで対策するのが良いと思います。代替不可であれば、実装は現在のままにして「桁区切り記号は禁止」の制限事項を付ける、あたりが良い落としどころかなと思います。
一意見ですが、ご参考になれば幸いです。
丁寧なコメント、ありがとうございました。
私の書き方がまずかったために、たいへん余計な手間をお掛けしてしまいました。
実は、”2.3″は私が書いたコードの一部です。Yamamotoさんにコメントの前提を誤解させてしまいました。
示したコードの1行目のif文は、利用しているOSのロケールが「小数点記号がピリオドであるロケール」か、「小数点記号がカンマであるロケール」かを判定する文です。ピリオドであれば、Trueになります。Val関数は、ロケールが何であれ、同じ振る舞いをして、たとえば英語でも独語でも”2.3″なら2.3を返し、”2,3″なら2を返します。投稿で引用したVBAのヘルプにそう書いてあり、テストしてもそうでした。WindowsAPIを利用すればロケールは分かるだろうけど、ロケール情報だけでは、そのロケールの小数点記号が何であるかは分かりませんし、またAPIの利用は面倒ですので、利用しませんでした。
suji=”0123456789./” や suji=”0123456789./” の部分を
Locale_eng=True や Locale_eng=False にして投稿すれば誤解を招かなかったかもしれないと反省しています。
そして、次のようなコードをお示しすれば、良かったと思います
(VBAはVisualBasic6相当の古い言語のせいか) Valのような振る舞いをする関数があり、それを利用してロケールの分類ができました、という報告をして、それで良いのかをプロの方に診てもらおうと思い、投稿させてもらった次第です。
お騒がせしました。
OISHIさん、
山本です。返信が遅くなってしまい申し訳ありません。
すみません、一行目のコードの意味を読み違えていました…。
したがってピリオド区切りで記載した実数の文字列(たとえば”2.3″)をVal関数で実数に変換し、& 演算子で文字列に戻した場合、もし実行環境ロケールの小数点区切りがピリオドであれば「元通りになる」…この原理で小数点区切り記号を判定しているのですね。なるほど、原理的にも確実な動作が期待されますし、何も問題は無いと思います。
なお、
Val("2.3")
とする代わりに2.3
と実数リテラルを書いても良いかもしれません。というのも、Val関数に固定の文字列値を指定した結果は環境に依らず一定…つまり事実上「定数」であるからです。自分の環境(Office 365のMac版Excel)で次のようなIf文を書いてみたところ:実行環境ロケールにおける小数点区切りがピリオドであるかどうかを正しく判定できました。ご参考になれば幸いです。
Yamamotoさま
再度のコメントをありがとうございます。
自分の文章が理解してもらえ、ホッとしました。
その上、&演算子の仕様と、なお書きのコード例まで教えてくださり、ありがとうございます。
試しに、WindowsのLocaleを日本語とポルトガル語にして、次のコードをVBAで実行させました。
—-
MsgBox (“” & 2.3)
—-
見事に、日本語 2.3 、ポルトガル語 2,3 と表示されました。
これを使えば小数点記号の判別がより簡潔にできます。
ありがとうございました。