初心者のFileMaker pro Q&A (旧掲示板)

みんなに優しく、解りやすくをモットーに開設しています。 以下のルールを守りみんなで助け合いましょう。

1.ファイルメーカーで解らない事があればここで質問して下さい。 何方でも、ご質問・ご回答お願いします。 (優しく回答しましょう)

You are not logged in.

Announcement

新しい掲示板は、こちら:https://fm-aid.com/forum/t/filemaker


#1 2013-09-30 17:22:37

nani
Guest

ローカルなカスタム関数

FM11です。

ひとつの計算フィールド内で何度も必要な計算式があります。
カスタム関数で関数を作成できることはわかったのですが、他のフィールドでは使いません。
ふと思ったのですが、ひとつの計算フィールド内だけで使う関数を作成して
動かすようなことはできるのでしょうか。

Let ( [
A=Int ( フィールドA *.5 );
B=Int ( フィールドB *.6 );
C=Int ( フィールドC *.7 );
D=Int ( フィールドD *.8 );
E=Int ( フィールドE *.9 )];

Case ( Mod ( A ; 100 )<5; Truncate ( A ; -2 ); Truncate ( A ; -1 ))&"¶" &
Case ( Mod ( B ; 100 )<5; Truncate ( B ; -2 ); Truncate ( B ; -1 ))&"¶" &
Case ( Mod ( C ; 100 )<5; Truncate ( C ; -2 ); Truncate ( C ; -1 ))&"¶" &
Case ( Mod ( D ; 100 )<5; Truncate ( D ; -2 ); Truncate ( D ; -1 ))&"¶" &
Case ( Mod ( E ; 100 )<5; Truncate ( E ; -2 ); Truncate ( E ; -1 ))


)

#2 2013-09-30 19:55:08

wader
Member

Re: ローカルなカスタム関数

Let ( $f = "Case ( Mod ( $x ; 100 )<5; Truncate ( $x ; -2 ); Truncate ( $x ; -1 ))" ;
Let ( $x = A ; Evaluate ( $f ) )
)
のような話?

Offline

#3 2013-09-30 20:44:09

Hiro
Member

Re: ローカルなカスタム関数

説明良く分かってませんが、こんなこと?

Let([
 $係数=0.5;
 $関数="Let(
   [$項目=Int($フィールド*$係数);$係数=$係数+0.1];
   Case(Mod($項目;100)<5;Truncate($項目;-2);truncate($項目;-1))
  )"
];
 List(
  Let($フィールド=フィールドA;Evaluate($関数));
  Let($フィールド=フィールドB;Evaluate($関数));
  Let($フィールド=フィールドC;Evaluate($関数));
  Let($フィールド=フィールドD;Evaluate($関数))
 )
)

Last edited by Hiro (2013-09-30 20:45:26)

Offline

#4 2013-10-01 09:21:15

Shin
Member

Re: ローカルなカスタム関数

その前に、
Case ( Mod ( A ; 100 )<5; Truncate ( A ; -2 ); Truncate ( A ; -1 ) )
の意味を考えて悩んでいましたが、なんか全く意味の無い分岐のような気がします。
Case ( Div ( A ; 100 )<5; Truncate ( A ; -2 ); Truncate ( A ; -1 ) )
ならば少し意味があるのですが。

Offline

#5 2013-10-01 10:39:15

狐猫
Guest

Re: ローカルなカスタム関数

確かに、
00~04なら、00、それ以外ならx0
だから、前者は無用ですね。
Divにすると、500までは100刻みでそれ以上は10刻み、だから意味はある。どっちかというと、逆にした方が普通?

#6 2013-10-01 18:24:58

nani
Guest

Re: ローカルなカスタム関数

皆様ありがとうございます。
Truncateについては「1位を切り捨てた上で、50未満なら00」という条件ですので、下記のように変更しました。
Case ( right ( A ; 2 )<50; Truncate ( A ; -2 ); Truncate ( A ; -1 ) )

知りたいことは、同じ計算式を複数のフィールドに適用する、という方法なのですが、
私が例に出したものが複数の要素を含んでしまったために、Hiro様の例が理解できませんでした。すみません。。
実は(フィールドA *0.5~) は実際には0.1ずつ一定に増えるのではなく、全くバラバラなものです。
力があればHiro様のご提示いただいたものから理解できると思うのですが、ちょっとわかりません。
この場合はどうすればよいでしょうか。

Case ( right ( A ; 2 )<50; Truncate ( A ; -2 ); Truncate ( A ; -1 ) )&"¶" &
Case ( right ( B ; 2 )<50; Truncate ( B ; -2 ); Truncate ( B ; -1 ) )&"¶" &
Case ( right ( C ; 2 )<50; Truncate ( C ; -2 ); Truncate ( C ; -1 ) )&"¶" &
Case ( right ( D ; 2 )<50; Truncate ( D ; -2 ); Truncate ( D ; -1 ) )&"¶" &
Case ( right ( E ; 2 )<50; Truncate ( E ; -2 ); Truncate ( E ; -1 ) )

#7 2013-10-01 19:59:06

wader
Member

Re: ローカルなカスタム関数

関数定義の引数を$xにして、関数の呼び出しではLetで変数に渡すというのを書いたのですが、全部書かないとわかりませんかね。
Let ( $f = "Case ( right ( $x ; 2 )<50; Truncate ( $x ; -2 ); Truncate ( $x ; -1 ))" ;
Let ( $x = A ; Evaluate ( $f ) )&"¶" &
Let ( $x = B ; Evaluate ( $f ) )&"¶" &
Let ( $x = C ; Evaluate ( $f ) )&"¶" &
Let ( $x = D ; Evaluate ( $f ) )&"¶" &
Let ( $x = E ; Evaluate ( $f ) )
)

Offline

#8 2013-10-01 20:08:03

Hiro
Member

Re: ローカルなカスタム関数

こんなこと、かな?

Let([
 //$関数を定義 << $関数($値,$係数) >>
 $関数="Let(
  $項目=Int($値*$係数);
  Case(Right($項目;2)*1<50;Truncate($項目;-2);truncate($項目;-1))
  )"
];
 //定義関数適用計算式 << $値=引数値1、$係数=引数値2、関数実行=Evaluate($関数) >>
 List(
  Let([$値=フィールドA;$係数=0.5]; Evaluate($関数));
  Let([$値=フィールドB;$係数=0.6]; Evaluate($関数));
  Let([$値=フィールドC;$係数=0.7]; Evaluate($関数));
  Let([$値=フィールドD;$係数=0.8]; Evaluate($関数))
  )
)

Offline

#9 2013-10-02 10:47:45

nani
Guest

Re: ローカルなカスタム関数

waderさま、Hiroさま
おかげ様で Evaluateを使った方法を理解出来ました。
ありがとうございます。

もう1点よろしいでしょうか。
計算を重ねていきたい場合、どうすればよいでしょうか。
下記のようにNumToJTextを加えたいのですが、うまくいきません。
入れ子にすればいいのはわかっているのですが。。

Let ( [
$f = "Case ( right ( $x ; 2 )<50; Truncate ( $x ; -2 ); Truncate ( $x ; -1 ))" ;
$f = NumToJText ( $f  ; 1 ; 0 )
];
List(
Let ( $x = フィールドA ; Evaluate ( $f ) );
Let ( $x = フィールドB ; Evaluate ( $f ) );
Let ( $x = フィールドC ; Evaluate ( $f ) );
Let ( $x = フィールドD ; Evaluate ( $f ) )
  )
)

#10 2013-10-02 12:39:02

everest
Guest

Re: ローカルなカスタム関数

関数もどきの呼び出しが長ったらしくなるんで、入れ子にした方がいいと思いますけど。
別々に定義するとしたらそれぞれ別の変数にします。
Let ( [
$f1 = "Case ( right ( $x1 ; 2 )<50; Truncate ( $x1 ; -2 ); Truncate ( $x1 ; -1 ))" ;
$f = "NumToJText ( Let ( $x1 = $x ; Evaluate ( $f1 ) ) ; 1 ; 0 )"
];

#11 2013-10-02 13:12:57

Hiro
Member

Re: ローカルなカスタム関数

「Right($x;2)<50」は文字比較されるので、意図しない結果を得る場合も("6"<"50"が偽とか)?
明示的に数値比較「Right($x;2)*1<50」にしておくと安全でしょう。

Let ([
 $f=
   "Let([
    $x=Case(Right($x;2)*1<50;Truncate($x;-2);Truncate($x;-1))); 
    $x=NumToJText($x;1;0)
   ];
    $x
   )"
];
 List(
  Let($x=フィールドA;Evaluate($f));
  Let($x=フィールドB;Evaluate($f));
  Let($x=フィールドC;Evaluate($f));
  Let($x=フィールドD;Evaluate($f))
  )
)

Last edited by Hiro (2013-10-02 13:38:25)

Offline

#12 2013-10-02 13:49:30

everest
Guest

Re: ローカルなカスタム関数

なるほど。順番に呼び出すならLetで先に実行した方がすっきりしますね。
私の書き方は複数の関数もどきを定義する方法なので、どっちも呼び出せますが。

Rightの修正は、元々数値なので、最初のMod ( A ; 100 )の方が素直では。なんで変えたのかな。

#13 2013-10-02 14:35:53

nani
Guest

Re: ローカルなカスタム関数

everestさま、Hiroさま、
おかげさまでよくわかりました。
今後すっきりとした処理を考えるのが楽しくなりそうです。
本当にありがとうございました。

#14 2013-10-02 14:50:31

everest
Guest

Re: ローカルなカスタム関数

Evaluateを使うと計算が遅くなるということを書くの忘れてた。

#15 2013-10-02 15:17:22

Hiro
Member

Re: ローカルなカスタム関数

Evaluate再帰式で多量の繰り返しループ演算処理をやれせる場合とか以外、実用的に問題ないでしょう。

Offline

Registered users online in this topic: 0, guests: 1
[Bot] ClaudeBot

Board footer

Powered by FluxBB
Modified by Visman

[ Generated in 0.010 seconds, 9 queries executed - Memory usage: 587.49 KiB (Peak: 604.03 KiB) ]