みんなに優しく、解りやすくをモットーに開設しています。 以下のルールを守りみんなで助け合いましょう。
1.ファイルメーカーで解らない事があればここで質問して下さい。 何方でも、ご質問・ご回答お願いします。 (優しく回答しましょう)
You are not logged in.
Pages: 1
お世話になっております。
環境:Win10 FM18
List_A List_B
りんご 赤
みかん 青
ばなな
Combination関数で6となります。
テーブルには、
レコード1 りんご 赤
レコード2 みかん 赤
レコード3 ばなな 青
この3レコードしかない場合、足りない3つを補完しております。
現在は1つ1つの組み合わせを変数とグローバルフィールドを使ったリレーション等で見ておりますが
List数が増えるとそれなりの時間がかかってしまいます。長いと30秒ぐらいです。
こちらを短縮する方法を模索しておりますが思いつきません。
とにかくスピード重視で何かございませんでしょうか?
全て変数で処理、もしくは足りないレコードが瞬時に分かればまだ早くできるような気がするのですが。
MBSプラグインが入っていますのでそちらを使った方法でも大丈夫です。
よろしくお願いいたします。
Offline
「足りないレコードを調べて補完する」というロジックはどうして必要になるのですか?
補完によって結局全ての組み合わせのレコードを作成するのであれば、
List_AもしくはList_Bにアイテムが追加されたタイミングで補完すれば、
いちいち足りないレコードを調べる必要はないように思うのですが?
Offline
0から作るなら、どちらかをグローバルの繰り返しフィールドにしておいて、目的のテーブルからインポートすればすぐです。
そこから既存のものを削除する処理をすれば早いでしょうね。
Offline
先ずは レコード補完のための「補完リストを取得」する計算式例です、
(※他の設定が一切不用の計算式だけによる方法で、簡便かつ敏速です!)
【計算手順】
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)
)
)
Last edited by Hiro (2019-08-09 01:27:37)
Offline
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を使うのですよね?
申し訳ございませんが引き続きご教示よろしくお願いいたします。
Last edited by Valon (2019-08-09 11:37:24)
Offline
> 長いと30秒ぐらいです
例では、
24通りの組み合わせができますが、
この程度でも30秒かかります?
簡単にテストしたら一瞬でしたが・・
欲しいのはリストではなく、不足レコードの補完ですよね?
Offline
チポ様
時間がかかるのは初めの投稿時に私が組んでいたやり方です。
30秒というのは大げさだったかもしれませんが、組み合わせが300近いと結構待ちます。
Hiro様のやり方ですと一瞬でした。
厳密には不足レコードのリストが欲しいです。
レコード補完はそのリストを元に自分でできそうです。
タイトルが紛らわしかったです、申し訳ございません。
Last edited by Valon (2019-08-09 12:27:40)
Offline
ListA,Bともに20種
組み合わせ400種のうちランダムに100種作り、残りのレコード作成をしてみましたが、
これでも一瞬でしたよ。
マシンは古いプアなものですが、、
Offline
■既存レコード
識別子 品名 色名
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)
)
)
Last edited by Hiro (2019-08-09 13:58:42)
Offline
チポ様
私の以前のやり方ですと多分アナログすぎて時間がかかっていたものと思われます。
次回何かございましたらまた手法を教えてください。
Hiro様
わざわざありがとうございます。
よくよく見なおしてみると、私のExecuteSQLの書き方もおかしいですね。。
正しく変数を設定したところ、実現できました。
識別子という後出し情報まで組み込んでいただき
ありがとうございました。処理スピードも大満足です。
また何かございましたらよろしくお願いいたします。
Offline
後出しじゃんけんで申し訳ありませんが
商品テーブルとカラーテーブル及び既存の組合せテーブル(データテーブル)を想定して、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)
)
質問者の方が解決済みなので、こんな方法も有りかなと思い・・・
koko009様
ありがとうございます。
色々なやり方があるのですね。
ExecuteSQLも最近覚えたばかりで色々な使い方に感心させられます。
今後ともよろしくお願いいたします。
Offline
Pages: 1
[ Generated in 0.006 seconds, 9 queries executed - Memory usage: 566.91 KiB (Peak: 587.81 KiB) ]