初心者のFileMaker pro Q&A

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

1.ファイルメーカーで解らない事があればここで質問して下さい。

何方でも、ご質問・ご回答お願いします。 (優しく回答しましょう)

ログインしていません。

アナウンス


#1 2019-08-08 20:14:38

Valon
メンバー

[解決] 組み合わせで足りないレコードを補完

お世話になっております。
環境:Win10 FM18

List_A   List_B
りんご    赤
みかん    青
ばなな

Combination関数で6となります。

テーブルには、
レコード1 りんご   赤
レコード2 みかん   赤
レコード3 ばなな   青

この3レコードしかない場合、足りない3つを補完しております。

現在は1つ1つの組み合わせを変数とグローバルフィールドを使ったリレーション等で見ておりますが
List数が増えるとそれなりの時間がかかってしまいます。長いと30秒ぐらいです。

こちらを短縮する方法を模索しておりますが思いつきません。
とにかくスピード重視で何かございませんでしょうか?

全て変数で処理、もしくは足りないレコードが瞬時に分かればまだ早くできるような気がするのですが。
MBSプラグインが入っていますのでそちらを使った方法でも大丈夫です。

よろしくお願いいたします。

オフライン

#2 2019-08-08 22:48:05

koeda
メンバー

Re: [解決] 組み合わせで足りないレコードを補完

「足りないレコードを調べて補完する」というロジックはどうして必要になるのですか?

補完によって結局全ての組み合わせのレコードを作成するのであれば、
List_AもしくはList_Bにアイテムが追加されたタイミングで補完すれば、
いちいち足りないレコードを調べる必要はないように思うのですが?

オフライン

#3 2019-08-09 00:45:42

Shin
メンバー

Re: [解決] 組み合わせで足りないレコードを補完

0から作るなら、どちらかをグローバルの繰り返しフィールドにしておいて、目的のテーブルからインポートすればすぐです。
そこから既存のものを削除する処理をすれば早いでしょうね。

オフライン

#4 2019-08-09 01:11:20

Hiro
メンバー

Re: [解決] 組み合わせで足りないレコードを補完

先ずは レコード補完のための「補完リストを取得」する計算式例です、
(※他の設定が一切不用の計算式だけによる方法で、簡便かつ敏速です!)

【計算手順】
1.「全組合せリスト」を計算
   りんご:赤
   りんご:青
   みかん:赤
   みかん:青
   ばなな:赤
   ばなな:青
2.「既存レコードの組合せリスト」を取得
   りんご:赤
   みかん:赤
   ばなな:青
3. 1.と2.から「目的の補完リスト」を計算取得
   りんご:青
   みかん:青
   ばなな:赤


++++++++++++++++++++
Let([

   //1. 全組合せリストを変数 $prm[1]へ書き出す(入れ子の2段ループ式)
   $lst1=List_Aフィールド;
   $lst2=List_Bフィールド;
   $i=0;
   $res="";
   $FNC=
      "Case($i=ValueCount($lst1); $res;
         Let([
            $i=$i+1;
            $itm=GetValue($lst1;$i);
            $j=0;
            $cmb=\"\";
            $res=List($res; Evaluate($SUB))
         ]; Evaluate($FNC))
      )";
   $SUB=
      "Case($j=ValueCount($lst2); $cmb;
         Let([
            $j=$j+1;
            #cmb=$itm & \":\" & GetValue($lst2;$j);
            $cmb=List($cmb; #cmb)
            ]; Evaluate($SUB))
      )";
   $prm[1]=Evaluate($FNC);

   //2. 既存の組合せリストを変数 $prm[2]へ書き出す
   $prm[2]=
      ExecuteSQL("SELECT \"品名\",\"色名\" FROM \"テーブル名\""; ":"; ¶)
];

   //3. ※「逆FilterValues関数式」で目的の補完リストを算出
   Let([
      $prm[1]=¶ & $prm[1] & ¶;
      $prm[2]="[\"\¶" & Substitute($prm[2]; [¶; "\¶\";\"\¶\"];[\"\¶"]) & "\¶\";\"\¶\"]";
      $prm[2]="Substitute($prm[1];" & $prm[2] & ")";
      $res=Evaluate($prm[2]);
      $res="\"" & Substitute($res;[¶;"\";\""]) & "\";\"\"";
      $res="List(" & $res & ")"
   ];
      Evaluate($res)
   )

)

編集者 Hiro (2019-08-09 01:27:37)

オフライン

#5 2019-08-09 11:34:38

Valon
メンバー

Re: [解決] 組み合わせで足りないレコードを補完

koeda様
ありがとうございます。
深夜にサーバーに補完させておく手も考えましたが、他の要素も絡んでいましてこちらは断念しました。

Shin様
ありがとうございます。
こちらのList_A、List_Bの元は多大なレコード数のフィールドから引っ張っている一部データであり
Listをグローバルの繰り返しフィールド化するのは難しいように思いました。
(私の知識不足なだけかもしれません。)


Hiro様
ありがとうございます。
テストしてみたところ、非常に近しいところまで来ました。

長いのですが、下記のようになっています。

■既存レコード
識別子  品名  色名
1000  りんご  BLUE
1000  みかん  BLUE
1000  ばなな  BLUE
1000  りんご  GREEN
1000  みかん  GREEN
1000  ばなな  GREEN
1000  りんご  GRY
1000  みかん  GRY
1000  ばなな  GRY
1000  りんご  NAVY
1000  みかん  NAVY
1000  ばなな  NAVY
1000  りんご  PINK
1000  みかん  PINK
1000  ばなな  PINK
1000  りんご  WHITE
1000  みかん  WHITE
1000  ばなな  WHITE
1000  すいか  NAVY

組み合わせが5足りない。

--------

■計算式
Let前に変数を設定 [$Number ; 値: 識別子]

Let([

   //1. 全組合せリストを変数 $prm[1]へ書き出す(入れ子の2段ループ式)
   $lst1=ValueListItemsで品名抽出;
   $lst2=ValueListItemsで色名抽出;
   追記 $Number = $Number
   $i=0;
   $res="";
   $FNC=
      "Case($i=ValueCount($lst1); $res;
         Let([
            $i=$i+1;
            $itm=GetValue($lst1;$i);
            $j=0;
            $cmb=\"\";
            $res=List($res; Evaluate($SUB))
         ]; Evaluate($FNC))
      )";
   $SUB=
      "Case($j=ValueCount($lst2); $cmb;
         Let([
            $j=$j+1;
            #cmb=$itm & \":\" & GetValue($lst2;$j);
            $cmb=List($cmb; #cmb)
            ]; Evaluate($SUB))
      )";
   $prm[1]=Evaluate($FNC);

   //2. 既存の組合せリストを変数 $prm[2]へ書き出す
   $prm[2]=
      ExecuteSQL("SELECT \"品名\",\"色名\" FROM \"テーブル名\" WHERE \"" & $Number & "\" = ? "; ":"; ¶)
];

   //3. ※「逆FilterValues関数式」で目的の補完リストを算出
   Let([
      $prm[1]=¶ & $prm[1] & ¶;
      $prm[2]="[\"\¶" & Substitute($prm[2]; [¶; "\¶\";\"\¶\"];[\"\¶"]) & "\¶\";\"\¶\"]";
      $prm[2]="Substitute($prm[1];" & $prm[2] & ")";
      $res=Evaluate($prm[2]);
      $res="\"" & Substitute($res;[¶;"\";\""]) & "\";\"\"";
      $res="List(" & $res & ")"
   ];
      Evaluate($res)
   )

)

------

・Letの結果
24通りの組み合わせが返される


・$cmbの結果
下記6通りが返される
すいか:BLUE
すいか:GREEN
すいか:GRAY
すいか:NAVY
すいか:PINK
すいか:WHITE

返されるのが5つであればそのまま使用できそうです。

計算式は半分も解読できていませんが、$cmbを使うのですよね?
申し訳ございませんが引き続きご教示よろしくお願いいたします。

編集者 Valon (2019-08-09 11:37:24)

オフライン

#6 2019-08-09 12:13:47

チポ
メンバー

Re: [解決] 組み合わせで足りないレコードを補完

> 長いと30秒ぐらいです
例では、
24通りの組み合わせができますが、
この程度でも30秒かかります?

簡単にテストしたら一瞬でしたが・・


欲しいのはリストではなく、不足レコードの補完ですよね?

オフライン

#7 2019-08-09 12:25:48

Valon
メンバー

Re: [解決] 組み合わせで足りないレコードを補完

チポ様

時間がかかるのは初めの投稿時に私が組んでいたやり方です。
30秒というのは大げさだったかもしれませんが、組み合わせが300近いと結構待ちます。
Hiro様のやり方ですと一瞬でした。

厳密には不足レコードのリストが欲しいです。
レコード補完はそのリストを元に自分でできそうです。
タイトルが紛らわしかったです、申し訳ございません。

編集者 Valon (2019-08-09 12:27:40)

オフライン

#8 2019-08-09 13:17:28

チポ
メンバー

Re: [解決] 組み合わせで足りないレコードを補完

ListA,Bともに20種
組み合わせ400種のうちランダムに100種作り、残りのレコード作成をしてみましたが、
これでも一瞬でしたよ。

マシンは古いプアなものですが、、

オフライン

#9 2019-08-09 13:40:01

Hiro
メンバー

Re: [解決] 組み合わせで足りないレコードを補完

■既存レコード
識別子  品名   色名
1000  りんご  BLUE
1000  みかん  BLUE
1000  ばなな  BLUE
1000  りんご  GREEN
1000  みかん  GREEN
1000  ばなな  GREEN
1000  りんご  GRY
1000  みかん  GRY
1000  ばなな  GRY
1000  りんご  NAVY
1000  みかん  NAVY
1000  ばなな  NAVY
1000  りんご  PINK
1000  みかん  PINK
1000  ばなな  PINK
1000  りんご  WHITE
1000  みかん  WHITE
1000  ばなな  WHITE
1000  すいか  NAVY
1001  りんご  BLUE
1001  みかん  BLUE
1001  ばなな  BLUE
1002  ラジオ  白
1003  ペンチ  メッキ
1004  タイヤ  白ライン入り


+++++++++++++++++++++

■式に使う引数パラメータの基礎データがグローバルフィールドに入力されている前提で、
「g識別子:1000」
「g品名リスト:りんご¶みかん¶ばなな¶すいか 」
「g色名リスト:BLUE¶GREEN¶GRY¶NAVY¶PINK¶WHITE」

■全1x4x6=24通りに足りない5組合せを算出する。
1000:すいか:BLUE
1000:すいか:GREEN
1000:すいか:GRAY
1000:すいか:PINK
1000:すいか:WHITE

■計算式
Let([
   $num=g識別子フィールド;
   //1. 全組合せリストを変数 $prm[1]へ書き出す(入れ子の2段ループ式)
   $lst1=g品名リストフィールド;
   $lst2=g色名リストフィールド;
   $i=0;
   $res="";
   $FNC=
      "Case($i=ValueCount($lst1); $res;
         Let([
            $i=$i+1;
            $itm=GetValue($lst1;$i);
            $j=0;
            $cmb=\"\";
            $res=List($res; Evaluate($SUB))
         ]; Evaluate($FNC))
      )";
   $SUB=
      "Case($j=ValueCount($lst2); $cmb;
         Let([
            $j=$j+1;
            #cmb=$num &\":\"& $itm &\":\"& GetValue($lst2;$j);
            $cmb=List($cmb; #cmb)
            ]; Evaluate($SUB))
      )";
   $prm[1]=Evaluate($FNC);
   //2. 既存の組合せリストを変数 $prm[2]へ書き出す
   $prm[2]=
      ExecuteSQL("SELECT \"識別子\",\"品名\",\"色名\" FROM \"テーブル名\" WHERE \"識別子\"=?"; ":"; ¶; $num)
];
   //3. ※「逆FilterValues関数式」で目的の補完リストを算出
   Let([
      $prm[1]=¶ & $prm[1] & ¶;
      $prm[2]="[\"\¶" & Substitute($prm[2]; [¶; "\¶\";\"\¶\"];[\"\¶"]) & "\¶\";\"\¶\"]";
      $prm[2]="Substitute($prm[1];" & $prm[2] & ")";
      $res=Evaluate($prm[2]);
      $res="\"" & Substitute($res;[¶;"\";\""]) & "\";\"\"";
      $res="List(" & $res & ")"
   ];
      Evaluate($res)
   )
)

編集者 Hiro (2019-08-09 13:58:42)

オフライン

#10 2019-08-09 15:22:02

Valon
メンバー

Re: [解決] 組み合わせで足りないレコードを補完

チポ様
私の以前のやり方ですと多分アナログすぎて時間がかかっていたものと思われます。
次回何かございましたらまた手法を教えてください。


Hiro様
わざわざありがとうございます。
よくよく見なおしてみると、私のExecuteSQLの書き方もおかしいですね。。

正しく変数を設定したところ、実現できました。
識別子という後出し情報まで組み込んでいただき
ありがとうございました。処理スピードも大満足です。

また何かございましたらよろしくお願いいたします。

オフライン

#11 2019-08-09 16:17:55

koko009
ゲストユーザー

Re: [解決] 組み合わせで足りないレコードを補完

後出しじゃんけんで申し訳ありませんが
商品テーブルとカラーテーブル及び既存の組合せテーブル(データテーブル)を想定して、Hiro様の方法をの一寸いじりました
Let([
      $prm[1]=¶ & ExecuteSQL ( "select a.\"品名\",B.\"色名\" from \"商品\"a,\"カラー\"b";"";"" ) & ¶;
      $prm[2]="[\"\¶" & Substitute(ExecuteSQL ( "select \"品名\",\"カラー\" from \"データ\"";"";"" ); [¶; "\¶\";\"\¶\"];[\"\¶"]) & "\¶\";\"\¶\"]";
      $prm[2]="Substitute($prm[1];" & $prm[2] & ")";
      $res=Evaluate($prm[2]);
      $res="\"" & Substitute($res;[¶;"\";\""]) & "\";\"\"";
      $res="List(" & $res & ")"
   ];
      Evaluate($res)
   )
質問者の方が解決済みなので、こんな方法も有りかなと思い・・・

#12 2019-08-09 18:17:08

Valon
メンバー

Re: [解決] 組み合わせで足りないレコードを補完

koko009様
ありがとうございます。

色々なやり方があるのですね。
ExecuteSQLも最近覚えたばかりで色々な使い方に感心させられます。

今後ともよろしくお願いいたします。

オフライン

クィック投稿

メッセージを書いて送信してください。
登録の確認

実在の人物による登録であることを確認します。

Board footer