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

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

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

You are not logged in.

Announcement

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


#1 2024-01-23 16:42:04

hadhuh
Guest

ソート順

お世話になっております。

ソート機能ですが「レコードをフィールド順でソート」を使用するとアクティブなフィールドでソートできるかと思うのですが、
「レコードのソート」のように「レコードをフィールド順でソート」で複数のソートを一括で行うことは可能でしょうか。

#2 2024-01-23 16:49:26

Shin
Member

Re: ソート順

表型式での話ですか。
複数キーにしたソートは、その延長ではできません。

Offline

#3 2024-01-23 17:12:07

hadhuh
Guest

Re: ソート順

Shin wrote:

表型式での話ですか。
複数キーにしたソートは、その延長ではできません。

例えばですが、ソートしたいフィールドが2つあったとして、
スクリプトで1度目のプライオリティソートした後に、レコードの順番をナンバリング(ナンバリングは桁ぞろえする)して保持し、
2度目のセカンドソートして、レコードの順番をナンバリング、
1度目と2度目のナンバリングした順番を合体して「レコードをフィールド順でソート」すると機能するでしょうか。

#4 2024-01-23 18:41:13

Shin
Member

Re: ソート順

単純なナンバリングではちょっと無理でしょうね。
1回めのソートで、次のようにナンバリングしても、
A a 100
A f 200
A b 300
B c 400
B d 500
2回めのナンバリングで、
A a 101
A b 302
B c 403
B d 504
A f 205
となるでしょうが、この順ではないです。
フィールド内容そのものを桁を揃えて合体させるのがいいのでは。

または、ナンバリングのフィールドを消去しておいて、Text1のソート後、

let (
	$t = case ( get ( レコード番号 ) = 1 ; Text1 ; UniqueValues ( list ( Text1 ; $t ) ) ) ;
	number * 100 + ValueCount ( $t )
)

という計算式でナンバリングを全置換し、で次にText2でソートして、

let (
	$t = case ( get ( レコード番号 ) = 1 ; Text2 ; UniqueValues ( list ( Text2 ; $t ) ) ) ;
	number * 100 + ValueCount ( $t )
)

という計算式で全置換していくとナンバリングができます。(カテゴリー数がそれぞれ100以内の場合)

ただ、そこまでするなら、普通のソートした方がいいのでは。

Last edited by Shin (2024-01-24 20:59:05)

Offline

#5 2024-01-24 15:21:06

チポ
Member

Re: ソート順

最初のナンバリングを単にレコードの並び順に振るのではなく、
ソートしたフィールドの値が同じグループごとの順に振っていけばいいですよね。

それにはソートしたフィールド名を得る必要がありますが、条件が分かりません。。

Offline

#6 2024-01-25 10:47:00

himadanee
Guest

Re: ソート順

複数のフィールド名をテキストで指定して、その順にソートする仕組みを作ってみました。

追加するフィールド3個
ids 集計 主キーの一覧
sorted テキスト グローバル(次の計算フィールドで使う、グローバル変数でも可)
sorter 計算 非保存 Position(sorted;主キー;1;1)

ソートするサブスクリプト
フィールド設定「sorted;ExecuteSQL("
SELECT \"主キー\"
FROM \"テーブル\"
WHERE \"主キー\" IN('" &
Substitute ( テーブル::ids ; ¶ ; "','" ) &
"')
ORDER BY " &
Get(スクリプト引数)
; "" ; "" )

レコードのソート「記憶する(sorterの昇順)」

このサブスクリプトを、ソートしたいフィールドを引数にして呼び出します。
引数は、フィールド名をQuoteしてカンマで連結
Quote("t1") & "," & Quote("t2")
降順にしたい場合はDESCを付ける
Quote("n1") & "," & Quote("t2") & " DESC," & Quote("t1")

※現在のテーブルのフィールドでしかソートできません。(SQLを複雑にすれば複数テーブルでも可能でしょう)
※IN()を使って対象レコードの主キーのリストをSQL文に埋め込んでるので、上限がどのくらいかな。
※非保存計算フィールドでソートするので、上記の上限とどっちがボトルネックになるか。100レコードぐらいでは瞬時に終わりましたが

#7 2024-01-31 16:04:30

hadhuh
Guest

Re: ソート順

himadanee wrote:

複数のフィールド名をテキストで指定して、その順にソートする仕組みを作ってみました。

追加するフィールド3個
ids 集計 主キーの一覧
sorted テキスト グローバル(次の計算フィールドで使う、グローバル変数でも可)
sorter 計算 非保存 Position(sorted;主キー;1;1)

ソートするサブスクリプト
フィールド設定「sorted;ExecuteSQL("
SELECT \"主キー\"
FROM \"テーブル\"
WHERE \"主キー\" IN('" &
Substitute ( テーブル::ids ; ¶ ; "','" ) &
"')
ORDER BY " &
Get(スクリプト引数)
; "" ; "" )

レコードのソート「記憶する(sorterの昇順)」

このサブスクリプトを、ソートしたいフィールドを引数にして呼び出します。
引数は、フィールド名をQuoteしてカンマで連結
Quote("t1") & "," & Quote("t2")
降順にしたい場合はDESCを付ける
Quote("n1") & "," & Quote("t2") & " DESC," & Quote("t1")

※現在のテーブルのフィールドでしかソートできません。(SQLを複雑にすれば複数テーブルでも可能でしょう)
※IN()を使って対象レコードの主キーのリストをSQL文に埋め込んでるので、上限がどのくらいかな。
※非保存計算フィールドでソートするので、上記の上限とどっちがボトルネックになるか。100レコードぐらいでは瞬時に終わりましたが


返信遅くなってしまい、申し訳ございません。
ExecuteSQLを使用したことないので仕組みが全く理解できていないのですが、

例えば、「ファースト」「セカンド」「サード」という3つのフィールドがあったとして、
これらを全て昇順でソートする場合は、
Quote(ファースト) & "," & Quote(セカンド) & "," & Quote(サード)
という計算式で結合し、変数に入れて、スクリプト引数として、

フィールド設定「sorted;ExecuteSQL("
SELECT \"主キー\"
FROM \"テーブル\"
WHERE \"主キー\" IN('" &
Substitute ( テーブル::ids ; ¶ ; "','" ) &
"')
ORDER BY " &
Get(スクリプト引数)
; "" ; "" )

に渡すということでしょうか。
大変恐縮ではございますが、ご教示の程宜しくお願い致します。

#8 2024-01-31 16:24:48

himadanee
Guest

Re: ソート順

「フィールド名をテキストで指定」なので、
Quote(ファースト)
ではなく
Quote("ファースト")
です。

ソートのスクリプトと違ってフィールド名がスクリプトに組み込まれないのがミソですので。
逆に、フィールド名を変更した場合は自動的に修正されないので要注意です。

#9 2024-01-31 18:19:46

hadhuh
Guest

Re: ソート順

himadanee wrote:

「フィールド名をテキストで指定」なので、
Quote(ファースト)
ではなく
Quote("ファースト")
です。

ソートのスクリプトと違ってフィールド名がスクリプトに組み込まれないのがミソですので。
逆に、フィールド名を変更した場合は自動的に修正されないので要注意です。

ありがとうございます。
フィールド設定の計算式についてですが、
「主キー」や「テーブル」という文字は環境で使用しているフィールド名やテーブル名に当てはめるということでお間違いないでしょうか。
例えば主キーのフィールド名が「No」でテーブル名が「MainTable」だとすると

フィールド設定「sorted;ExecuteSQL("
SELECT \"No\"
FROM \"MainTable\"
WHERE \"No\" IN('" &
Substitute ( MainTable::ids ; ¶ ; "','" ) &
"')
ORDER BY " &
Get(スクリプト引数)
; "" ; "" )

になるということでお間違いないでしょうか。

#10 2024-01-31 19:11:07

himadanee
Guest

Re: ソート順

主キーが数字だと、シングルクオートは不要になります。
テキストの場合囲みが必要
IN('a','b','Z')
数値の場合囲みは不要
IN(1,2,9)
という風になりますので。

SQLで、対象レコードの主キーのリストを指定したソート順でソートしてグローバルフィールドに入れ、
FMのソートはその結果のリストの内での主キーの位置でソートする、という仕組みです。
なので、主キーがただの数字(またはテキストでも主キー同士で部分一致する場合)だとうまくいかないですね。(1の位置を計算したつもりで11の位置を得てしまう可能性がある)
デフォルトのUUIDを使って実装してました。

そういう場合は、終端記号を追加するように、例えば
"#"&
ExecuteSQL(
~~~
; "" ; "#" ) & "#"
として、sorterの計算式を
Position(sorted;"#"&主キー&"#";1;1)
のようにすればいいかな。(テストしてません)

#11 2024-02-01 16:20:44

hadhuh
Guest

Re: ソート順

himadanee wrote:

主キーが数字だと、シングルクオートは不要になります。
テキストの場合囲みが必要
IN('a','b','Z')
数値の場合囲みは不要
IN(1,2,9)
という風になりますので。

SQLで、対象レコードの主キーのリストを指定したソート順でソートしてグローバルフィールドに入れ、
FMのソートはその結果のリストの内での主キーの位置でソートする、という仕組みです。
なので、主キーがただの数字(またはテキストでも主キー同士で部分一致する場合)だとうまくいかないですね。(1の位置を計算したつもりで11の位置を得てしまう可能性がある)
デフォルトのUUIDを使って実装してました。

そういう場合は、終端記号を追加するように、例えば
"#"&
ExecuteSQL(
~~~
; "" ; "#" ) & "#"
として、sorterの計算式を
Position(sorted;"#"&主キー&"#";1;1)
のようにすればいいかな。(テストしてません)


どうしても計算式で返す値が「?」になるのですが、ご教示いただけますでしょうか。

・「No」は数値のシリアル番号で管理しています。(重複はありません)
・テーブルは「MainTable」という名前です。
・「$list」は「1,2,3,・・・」で「No」の集計です。
・「$kekka」は「"MainTable::ファースト","MainTable::セカンド"」というフィールド名が代入されています。

ExecuteSQL ( "SELECT \"No\"
FROM \"MainTable\"
WHERE \"No.\" IN(" & $list & ")
ORDER BY " &
$kekka ; "" ; "")

#12 2024-02-01 16:23:31

hadhuh
Guest

Re: ソート順

「WHERE \"No.\"」は「WHERE \"No\"」です。失礼いたしました。

#13 2024-02-01 16:45:14

himadanee
Guest

Re: ソート順

先に書きましたように、主キーですから「重複がない」のは当然ですが、部分一致するとPosition関数で破綻しますから、
>・「$list」は「1,2,3,・・・」で「No」の集計です。
この場合
>$kekka ; "" ; "")
ではだめです。

まずはSQLの結果を見るために、
>・「$kekka」は「"MainTable::ファースト","MainTable::セカンド"」というフィールド名が代入されています。
これを直してください。テーブル名が入っててはだめです。
完全修飾でなくフィールド名だけにしてください。
SQLでテーブル名を付ける場合は::でなく.区切りになります。
"table"."field"

#14 2024-02-01 17:49:38

hadhuh
Guest

Re: ソート順

himadanee wrote:

先に書きましたように、主キーですから「重複がない」のは当然ですが、部分一致するとPosition関数で破綻しますから、
>・「$list」は「1,2,3,・・・」で「No」の集計です。
この場合
>$kekka ; "" ; "")
ではだめです。

まずはSQLの結果を見るために、
>・「$kekka」は「"MainTable::ファースト","MainTable::セカンド"」というフィールド名が代入されています。
これを直してください。テーブル名が入っててはだめです。
完全修飾でなくフィールド名だけにしてください。
SQLでテーブル名を付ける場合は::でなく.区切りになります。
"table"."field"

「$kekka」を"table"."field"の形に修正することで計算式の結果が「?」ではなくなりました。ありがとうございます。
しかし、グローバルフィールド(sorted)にフィールド設定をした後に「sorter 計算 非保存 Position(sorted;主キー(当方では「No」フィールド);1;1)」
を昇順にしたレコードのソートを行ったのですが、ソートが上手く機能しません。
主キーを数値にしていることが問題なのでしょうか。

#15 2024-02-01 18:58:03

himadanee
Guest

Re: ソート順

そのことは、#10に書いてあります。

#16 2024-02-02 09:51:26

hadhuh
Guest

Re: ソート順

情報が整理できておらず、申し訳ございません。
記載の通り修正し、グルーピングされるように修正されました。ありがとうございます。
しかしファイルメーカーのデフォルト機能でソートした時と順番が異なりました。(「風景」「歴史」の順番が、「歴史」「風景」になってしまいます。)
何か考えられることはありますでしょうか。それとも私の設定が間違っている可能性が高いのでしょうか。
度々申し訳ございませんが、ご教示の程、お願い致します。

#17 2024-02-02 10:23:41

himadanee
Guest

Re: ソート順

あちゃあ。英字と数字フィールドでしかテストしてませんでした。

FileMaker SQL は、Unicode バイナリソート順を使用します。これは言語のソートやデフォルトの言語のニュートラルなソート順で使用される FileMaker Pro のソート順とは異なります。

まさかFMの索引が使われないとは、知りませんでした。
索引が使える方法を考えないとだめですね。

#18 2024-02-02 10:59:08

himadanee
Guest

Re: ソート順

「FileMaker Data API を実行」なら索引順でソートすると思ったんですが、どうもそうではない?
この機能は取得するフィールドを指定できないので、SQLより面倒です...

#19 2024-02-02 11:35:03

hadhuh
Guest

Re: ソート順

そういうことだったんですね。

かっこ悪いやり方かもしれませんが、
やはり昇順や降順でグルーピングを繰り返すのがよいのでしょうか...

#20 2024-02-06 20:53:41

himadanee
Guest

Re: ソート順

Javascriptだと日本語ソートもできるようなのでWebビューアでやらせたらどうかと思いましたが、対象レコードのデータを全部送るのは結構手間がかかりそうです。

スクリプトの「レコードをフィールド順でソート」だとフィールド1つしかソートできませんが、表形式だとできるので、
ソートさせたいフィールドだけ含めた表形式レイアウトを作っておくとかですかねえ。

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

Board footer

Powered by FluxBB
Modified by Visman

[ Generated in 0.047 seconds, 9 queries executed - Memory usage: 570.43 KiB (Peak: 590.97 KiB) ]