第67回 論理式

おはようございます。こんにちは。こんばんは。
エヌ・ケイ・カスタマイズの泉です。

季節は「秋」です。
子供と公園や川に行くと、草むらから虫たちの鳴き声が聞こえてきます。
自宅で育てている多肉植物(エケベリア)も紅葉しはじめました。
近年、秋でも暑い日が続いていましたが、今年はかなり涼しく過ごせており、
久しぶりに、秋を実感している今日このごろです。

論理式

前回、オブジェクトの非表示に使用した計算式は、

タスク管理::期限 ≧ Get ( 日付 )

でした。
上記計算式の結果で、表示/非表示をFileMakerが判断していますが、どのようにして判断しているのでしょうか?

フィールドタイプにはありませんが、計算式には 論理式 という概念があります。

真(True)か偽(False)のどちらかが結果として返る式です。この結果は数値で、

・真(True):1
・偽(False):0

となり、上記計算式では

・期限が日付と同じか大きい(期限を過ぎていない) → 真(True)は 1 → 非表示
・期限が日付より小さい(期限を過ぎている) → 偽(False)は 0 → 表示

ということになります。「真/偽」の結果を利用してなにかを判断するために使います。
そして、論理式を書く場合は、特にデータタイプに気をつける必要があります。

データタイプと論理式

文字列( テキストタイプの値) を比較演算子で評価した論理式の結果は、
少しあいまいな評価の結果が返ることに注意してください。
比較演算子では文字列の大文字と小文字を区別しません。

以下の計算式は結果に 1(真) を返します。

"A" = "a"

大文字と小文字を区別して比較するにはExact 関数を使います。

Extract ( テキスト ; 比較テキスト )

以下の計算式は結果に 0(偽) を返します。

Extract ( "A" ; "a" )

また、数値や日付、タイムスタンプタイプを比較演算子で評価する場合、フィールド値を利用するのであれば、
その計算式に必要なフィールドタイプ(数値や日付、タイムスタンプ)が設定されていないと正しい結果になりません。
例えば、以下の計算式はどちらも 0(偽) を返します。

NG例① : 2018/5/2 < 2018/5/11
NG例② : ”2018/5/2″ < “2018/5/11”

5 月2 日より5 月11 日の方が後の日付だから 1(真) のはずなのですがなぜでしょう。

理由は 例①は 数値 として、例②は 文字列 として評価されているから です。

例①の場合、”/” が年月日の区切り文字ではなく、演算子の除算(割り算)として計算されます。

2018/5/2 < 2018/5/11
↓
201.8 < 36.6909090909090909

∴ 結果:0(偽)

例②の場合、テキストタイプのフィールドで数字の入った文字列を昇順ソートした結果と同じように、
文字列の大小を最初の文字( 一番左の文字) から順に、1文字ずつ比較して「1」よりも「2」の方が後になったという論理です。

"2018/5" < "2018/5" → 結果:0(偽)

[理由] "2018/5" = "2018/5" だから


"2018/5/2" < "2018/5/1" → 結果:0(偽)

[理由] 文字列を昇順ソートした場合、"2018/5/2" より "2018/5/1" が上に位置する
つまり "2018/5/2" > "2018/5/1" 

実際に、「データビューア」で確認してみましょう。

これは文字列での例ですが、計算式にフィールドを使用している場合も同じです。
フィールドタイプがテキストだったり、式に直接「2018/5/17」のように入力するには、
日付やタイムスタンプは次のような書き方をします。

GetAsDate ( テキスト )
↓日付の正しい比較例①:

GetAsDate ( "2018/5/7" ) < GetAsDate ( "2018/5/11" ) → 結果:1(真)

テキストで記述したデータをGetAsDate 関数で日付タイプに変換して比較しています。
5 月11日の方が後、つまり「大きい」のでこの式は1(真)です。
以下の書き方でも同じ結果になります。

↓日付の正しい比較例②:

Date ( 5 ; 7 ; 2018 ) < Date ( 5 ; 11 ; 2018 ) → 結果:1(真)

次の例は「売上日」フィールドの日付と消費税率の施行日を比較した結果の
論理値に従って消費税率を返します。

If ( 条件式 ; 結果1 ; 結果2 )

↓計算式の例

If ( 売上日 < Date ( 4 ; 1 ; 2014 ) ; 0.05 ; 0.08)

まとめ

「条件分岐と言えば論理値」、「論理値と言えば条件分岐」と言えるくらい、
スクリプトを作るなら、論理値を導き出す計算式は頻出します。

頻出するが故に、『あれ?なんで思ったとおりの結果にならないの?』という場面も頻発します。
人間が見ると計算式はあっているのですが、コンピュータ(プログラム)はそううまくいかないことが多いです。

「2021/9/15」

上の文字列を見たとき、何を意味していると思いましたか?
おそらく「日付の文字列だ」と判断したのではないでしょうか?
では、次の文字列はどうでしょう?

「2021/2/29」

「これも日付の文字列だ」と判断したのではないでしょうか?
「2021年の2月に29日はないよ」と速攻で気づいた方はすごいです!!
そうなんです。
2021年2月29日は存在しないので、この文字列は「日付の文字列」ではありません。

何が言いたいかと言うと、計算式で論理値を導き出す時は、人間の脳で考えていることを
「具体的に正確に」計算式に落とし込む必要があります。
日付の比較がしたいのか、数値の比較がしたいのか、といったことを計算式に反映させなければ、
思ったような結果が得られませんので、注意してください。

ところで、『真偽』というキーワードがでてきたとき、数学を思い出しませんでしたか?
ちょっと調べてみたところ、「数学Ⅰ」の「命題の真偽」で学んでいました。
どんな内容だったか、気になった方は、検索してみていはいかがでしょうか?
私は検索しました!!
「命題」「逆・裏・対偶」まで調べました!!

それでは、また次回の更新をお楽しみに!!

Follow me!