10 返信 最新の回答 日時: Feb 20, 2017 1:47 PM ユーザー:norinori

    FileMaker 14で文字列(全角半角混在)を固定バイト長で分割

    norinori

      FileMaker 14で文字列(全角半角混在)を固定バイト長で分割したいのですが、

      昔のFileMakerに実装されていたLengthb,Leftb,MiddlebはFileMaker14ではありません。

       

      そこでカスタム関数にてLengthb(Length ( テキスト & Filter ( テキスト ; RomanZenkaku ( KanaZenkaku ( テキスト ) ) ) ))

      を作成して、

      ・1文字づつを変数$dataに格納

      ・$dataをカスタム関数Lengthbでバイト数チェック

      ・指定バイト数を超えていない場合、さらに1文字を変数$dataに格納

      ・指定バイト数を超えれば、新規レコード作成し、$dataをフィールド設定

      のスクリプトを実行してみたのですが、なにぶん1文字づつの処理なので時間が

      かなりかかってしまい、実用できる処理にはなりませんでした。

      (分割元のテキストはたかだか200kbほどなのですが)

       

      なにか効率的な方法はありませんでしょうか?

       

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

       

      ※検索サイトでfmpro.jpにLeftbがあるという情報まではたどり着きましたが、現在fmpro.jpは

       アクセスできないとうで、かつFileMaker14には対応していない?

        • 1. Re: FileMaker 14で文字列(全角半角混在)を固定バイト長で分割
          sago350@未来Switch

          こんな感じで。

          Length ( テキスト & Filter ( テキスト ; RomanZenkaku(KanaZenkaku(テキスト)) ) )

           

          スクリーンショット 2017-02-17 10.58.54.png

          <追記>

          あ、マチガイ。問題はその先だった・・・

          • 2. Re: FileMaker 14で文字列(全角半角混在)を固定バイト長で分割
            user19752

            こうかな。

             

            Case ( LengthB ( text ) <= bytes ; text ;

            LeftB ( Left ( text ; Length ( text ) - Ceiling ( ( LengthB ( text ) - bytes ) / 2 ) ) ; bytes )

            )

             

            指定バイト数より長ければ、長いバイト数の半分文字数ずつ減らしてみる。

            • 3. Re: FileMaker 14で文字列(全角半角混在)を固定バイト長で分割
              user14047

              どちらも対応バージョンのチェックの更新がされていなかっただけで FileMaker Pro 15 でも利用可能です^^;

              古いマシンを労わりながら公開しておりますので、落ちていたらごめんなさい。

               

              分割はどのような形が最終目的ですか?

              メール本文を n 文字毎に改行を入れる処理だと、もともと入っている改行をどうするかであるとか、禁則処理をどうするかという問題が出てきます。

              • 4. Re: FileMaker 14で文字列(全角半角混在)を固定バイト長で分割
                norinori

                ありがとうございます。求めていたものがGetできました。

                 

                行いたい処理の概要は、他システムから受け取ったデータ(固定長・全角混在・改行コードなし)を決められた

                長さに分割して、指定した項目にセットすることです。

                 

                いただいたLeftbで上記処理を実装してみましたが、残念ながら1文字づつ取得し文字列長をチェックする方式の

                ほうが処理時間ははやかったです。

                 

                1文字づつ取得し文字列長チェックの繰り返し → 256byte分割 約1秒

                Leftbで文字列を取得し、その後Rightで取得した文字列を削除の繰り返し → 256byte分割 約2秒

                 

                Leftbも1文字づつ取り出すロジックだったので、カスタム関数の再帰のオーバーヘッド分処理時間が

                かかってしまったようです。

                 

                逆に考えてMiddle関数で256文字取得して、lengthbで256byte以上の場合は減らしていくロジックで一度

                トライしてみます。

                これでダメなら、インポート前にVBなどのバッチ処理でタブ区切りに分割する処理をかますしかないですね

                 

                しかしFMはなぜバイト処理の関数を廃棄したのでしょうか??

                • 5. Re: FileMaker 14で文字列(全角半角混在)を固定バイト長で分割
                  user14047

                  最後の部分だけに反応...

                  FileMaker は内部的に UTF-16 でデータが格納されています。

                  Shift_JIS における 2 バイトという概念がそぐわなくなっているからかと思います。

                  UTF-16 の場合、1文字でも、2バイトの場合もあれば、3バイト、4バイトの場合もありますからね...

                  • 6. Re: FileMaker 14で文字列(全角半角混在)を固定バイト長で分割
                    user19752

                    Leftbも1文字づつ取り出すロジックだった

                     

                    同じ名前でカスタム関数を書いてしまいましたけど、私のは毎回余った文字数の半分は減るので、200KBならせいぜい20回ぐらいの再帰呼び出しで完了するはずです。

                    1文字ずつ取り出すと、128~256回です。

                     

                    それでも遅かったので見直してみたら、LengthBを2回呼び出してました。1回にしたらおよそ倍速になりました。

                    Let ( lb = LengthB ( text ) ;

                    Case ( lb <= bytes ; text ;

                    LeftB ( Left ( text ; Min ( bytes * 2 ; Length ( text ) - Ceiling ( ( lb - bytes ) / 2 ) ) ) ; bytes )

                    )

                    )

                     

                    Min()を使って最初の呼び出しで大幅に切り詰めるようにもしたけれど、そっちはそれほど効果はない。

                    再帰のたびに同じ文字列に対してLengthBを呼んでるのが根本的に無駄かなあ。

                    • 7. Re: FileMaker 14で文字列(全角半角混在)を固定バイト長で分割
                      user14047

                      素晴らしい!

                      比較したら、圧倒的に速かったです。

                       

                      FileMaker Pro 6 当時の LeftB 関数の仕様に合わせるべくちょっと改変させていただいた検証ファイルを添付しました。

                      • 8. Re: FileMaker 14で文字列(全角半角混在)を固定バイト長で分割
                        user19752

                        「倍速」でも200kbから256バイト取り出すのに10回で10秒弱かかってたのですが、先頭から取り出していくように変えたら0.14秒になりました

                         

                        Case (

                            バイト数 <= 0 ;

                                "" ;

                            バイト数 = 1 ;

                                //1バイト取得するとき次の文字が全角ならば半角スペース

                                Let ( ~次 = Left ( テキスト ; 1 ) ; Case ( Exact ( ~次 ; RomanZenkaku ( KanaZenkaku ( ~次 ) ) ) ; " " ; ~次 ) ) ;

                            Let (

                                [

                                    //バイト数の半分はすぐに確定する

                                    ~確定分 = Left ( テキスト ; バイト数 / 2 ) ;

                                    ~確定バイト数 = Length ( ~確定分 & Filter ( ~確定分 ; RomanZenkaku ( KanaZenkaku ( ~確定分 ) ) ) ) ;

                                    ~残り = Right ( テキスト ; Length ( テキスト ) - Length ( ~確定分 ) )

                                ] ;

                                // 再帰

                                ~確定分 & Case ( ~残り <> "" ; LeftB_03 ( ~残り ; バイト数 - ~確定バイト数 ) )

                            )

                        )

                        2 人中 2 人が役に立つと言っています
                        • 9. Re: FileMaker 14で文字列(全角半角混在)を固定バイト長で分割
                          user19752

                          残り全部を次の再帰に渡す必要ないので、この方が少し速くなる

                           

                          ~残り = Middle ( テキスト ; バイト数 / 2 + 1 ; バイト数 - ~lb )

                          • 10. Re: FileMaker 14で文字列(全角半角混在)を固定バイト長で分割
                            norinori

                            user19752さん

                            素晴らしいです。十分に実用レベルだと思います!!