数値項目の通貨書式と円記号の扱い
数値項目の書式を「通貨」(Format = "C")にすると、編集画面の入力欄には ¥57,000 のように円記号と桁区切りの付いた値が入ります。保存するときはサーバーがこの文字列から円記号を取り除いて数値に戻します。
1.5.1.0 でこの処理が書き換えられ、実行環境によっては入力欄の値を触らずに保存すると 0 になる不具合がありました。1.5.3.0 で修正されています。
円記号の 3 種類
見た目は似ていても、コードポイントの違う文字が混ざります。
| 文字 | コードポイント | 名前 |
|---|---|---|
¥ | U+00A5 | 半角の円記号 |
¥ | U+FFE5 | 全角の円記号 |
\ | U+005C | バックスラッシュ(日本語のフォントでは円記号に見えることがある) |
表示から保存までの流れ
入力欄に入る値
書式が「通貨」か「桁区切り」、または読み取り専用のとき、入力欄には書式を付けた値が入ります(Num.cs)。書式付けは言語ごとの通貨用カルチャ(日本語なら ja-JP)で ToString("C" + 小数点以下桁数) を呼び、日本語のときは結果の ¥(U+FFE5)を ¥(U+00A5)に置き換えます(Column.cs、Context.cs)。そのため、入力欄の円記号は常に半角の ¥(U+00A5)です。
保存時の変換(1.5.8.1)
Num のコンストラクタは、言語ごとの通貨用カルチャで文字列を数値に変換します(Num.cs)。変換の前に NormalizeYenSymbol が、先頭(マイナスの直後も含む)の \・¥・¥ を、そのカルチャの通貨記号に置き換えます。カルチャの通貨記号が ¥ でも ¥ でもない言語では何もしません(Strings.cs、Types.cs)。
図を読み込み中…
カルチャの通貨記号に揃えてから NumberStyles.Any で解析するので、半角・全角・バックスラッシュのどれで入力しても数値に戻ります。
1.5.1.0 〜 1.5.2.0 の不具合 1.5.1.0 〜 1.5.2.0
症状
書式を「通貨」にした数値項目で、入力欄に自動で入った ¥57,000 をそのまま保存すると、値が 0 になります。円記号を手で消してから保存すると正しく保存されます。
原因
| 版 | 円記号の処理 | ¥57,000(U+00A5)の結果 |
|---|---|---|
| 1.5.0.0 | 先頭の \(U+005C)と ¥(U+00A5)を取り除いてから解析する | 57,000 → 57000 |
| 1.5.1.0 〜 1.5.2.0 | NormalizeYenSymbol が先頭の \ と ¥ を ¥(U+00A5)に置き換え、¥ はそのまま残して解析する | 解析に失敗 → 0 |
| 1.5.3.0 以降 | 先頭の \・¥・¥ をカルチャの通貨記号に置き換えて解析する | 57000 |
1.5.1.0 の NormalizeYenSymbol は ¥(U+00A5)を「正しい形」として残します(Strings.cs(1.5.1.0))。一方で解析に使う ja-JP のカルチャの通貨記号は、ICU を使う .NET の環境(Linux など)では ¥(U+FFE5)です。入力欄に入る ¥(U+00A5)と一致しないので解析に失敗し、0 が保存されます。通貨記号が ¥(U+00A5)の環境では起きません。
Nullable(空欄を許可)の数値項目では、事前の解析に失敗した時点で値を設定せずに戻ります。
1.5.3.0 のリリースで「プリザンターの実行環境によって、通貨記号を含む数値型の値が更新時に 0 にリセットされてしまう問題を解消」として修正されました(e58aa58)。
1.5.1.0 〜 1.5.2.0 での回避
- 書式を「通貨」以外(標準や桁区切り)にする。
- 1.5.3.0 以降に上げる。
ブラウザ側の入力チェック
1.5.1.0 から、数値の入力チェック(c_num・c_min_num・c_max_num)は $p.parseCurrencyString で言語ごとの形式を見るようになりました(validator.js)。日本語・中国語では次の形を受け付けます(validator.js)。
| 入力 | 結果 |
|---|---|
¥57,000・¥57,000・\57,000・57,000 | 通る(57000) |
-¥57,000 | 通る(-57000) |
¥-57,000(円記号のあとにマイナス) | 通らない |
$57,000 | 通らない(日本語では $ を受け付けない) |
1,,000・1,000,・.5 | 通らない |
1.5.0.0 までのチェックは正規表現 /^(-)?(¥|\\|\$)?[\d,.]+$/ で、全角の ¥ を受け付けず、$ は受け付けていました。
関連ページ
- バージョンアップ
- 日付項目の入力モードと表示形式の拡張(設計)(数値項目のカスタム書式の仕組み)