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

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

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

You are not logged in.

Announcement

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


#1 2015-07-02 11:10:28

norisu
Guest

フィールド内のテキストをloop処理する計算式はあるでしょうか?

バージョン13でウインドウズ版を使っています。

テキストフィールドに収められている文字列を整形して
別の計算フィールドに表示したいのですが、その内容がなんというか
ある程度フォーマットが決まっているものの、そうでない場合もあるんです。
そのような場合の計算式はあるでしょうか?


たとえば下記のようなフォーマットが基本形で
「作成者情報+(名前+住所+ペット)×複数個」 になっているのですが
例1
---------------------------------------------
作成:株式会社○○ 作成日2015/4/10 担当:山田
<名前:中村><住所:大阪><ペット:猫>
<名前:香川><住所:北海道><ペット:犬>
<名前:山下><住所:徳島><ペット:うさぎ>
---------------------------------------------

これを、
---------------------------------------------
名前:中村 ペット:猫 名前:香川 ペット:犬 名前:山下 ペット:うさぎ
---------------------------------------------
このように名前+ペット名にしたいのですが、
ただ、下記のような内容の場合もあるため
画一的な処理がしづらくて困っています


例2
---------------------------------------------
<名前:伊藤><ペット:猫>
<名前:織田><住所:北海道><出身:○○高校><ペット:犬>
<名前:山下><住所:徳島><ペット:>
<名前:織田><住所:><ペット:金魚・柴犬>



---------------------------------------------

こうしたい↓
---------------------------------------------
名前:伊藤 ペット:猫 名前:織田 ペット:犬 名前:山下 ペット:-なし- 名前:織田 ペット:金魚・柴犬 ・・・
---------------------------------------------

例1との違いは、下記の4点です
・作成者情報が無い場合もある
・名前、住所、ペット以外の情報が入り込む場合もある
・ペットがない場合もあり、無しということを表示したい
・名前がないことは無く、名前の重複は気にしない(同一名前でペットをまとめることはしない)


「名前+ペット+その他の情報」が出現する回数は不定で最大でも20回程度です
また、見やすいように改行を入れていますが、改行なしですべてつながっている状態のテキストデータです。
なにかヒントだけでもいただけないでしょうか・・・

#2 2015-07-02 16:23:30

calcer
Guest

Re: フィールド内のテキストをloop処理する計算式はあるでしょうか?

「<名前:」を探して<の次の文字から、次の>の前までを出力
その次の「<ペット:」を次の「<名前:」の前までから探して、同様に(無ければ「なし」)出力
それを繰り返す

#3 2015-07-02 16:47:06

qb_dp
Member

Re: フィールド内のテキストをloop処理する計算式はあるでしょうか?

スクリプト例:
変数を設定 [$val; 値:"<名前:織田><住所:北海道><出身:○○高校><ペット:犬>"]
変数を設定 [$val2; 値:Substitute ( $val ; ["<名前" ; "$名前"] ;["<" ; ";    $"] ;  [":" ; "=\""] ;  [">" ; "\""]  )]
変数を設定 [$Result; 値:Evaluate (  "LET(["  & $val2 &  "]; \"名前:\" & $名前 & \" ペット:\" & If ( IsEmpty ( $ペット ) ; \"-なし-\" ; $ペット ) )"  )]

上記のスクリプトで「名前:織田 ペット:犬」が取得できます。
この処理は、1件のみの処理です。


Substitute ( 元文字列 ; "<名前" ; "¶<名前")
で、1行1件になるようにし、
あとは、Loopで処理。

Offline

#4 2015-07-02 21:12:25

Hiro
Member

Re: フィールド内のテキストをloop処理する計算式はあるでしょうか?

ご希望通りループ計算式で一発算出する式例


Let([
   $lst=Substitute( テキストフィールド ;"<名前:";"¶<名前:");
   $pos=Position($lst;"<名前:";1;1);
   $lst=Middle($lst;$pos;Length($lst));
   $i=0;
   $res="";
   $fnc=
      "Case(
         $i=ValueCount($lst); $res;
         Let([
            $i=$i+1;
            $itm=GetValue($lst;$i);
            $p1=Position($itm;\"<名前:\";1;1);
               $p2=Position($itm;\">\";$p1;1);
                  $nm=Middle($itm;$p1+1;$p2-$p1-1);
            $p3=Position($itm;\"<ペット:\";1;1);
               $p4=Position($itm;\">\";$p3;1);
                  $pet=Middle($itm;$p3+1;$p4-$p3-1); $pet=$pet & Case($pet=\"ペット:\";\"なし\");
            $res=List($res;$nm;$pet)
         ];Evaluate($fnc))
      )"
];
   Substitute(Evaluate($fnc);¶;" ")
)

Offline

#5 2015-07-03 21:08:14

norisu
Guest

Re: フィールド内のテキストをloop処理する計算式はあるでしょうか?

みなさんありがとうございます
calserさんの概念をスクリプトにするとqb_dpさんのようになり、
それを計算フィールドで行うとHiroさんのやり方になるということでしょうか?
後学のためにHiroさんの計算式をスクリプトに置き換え直し、理解しようとしていますが

下から6行目の     $res=List($res;$nm;$pet)  と
上から9行目の    $i=ValueCount($lst); $res; の関係性がわかりません。
Listは異なるフィールドから値をもってくる関数ですよね・・?
$resは最初はNULL、
$nmは名前:○○、
$petはペット:○○、
それらを改行して$resに格納してまた8行目に戻り
テキストフィールドの改行区切りの値の個数が$resと同じでなければloop処理・・・?ということでしょうか? ←ここの理解が間違っていそうです

$resは最初はNULLで、一回目のloopが終わると 名前:○○(改行)ペット:○○ の2行になって まではわかるのですが
それとValueCount($lst)を使用してloop処理を続けるかどうか判断しているらしき部分が
なぜそうなるのでしょうか・・・?

#6 2015-07-04 00:25:22

Hiro
Member

Re: フィールド内のテキストをloop処理する計算式はあるでしょうか?

式の構造は、ループ・スクリプトの構成とほぼ同じです。

【スクリプトの場合】
・初期値や変数の登録  //式では、2行目から6行目までに相当
・Loop  //23行目のEvaluate($fnc)部分
・ もし設定条件を満たしたらループを抜け、結果を返す  //8、9行目の Case($i=ValueCount($lst); $res; それ以外の処理)
・ 未満は、変数と結果を更新してから  //10行目から19行目までに相当
・ ループ先頭へ戻る  //20行目の自己再帰 Evaluate($fnc)
・End Loop
・結果を書式編集して終了  //23行目の Substitute(Evaluate($fnc);¶;" ")

【再帰式の説明】
Let([
   $lst=Substitute( テキストフィールド ;"<名前:";"¶<名前:");  //1行書テキストを一覧リスト化して変数$lstに格納
   $pos=Position($lst;"<名前:";1;1);  //$lst一覧リストの最初の"<名前:"の出現位置を算出
   $lst=Middle($lst;$pos;Length($lst));  //$lst一覧リストから不用な「作成者情報」を削除して、再格納
   $i=0;  //変数$i リスト行番カウンタの初期値設定
   $res="";  //変数$res result結果の初期値設定
   $fnc=  //カスタム・ループ関数$fncを定義
      "Case(  //処理の条件分岐
         $i=ValueCount($lst); $res;  //ループ抜け条件を指定、現在の行番カウンタ$iが総リスト行数と同じなら、現在の結果$resを返して$fnc関数終了
         Let([  //以外の処理、ココから▼
            $i=$i+1;  //行番カウンタ$iを1カウントアップ更新
            $itm=GetValue($lst;$i);  //現在のカウンタ行番の項目内容を変数$itmに格納
            $p1=Position($itm;\"<名前:\";1;1);  //現在の項目で最初の「<名前:」の出現位置を算出
               $p2=Position($itm;\">\";$p1;1);  //現在の項目で「<名前:」以降最初の「>」出現位置を算出
                  $nm=Middle($itm;$p1+1;$p2-$p1-1);  //現在の項目から名前データを算出、変数$nmへ格納
            $p3=Position($itm;\"<ペット:\";1;1);  //現在の項目で最初の「<ペット:」の出現位置を算出
               $p4=Position($itm;\">\";$p3;1);  //現在の項目で「<ペット:」以降最初の「>」出現位置を算出
                  $pet=Middle($itm;$p3+1;$p4-$p3-1); $pet=$pet & Case($pet=\"ペット:\";\"なし\");  //現在の項目からペットデータを算出、次いで「なし」の場合の補正を追加して、変数$petへ格納
            $res=List($res;$nm;$pet)  //現在の項目から抽出した名前$nmとペット$petを既存結果$res一覧へ追加リスト、再格納
         ];Evaluate($fnc))  //最後に「Evaluate($fnc)」でカスタム関数$fncを最初から繰り返す、再帰計算します。 
      )"
];
   Substitute(Evaluate($fnc);¶;" ")  //「Evaluate($fnc)」でカスタム関数$fncをココで実行、結果は一覧リストなので改行をスペースに替える補正して完了
)

Offline

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

Board footer

Powered by FluxBB
Modified by Visman

[ Generated in 0.005 seconds, 7 queries executed - Memory usage: 541.05 KiB (Peak: 561.59 KiB) ]