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

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

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

You are not logged in.

Announcement

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


#1 2017-11-20 19:37:24

やまほん
Member

正規表現とevaluate??

win7,ad14です。

久々に壁にぶち当たり、丸2日悩みましたがお手上げです。

フィールドAに、改行区切りのテキストが入っています。
行数は1~10行程度で固定ではありません。

例えば、フィールドAに

みかんバナナ
いちご
さくらんぼ
いちじく
バナナ
メロン
メロンレモン
みかんいちじくバナナ
パイナップルグレープフルーツ

と入っているとします。
求めたい結果は フィールドBに

みかん
いちご
さくらんぼ
いちじく
バナナ
メロン
レモン
パイナップルグレープフルーツ

です。

同じ文字列が他の行の文字列にあればその重複文字のみを削除したいのです。
使われている文字列のリストなどはありません。
(上の例ではわかりやすく単語にしているだけです)
LOOP的な処理として考えたのですが、処理の順番として、

1行目の"みかんバナナ"は、ほかの行には重複しないので変化なし。
2行目の"いちご",3行目の"さくらんぼ"も同様。
4行目の"いちじく"は8行目の"みかんいちじくバナナ"の"いちじく"を削除し"みかんバナナ"に。
5行目の"バナナ"は1行目を"みかん"、8行目を"みかん"に。
6行目の"メロン"は7行目を"レモン"に。
7行目は"レモン"になったが他の行に重複なしで他の行は変化なし。
8行目は"みかん"になったので、1行目のみかんと重複するが、上の行を優先して8行目の""みかん"削除で、この行は無くなる。
9行目は他に重複なしなので、他の行の変化なし。

いろいろ調べた結果、式で求めるには正規表現とevaluateで再帰式の組み合わせなのかと思い、
http://manual-mailmakerpop.joy-h.com/ma … expressionプラグインを使わせていただきましたが、行き詰まりました。
ここまで複雑だと一発の式で求めるのは無理でしょうか。

レコード数は1万程度ありまして、最終的にフィールドAとフィールドBを確認して手動での訂正もしますが、
少しでも処理させられるところまで出来ればあとの手間が省けるのでなんとかしたいのですが。
お知恵をいただければ・・・。
よろしくお願いします。

Last edited by やまほん (2017-11-20 19:43:48)

Offline

#2 2017-11-20 22:52:50

Shin
Member

Re: 正規表現とevaluate??

テキストを、1行1レコードのテーブルへ変換します。
1行毎に、そのテキスト内容が同じならばそのまま、内包されていれば Substitute() で文字列を削除する全置換を行い、loop で全行を処理。
テキスト内容の重複検索を行い、最終行を削除、を検索結果が無くなるまで繰り返す、
という2段階の処理で良いでしょう。最後に、適当に元のテキストフィールドに書き戻します。
https://www.dropbox.com/s/adh4kt14swwa3 … 7.zip?dl=0

この処理を再帰式にまとめれば良いのでしょうが、2重の再帰にすれば、何とかなるかも。

Last edited by Shin (2017-11-20 22:55:22)

Offline

#3 2017-11-21 04:49:57

Hiro
Member

Re: 正規表現とevaluate??

3重入れ子を含め4連立のループ式で何とかできますネ。

Let([
   $lst=フィールドA;
   $n=ValueCount($lst);
   $h=0;
   #dmy=Evaluate( Substitute(10^$n-1; 9; "Let([$h=$h+1;$itm[$h]=GetValue($lst;$h)];\"\") &") & "\"\"" );
   $i=0;
   $fnc=
      "Case($i=$n; $lst;
         Let([
            $i=$i+1;
            $key=$itm[$i];
            $j=0;
            $r=\"\";
            $lst=Evaluate($sub)
         ]; Evaluate($fnc))
      )";
   $sub=
      "Case($j=$n; $lst;
         Let([
            $j=$j+1;
            $itm[$j]=Case($key<>$itm[$j]; Substitute($itm[$j];[$key;\"\"]); $itm[$j]);
            $lst=Let([$k=0;$r=\"\"; $f=\"Case($k=$n;$r;Let([$k=$k+1; $r=List($r;$itm[$k])];Evaluate($f)))\"];Evaluate($f));
            $itm[$j]=Case(ValueCount(FilterValues($lst;$itm[$j]))=1;$itm[$j])
         ]; Evaluate($sub))
      )"
];
   Evaluate($fnc)
)


※ 全てのレコードに適用するのは、この計算値で「フィールド内容の全置換」するのが良いでしょう。

Last edited by Hiro (2017-11-21 11:07:22)

Offline

#4 2017-11-21 09:04:37

やまほん
Member

Re: 正規表現とevaluate??

その後、スクリプトを使った形で自分で試行錯誤してやってました。
基本的な考え方はShinさんのものと同じですが、別テーブルを使う方法は思い浮かばず、
スクリプトの中で(変数だらけになりましたが)なんとか処理できました。
私のスクリプトは複雑すぎて、Shinさんの方法はスクリプトがシンプルでなるほど!と思いました。ありがとうございます。

Hiroさん、私も多重ループでスクリプトを作ったのでそれを式に置き換えられる知識があればいいのですが、、、
なにぶんこういった複雑な数式に弱くて・・・。
じっくり紐解きながら勉強させていただきます。

お二方の案、自分のつたないスクリプトでも求めることができましたので解決とさせていただきます。
サンプル等ありがとうございました!

Offline

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

Board footer

Powered by FluxBB
Modified by Visman

[ Generated in 0.007 seconds, 7 queries executed - Memory usage: 515.45 KiB (Peak: 520.36 KiB) ]