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

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

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

You are not logged in.

Announcement

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


#1 2018-10-24 11:10:46

salon_hiyake
Member

連続する数字だけを、省略表記するカスタム関数

1
2
3
5
7
8

などの整数値が改行区切りでフィールドに入っています。
これを、

1―3
5
7―8

という風に、「連続する整数ならダッシュつなぎでまとめる、そうでなければ、単独の数値として表記する」としたくてカスタム関数を書いてみたのですが、うまくいきません。

以下のように、処理する部分に分けて、2つの関数を書いてみて、この2つを何らかの方法で組み合わせることで、できそうな気がするのですが、複雑になりすぎて組み合わせ方がわかりません。

どなたか、わかる方がいらっしゃったら、アドバイスをお願いします。


■書いてみた1つ目の関数、RenzokuNum(lst)
------------------------------------------------------
/*RenzokuNum() ひと続きの連続の数字をダッシュつなぎでまとめる(1回のみ、単独の数字は処理しない)*/

Let([
        $lst= SortValues ( lst ; 2 );        /*改行区切りのテキストを、数字としてソート縦郭*/
        $CR="¶";                            /*改行(関数内で、ダブルコーテーションをエスケープするのが面倒なので、変数に入れておく)*/
        $null="";
        $Dash="―";
        $i=0;
        $Itm = GetValue($lst; 1);                           /*現在の値*/
        $NextItm= GetValue($lst; 2);                        /*次の値*/
        $FirstItm = GetValue($lst; 1);                      /*n―mの開始値*/
        $LastItm=$null;                                     /*n―mの終了値*/
        $res="";
        $fnc="                                              /*$fnc開始*/
Case($NextItm - $Itm  ≠  1; $res;                          /*終了条件:現在の値と次の値の差が1でないなら終了*/
                   Let([
                         $i=$i+1;
                         $itm=GetValue($lst; $i);                        /*$i番目の値を取得*/
                         $NextItm=GetValue($lst; $i+1) ;                 /*$i+1番目の値を取得*/
                         $LastItm= $Itm  ;                               /* 終了値を更新*/
                         $res=$FirstItm & $Dash & $LastItm & $CR         /*ダッシュつなぎにして、改行を追加*/
                       ]; Evaluate($fnc))                                /*内側の$fnc計算*/
   )
"
   ];
  Evaluate($fnc)                                                         /*外側の$fnc計算*/
)
------------------------------------------------------
↑この関数は、

1
2
3
5
7
8

の入力を受け取ったとき、

1―3

のように、「最初の連続した数字をダッシュつなぎでまとめる」ことはできます。


■書いてみた2つ目の関数、StraightNum(lst)
------------------------------------------------------
/*StraightNum(lst)改行区切りの値全てをダッシュつなぎでまとめる(正常動作しない) */
Let([
        $lst= SortValues ( lst ; 2 );        /*改行区切りのテキストを、数字としてソート*/
        $CR="¶";                            /*改行(関数内で、ダブルコーテーションをエスケープするのが面倒なので、変数に入れておく)*/
        $null="";
        $Dash="―";
        $i=0;
        $Itm = GetValue($lst; 1);                                  /*現在の値*/
        $NextItm= GetValue($lst; 2);                               /*次の値*/
        $FirstItm = GetValue($lst; 1);                             /*n―mの開始値*/
        $LastItm=$null;                                            /*n―mの終了値*/
        $res="";
        $fnc="                                                     /*$fnc開始*/
             Case($i=ValueCount($lst); $res;                       /*Case文開始。終了条件:$iが値の数に達したら終了*/
                       Let(
                            [                                      /*内側のLet開始*/
                             $i=$i+1;
                             $itm=GetValue($lst; $i);              /*$i番目の値を取得*/
                             $NextItm=GetValue($lst; $i+1) ;       /*$i+1番目の値を取得*/
                             $FirstItm=If($FirstItm=$null  ; $itm ; $FirstItm) ;             /*$FirstItmがヌルなら取得しなおす。ヌルでなければそのまま*/
                             $LastItm=$itm ;
                             $res=Case( $NextItm -$itm ≠  1 ;                               /*連続した数(差が1でない)ときの条件と計算式*/
                                               Case($FirstItm =  $itm ; $res & $itm & $CR ;
                                                    $FirstItm ≠ $itm ; $res & $FirstItm & $Dash & $LastItm & $CR  )
                                           ;
                                           $NextItm -$itm  =  1 ; Let([ $LastItm = $null  ] ;  $res )                      /*連続した数(差が1)のとき(出力しない)の条件と計算式*/
                                           )
                           ]; Evaluate($fnc)
                           )                                       /*内側のLet終了、内側の$fnc計算*/
                   )                                               /*Case文終了*/
"                                             
  ];
   Evaluate($fnc)                                                  /*外側の$fnc計算*/
  )                                                                /*外側のLet終了*/
------------------------------------------------------

↑この関数は

1
2
3
5
7
8

の入力を受け取ったとき、

1―3
1―5
1―8

のように、「最初の開始値から、連続した数字をダッシュつなぎでまとめる」ことはできますが、2つ目以降の値の開始値が、最初に取得したもののままになってしまいます。

Offline

#2 2018-10-24 13:25:00

Hiro
Member

Re: 連続する数字だけを、省略表記するカスタム関数

一般関数による式例です。
(カスタム関数が必要なら、この式をベースにカスタム関数化ください)

Let([
   $prm=SortValues(リストフィールド; 2);
   $i=0;
   $res="";
   $fnc=
      "Case($i=ValueCount($prm); $res;
         Let([
            $i=$i+1;
            #pre=GetValue($prm;$i-1);
            #now=GetValue($prm;$i);
            #nxt=GetValue($prm;$i+1);
            #itm=
               Case(
                  #pre<>#now-1; #now;
                  #nxt<>#now+1; ""―"" & #now;
                  ""―""
                  );
            $res=List($res; #itm)
         ]; Evaluate($fnc) )
      )"
];
   Substitute(Evaluate($fnc); ["¶―";"―"];["――";"―"])
)

Offline

#3 2018-10-24 16:38:48

salon_hiyake
Member

Re: 連続する数字だけを、省略表記するカスタム関数

Hiroさん、早速のお返事ありがとうございます。こんなにシンプルに出来たんですね。
カスタム関数化もできました。
大変お世話になりました。

Offline

#4 2018-10-24 17:22:37

Shin
Member

Re: 連続する数字だけを、省略表記するカスタム関数

どこかで見た話題だと思っていたら、逆の話題だった。
「1-5」を「1/2/3/4/5」のように数字を分解することはできるでしょうか?
https://fm-aid.com/bbs2/viewtopic.php?id=6039

Offline

#5 2018-10-24 22:54:19

Hiro
Member

Re: 連続する数字だけを、省略表記するカスタム関数

【#2式の訂正報告】
すみません、>#2回答式にミスがありました。(時に重複した「ー」を取り切れない)
回答時忙しかったので、あまり検証せずアップしてました。
今落ち着いて検証し直したらやはりミスがありましたので、
訂正式を報告します。式はよりシンプルになりました。

Let([
   $prm=SortValues(リストフィールド; 2);
   $i=0;
   $res="";
   $fnc=
      "Case($i=ValueCount($prm); $res;
         Let([
            $i=$i+1;
            #pre=GetValue($prm;$i-1);
            #now=GetValue($prm;$i);
            #nxt=GetValue($prm;$i+1);
            #itm=
               Case(
                  #pre<>#now-1; #now;
                  #nxt<>#now+1; ""―"" & #now
               );
            $res=List($res; #itm)
         ]; Evaluate($fnc) )
      )"
];
   Substitute(Evaluate($fnc); ["¶―";"―"])
)

   
ただし、この式では重複データが無い事がデフォルト条件で、
ある場合、
   1
   2
   2
   2
   3
   5
  ↓
   1-2
   2
   2-3
   5
となります。

重複の可能性があり、結果を重複を取り除いた、
  ↓
   1--3
   5
を求めるなら、

Let([
   $prm=SortValues(リストフィールド; 2);
   $i=0;
   $res="";
   $fnc=
      "Case($i=ValueCount($prm); $res;
         Let([
            $i=$i+1;
            #pre=GetValue($prm;$i-1);
            #now=GetValue($prm;$i);
            #nxt=GetValue($prm;$i+1);
            #itm=
               Case(
                  #pre<>#now-1 and #pre<>#now; #now;
                  #nxt<>#now+1 and #nxt<>#now; ""―"" & #now
               );
            $res=List($res; #itm)
         ]; Evaluate($fnc) )
      )"
];
   Substitute(Evaluate($fnc); ["¶―";"―"])
)

Last edited by Hiro (2018-10-25 13:19:36)

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: 553.88 KiB (Peak: 574.78 KiB) ]