今回は、文字列フィールドの中で、数値型のレコードだけ判定する方法を考えてみたいと思います。
例えば以下のようなデータを考えてみます。
この中でappleは完全に文字列ですが、それ以外は数値型として取り扱いたいデータです。一見してIs関数で抽出できそうですが、実は一筋縄では行きません。
よくやりがちな失敗パターン
例えば、関数リストを眺めていると、以下のような関数でできそうに思うかもしれません。
IsNumber(ToNumber([String]))
結果は以下のとおりです。
これは、ToNumber関数でStringフィールドを数値に変換するわけですが、IsNumber関数がデータの型を判定するため失敗します。つまり、「apple」はToNumber関数で数値型になりますが、値はNullとなります。その後、IsNumber関数がデータ型自体を判定するため、数値型ということになり、結論としてはTrueとして判定してしまうためです。
数値として判定する方法
3つご紹介します。2番目の方法は、Designer Cloudなどで有効に使えそうな方法です。
ToNumberを使った方法
IsNumberではフィールドの型自体を判断するとのことなので、それではToNumberで変換したときにNullになっているものあればIsNullで判定できないのか?ということでやってみましょう。
!IsNull(ToNumber([String]))
数値に変換してNullでなければ数値型という意味になります。結果は以下の通りで、思ったのと違う結果になっています。
なぜ「apple」がTrueになってしまうのか。これはToNumberで数値型に変換したときに、文字列は「0」という結果を出力するためです。ただし、「1,000」は数値として認識してくれています。
しかしこれ、よくよく見ると、いくつかオプションがあることがわかります。
bIgnoreErrors、keepNulls、decimalSeparetorというオプションがあることがわかります。ただ、fxボタンから関数をそのまま選択しても、これらのオプションは自動で挿入されません。
これらの意味は以下のとおりです。
- bIgnoreErrors
エラーを無視するようになるオプションです。デフォルトでは「情報を失いました」と表示が出るので意図的にやっているのであれば、Trueにした方が無駄な表示を消すことができます。
- keepNulls
数値に変換できない場合、False(デフォルト)では0を出力しますが、TrueにするとNullを出力するようになります。
- decimalSeparator
3桁区切り記号を指定できます。これを指定すれば、その記号は区切り記号として認識してくれ、正常に数値に変換できます。
つまり、
!IsNull(ToNumber([String],"True","True",","))
という関数で判定が可能になります。
これにより、以下のような結果が得られます。
セレクトツールで数値型に変換してからNullになっているかどうかで判定する方法
一度セレクトツールで数値型(Double)に変換してみると、文字列はNullになるためセレクトツールで変換後にIsNull関数でNullになっているかどうかで、文字列なのか数字なのかを判定することが可能です。3桁ごとの区切り文字がある場合は、これはセレクトツールでは文字列として判断してしまうため、あらかじめReplace関数で空白に置換しておくとこのようなものにも対応可能です。つまり、以下のようなワークフローになります。
※フォーミュラツール内はIsEmpty関数でもIsNull関数でも結果は同じです
最初のフォーミュラツール:
セレクトツール:
最後のフォーミュラツール:
これにより、以下のような結果になります。
正規表現で判定
例えば、以下のような正規表現式で表すことができます。
^[+\-]*[\d,]+\.*\d*$
これは、以下のような条件で判定しています。
- 行頭から行末まで数値であるかどうか
- 頭に(半角の)+、-の符号がついていてもOK
- 小数点があってもOK
- 小数点以降の数字があってもなくてもOK
- 3桁ごとの区切り記号があってもOK(ただし、正確に3桁ごとに区切られているかどうかは判定しておらず、区切り記号があってもOKとして判断)
ただし、「+,.」などはTrueとして返してしまいます。何を優先して判断したいか、で正規表現の内容を変えることができるので、色々工夫してみてください。もしくは、IF文などを使って少なくとも数字を含んでいないといけない、などの条件を別途付け加えることもできます。
なお、正規表現ツールを使う場合は、以下のような設定となります。
正規表現はシンプルに表現できますが、慣れていないと難しいため最初に紹介した複数ツールを組み合わせた方法の方が確実にワークフローを構築できる可能性があります。
ロケールの影響
ところで、ロケール(地域)によっては、このままでは失敗します。つまり、フランスを中心とした国々では、小数点を示すピリオドがカンマになっています。逆に、そのような国では3桁の区切り記号がピリオドになります。ですので、この方法は国によって若干のアレンジが必要になります。グローバルのデータを扱う場合はご注意ください。
まとめ
- 文字列フィールドから各レコードが数値かどうかを判断する方法をご紹介しました
- 方法としては、IsNull+ToNumber、セレクトツール+IsNull/IsEmptyで判断後結合ツールで結果を結合するか、正規表現を使う方法があることを紹介しました。
- ロケールにも注意してください(フランス式の場合はピリオドとカンマが入れ替わります)
サンプルワークフローダウンロード
次回
しばらく関数シリーズで行きたいと思います。
コメント