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

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

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

You are not logged in.

Announcement

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


#1 2022-07-27 09:38:35

noel
Member

全ての文字の間にスペースを挿入したい

いつもお世話になっております。

環境はMac FM17 です。

タイトルの通り、全ての文字の間にスペースを挿入する計算式を模索しております。

例として、
「name」フィールドの内容が"やまだたろう"であった場合、
「name_space」に
"や ま だ た ろ う" もしくは
" や ま だ た ろ う "
と帰ってくる「name_space」の計算式(計算式自動入力or計算フィールド)が目標です。

補足として、
・「name」の内容は1文字〜上限なし
・「name」と「name_space」フィールドは同じテーブル
・挿入されるテキストは最終的にSubtituteでスペースに変換するので指定はありません

これまではスクリプトにおいてloop処理で1文字ずつスペース挿入していく方法をとっていたのですが、
フィールドの計算式自動入力で一発で求められないかと思い、ご教示賜わりに参りました。

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

Offline

#2 2022-07-27 10:00:22

Shin
Member

Re: 全ての文字の間にスペースを挿入したい

While (
[
    text = self ;
    i = length ( text )
] ;
    i > 1 ;
[
    text = Replace ( text ; i , 0 ; " " ) ;
    i = i - 1
] ;
    text
)

を、自動計算に設定します。
手打ちなので打ち間違いがあるかも。

Last edited by Shin (2022-07-27 10:01:27)

Offline

#3 2022-07-27 10:10:13

noel
Member

Re: 全ての文字の間にスペースを挿入したい

Shin 様

早速のご回答ありがとうございます。

While関数を使用すればご教示いただいた内容で結果を求められるのですね。
ただ、While関数はFM18が始点のようでFM17では使用することができませんでした。。

Offline

#4 2022-07-27 10:17:08

チポ
Member

Re: 全ての文字の間にスペースを挿入したい

ですよね。

同じ考えで
Let
Evaluate
を使った再起式でできますが、

繰り返しフィールドに一文字ずつブランクを付けて展開すれば
簡単では。

印刷のフォーマットの問題でしょうか?
とすれば、他の方法も考えられますが。。

Offline

#5 2022-07-27 10:33:34

noel
Member

Re: 全ての文字の間にスペースを挿入したい

チポ様

ありがとうございます。

おっしゃるとおり印刷のフォーマットに起因するものです。

イメージですが表彰状のようなレイアウトで下記のようになることが最終目標です。

"○ ○ 月 ○ ○ 日 、" & name_space & "殿 は 素 晴 ら し い 成 績 を お さ め ま し た 。"
name_space = "や ま だ た ろ う"

恥ずかしながらカスタム関数がないかと淡い期待をしておりました。

Last edited by noel (2022-07-27 10:35:20)

Offline

#6 2022-07-27 10:40:55

qb_dp
Member

Re: 全ての文字の間にスペースを挿入したい

久しぶりに再起式を書いてみました。

Let ([
$_str = Self
;~count = Length ( $_str )
;$_n = ~count+1
;$_f = "Case ( $_n ≤ 1; $_str ;
	LET([$_str=Replace ( $_str ; $_n ; 0 ; Char ( 32 ) ); $_n=$_n-1] ; Evaluate($_f))
)"
];
Evaluate($_f)
)

Offline

#7 2022-07-27 10:46:38

noel
Member

Re: 全ての文字の間にスペースを挿入したい

qb_dp様

ありがとうございます。

そっくりそのまま使用させていただき、求めていた結果がでるようになりました。
まだ式内で何が行われているか理解できておりませんが、
一つずつ噛み砕きながら身につけるようにいたします。

Shin様、チポ様、qb_dp様
こんなに早くレスポンスをいただき感謝の念でいっぱいです。
改めてありがとうございました!!

Offline

#8 2022-07-27 10:47:23

Shin
Member

Re: 全ての文字の間にスペースを挿入したい

繰り返しフィールドに1文字ずつ入れておいて、配置する方法も簡単ですよ。

Offline

#9 2022-07-27 10:52:22

noel
Member

Re: 全ての文字の間にスペースを挿入したい

作文用紙のように繰り返しフィールドを1マス1マスとして使っていくということでしょうか。
確かに簡単ですし、おもしろく、メンテナンス性も良さそうですね。
次回同じようなレイアウトを作成する際は試してみます。
ありがとうございます!

Offline

#10 2022-07-27 11:08:51

himadanee
Guest

Re: 全ての文字の間にスペースを挿入したい

>「name」の内容は1文字〜上限なし
となってますが、このタイプの再帰式は300文字ぐらいが限界なので、念のため。(400文字で結果が?になることだけ確認済)

#11 2022-07-27 11:18:19

noel
Member

Re: 全ての文字の間にスペースを挿入したい

himadanee様

限界があるのですね!
頭に入れておくようにいたします。
ご注意いただきありがとうございます。

Offline

#12 2022-07-29 20:31:17

himadanee
Guest

Re: 全ての文字の間にスペースを挿入したい

あんまりテストしてないけど、ようやくできた...
これも限界はあるだろうけどとりあえず6400文字まではエラーにならないのを確認しました。(2^300文字ぐらいまでいけるのかな?)
(文字の間に、なので末尾にはスペースが付きません)

Let ([
$str = text
;$f = "Let ( [ $s=$str ; n = Length($s) ] ;
Case ( n ≤ 1; $s ;
Let([
l=Left($s;Ceiling(n/2))
;r=Right($s;Floor(n/2))];
Evaluate(Substitute ( $f ; \"$\"&\"str\" ; Quote(l) ) ) & Char(32) & Evaluate(Substitute ( $f ; \"$\"&\"str\" ; Quote(r) ) ) ) ) )"
];
Evaluate($f)
)

#13 2022-07-30 14:47:16

koko009
Guest

Re: 全ての文字の間にスペースを挿入したい

脇からの余計な質問をさせてください。
この問題をテキストの文字数を106496とし、下記のスクリプトでloopで処理したとところ処理時間が再帰式やWhile関数(上限をLength ( テスト)+1に設定)に比べ3倍近く掛かりました(loop:86689,while:27282,再帰式:27702)。
変数を設定 [ $count; 値:2 ]
変数を設定 [ $text; 値:recursive::a1 ]
Loop
Exit Loop If [ $count-1 ≥ Length ( $text ) ]
変数を設定 [ $text; 値:Replace ($text ;$count; 0 ; " " ) ]
変数を設定 [ $count; 値:$count + 2 ]
End Loop
フィールド設定 [ recursive::b1; $text ]
今までloop方が速いとの思い込みがあるので私の書いたスクリプトに問題が在るのではないかと思い投稿させていただきました。
ご教授お願いいたします。
環境は、Windows10 FM19.5.2

#14 2022-07-30 15:16:55

Shin
Member

Re: 全ての文字の間にスペースを挿入したい

スクリプトは、一種のインタープリターですので、実行するごとに1行ずつコンパイルされて実行されます。ですから、回す回数にもよるでしょうが、loop は遅くなりますよ。
スクリプトの実行は、行数に比例して時間がかかります。上のスクリプトでしたら、実行時には30万ステップ以上になりますので、それを考えれば、その程度の時間差は出ると思います。
変数を設定 [ $count; 値:2 ]
変数を設定 [ $text; 値:recursive::a1 ]
Loop
Exit Loop If [ [ Let ( [ $text = Replace ($text ;$count; 0 ; " " ) ; $count = $count + 2 ] ; $count-1 ≥ Length ( $text ) )] ]
End Loop
フィールド設定 [ recursive::b1; $text ]
にしてみると、ステップ数が半分程度になるので、早くなるかも。
変数を設定 [ $text; 値:recursive::a1 ]
変数を設定 [ $count; 値:Length ( $text ) ]
Loop
Exit Loop If [ [ Let ( [ $text = Replace ($text ;$count; 0 ; " " ) ; $count = $count - 1 ] ; $count ≤1 )] ]
End Loop
フィールド設定 [ recursive::b1; $text ]
にすると、計算量が少しだけ減るので、少し早くなるかも。

Last edited by Shin (2022-07-31 08:30:10)

Offline

#15 2022-07-30 15:57:15

koko009
Guest

Re: 全ての文字の間にスペースを挿入したい

shin様 有り難うございます。早速 「Let ( [ text =・・」を「 Let ( [ $text =・・」に直し処理してみたところ
前のバージョン:83979
後のバージョン:処理実行されず
の結果となりました。

スクリプトの実行は、行数に比例して時間がかかります。上のスクリプトでしたら、実行時には30万ステップ以上になりますので、それを考えれば、その程度の時間差は出ると思います。

単に私の知識不足で勝手に思い込んでいただけだけなのですね。

#16 2022-07-30 21:18:14

himadanee
Guest

Re: 全ての文字の間にスペースを挿入したい

あれ?FM17だと無条件でAdvancedじゃなかったですか?
カスタム関数でも再帰ができます。
例えばinspaceという関数を定義する。
Case ( Length ( text ) < 2 ; text ;
Left ( text ; 1 ) & " " & inspace ( Right ( text ; Length ( text ) - 1 ) )
)

これだと5万文字が上限かな?再帰呼び出しの回数が変更できるのはいつからだったかな?

#17 2022-07-31 09:00:24

Shin
Member

Re: 全ての文字の間にスペースを挿入したい

こちらの検証では動いていますが。
だいたいの想定通りに、実行時間は2/3になっています。

下のアルゴリズムにすると、2/3になりました。思ったより早くなりました。Length()  が遅いのかな。

Offline

#18 2022-07-31 09:40:43

koko009
Guest

Re: 全ての文字の間にスペースを挿入したい

shin様 失礼しました。スクリプトの設定順を最初のまま使用していたので、正しいloop処理が行われていませんでした。申し訳ありません。
当方の計測結果は:30220
となりました。再帰式やWhile関数での処理時間に劣るもののすごい数値です。私には単純なアルゴリズムしか思いつきませんがこんなに違うとは!!
有り難うございました。

#19 2022-07-31 09:42:05

himadanee
Guest

Re: 全ての文字の間にスペースを挿入したい

「後のバージョン」が実行されなかったのは、一か所$が抜けてたんでしょう。

再帰回数の指定ができるのは18.0からだった。
https://help.claris.com/ja/pro-help/con … rsion.html

#20 2022-08-01 16:04:08

koko009
Guest

Re: 全ての文字の間にスペースを挿入したい

どうでもいい実験結果の報告です。
1000000文字のテキストで試してみました。
再帰式:275932ms
while:3152270ms
loop:途中で止めました。
212992では
loop:121819ms
再帰式:61318ms
while:114066ms
サンプル数が少ないのとPCのスペックの問題もあり参考まで。

#21 2022-08-01 18:05:13

Shin
Member

Re: 全ての文字の間にスペースを挿入したい

計算式のサイズ:    テキスト、数値、参照するフィールド、演算子、およびカッコを含め最大 30,000 文字
のはずですが???

Offline

#22 2022-08-02 08:31:02

koko009
Guest

Re: 全ての文字の間にスペースを挿入したい

計算フィールドではなくフィールド設定の方の計算式で実行しています。結果はLength ( フィールド)で1999999文字が返されているので問題はないかと思いますが?

#23 2022-08-02 10:52:52

himadanee
Guest

Re: 全ての文字の間にスペースを挿入したい

3万文字の制限は計算式を設定するダイアログの制限だったと思ってたんですが、今データビューアで試してみたら、
Evaluate(
Substitute ( 10^100-1 ; 9 ; Substitute ( 10^100-1 ; 9 ; "+1" ) )
)
は計算できました(+1を1万回なので2万文字)
が、どっちかを^200にしたら(4万文字)エラー(結果が?)になってしまいました。(FM19.5.2.201)

#12の私の再帰式は、文字列を半分にしてそれぞれ計算式に埋め込んで再帰呼び出ししている(変数のバッティングを避けるため)ので、Evaluateに与える文字列が3万文字を超えてるはずなんですが、不思議ですね。
こっちでやっても確かに102400文字でもエラーなく計算終了してました。(計算フィールド)
同じ文字数でも演算子の数とかも関係してるのかな?
そうでした。^200にする代わりに"+100"にしてみたらエラーにならなかった。う~ん。ややこしい。

ベンチマークはやってみてないですが、WhileがEvaluateの再帰式より遅いというのはちょっとがっかりな感じですね。さすがにこんなに長いテキストを扱うことはほとんどないと思いますけど...
アルゴリズム自体が再考の余地あり?

#24 2022-08-02 10:59:28

Shin
Member

Re: 全ての文字の間にスペースを挿入したい

以前は、その制限で再帰式は数千再帰くらいが限度でしたよね。計算途中の制限が無くなったのでしょうかね。

Offline

#25 2022-08-02 11:37:21

koko009
Guest

Re: 全ての文字の間にスペースを挿入したい

私は、再帰式につては門外漢なのですが昔以前あったの同名のサイトで文字列をバイト数で抜き出す方法を教わった際、最初に後ろから削る再帰式(再帰回数が298~302回限度)を教わりさらに別の方から次の改良版なら制限がないと教わったような記憶が・・・かなり曖昧な・・
Let([
  $byt=1000000;  //制限バイト数を指定
  $txt=Left ( recursive::a1; $byt ); //文字列フィールドを指定
$LengthB="Length($txt & Filter($txt;RomanZenkaku(KanaZenkaku($txt))))";
$LeftB="Case(Evaluate($LengthB)<=$byt; $txt; Let([$txt=Left($txt; Length($txt)-1)];Evaluate($LeftB)))"
];
Evaluate($LeftB)
)
今回テキストが百万文字を超えたためこれを使い百万文字に文字数を整えました。(当然時間が多少掛かりました)

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

Board footer

Powered by FluxBB
Modified by Visman

[ Generated in 0.006 seconds, 7 queries executed - Memory usage: 574.92 KiB (Peak: 611.83 KiB) ]