7 返信 最新の回答 日時: Sep 12, 2007 8:53 AM ユーザー:(kanokoage)

    Duplicateの戻りオブジェクト取得方法

    Level 1
      InDeign CS2 & VBA(Access2003)

      お世話になります。
      タイトルの通り、配置したTextFrameを状況に応じて複製するスクリプトを作成していますが、複製されたオブジェクトを変数にセットしようとするとエラー(「型が一致しません」)が発生 します。

      Dim ind1 As New InDesign.Application
      Dim doc1 As InDesign.Document
      Dim txt1 As InDesign.TextFrame, txt2 As InDesign.TextFrame
      Dim pag1 As InDesign.PageItem

      Set doc1 = ind1.Documents("test.indd")
      Set txt1 = doc1.TextFrames.Add
      txt1.GeometricBounds = Array(0, 0, 100, 50)
      txt1.Contents = "test text"

      この後、リファレンスにはDuplicateの戻りオブジェクトはPageItemとあるので

      Set pag1 = txt1.Duplicate(Array(100, 0))

      と書きましたがエラーが発生しました。
      戻り値もTextFrameではないかと思い

      Set txt2 = txt1.Duplicate(Array(100, 0))

      と書いてもエラーが出ます。メソッドだけ実行すると成功するのですが、

      txt1.Duplicate(Array(100, 0))

      このあと
      Set txt2 = doc1.TextFrames.LastItem

      を実行しても、複製されたものとは異なるオブジェクト参照が入っていました。

      どなたかよきアドバイスをよろしくお願いいたします。
        • 1. Re: Duplicateの戻りオブジェクト取得方法
          Level 1
          これはVBScript固有のバグですね。JavaScriptでは
          txt2 = txt.duplicate([100,0]);
          で問題なくいけます。

          複製後のオブジェクトの座標が分かっていて固有であれば(つまり重なってない)
          以下のように探すことができると思います。
          For i = 1 To doc1.TextFrames.Count
          If doc1.TextFrames(i).x = 0+100 And doc1.TextFrames(i).y = 0+0 Then
          Set txt2 = doc1.TextFrames(i)
          Exit For
          End If
          Next i

          そうでなければ、ちょっとマニアック(トリッキー?)な方法ですが
          複製の部分だけJavaScriptで実行させてみてはどうでしょう。
          VBScript と JavaScript 間でオブジェクトのやり取りができないので
          テキストフレームにラベルを付けています。

          txt1.GeometricBounds = Array(0, 0, 100, 50)
          txt1.Contents = "test text"
          txt1.Label = "org"

          app.DoScript "doc1 = app.activeDocument; for (i=0 ; i < doc1.textFrames.length ; i++){if (doc1.textFrames[i].label == ""org"") {txt = doc1.textFrames[i] ; break; } }txt2 = txt.duplicate([100,0]);txt2.label=""dup"";" , idJavascript

          For i = 1 To doc1.TextFrames.Count
          If doc1.TextFrames(i).Label = "dup" Then
          Set txt2 = doc1.TextFrames(i)
          Exit For
          End If
          Next i
          • 2. Re: Duplicateの戻りオブジェクト取得方法
            Level 1
            app.DoScriptの中が分かりにくいですね。JavaScript部分は次のようになっています。

            doc1 = app.activeDocument;

            for (i=0 ; i < doc1.textFrames.length ; i++){

              if (doc1.textFrames[i].label == "org") {

                txt = doc1.textFrames[i];

                break;

              }

            }

            txt2 = txt.duplicate([100,0]);

            txt2.label="dup";
            • 3. Re: Duplicateの戻りオブジェクト取得方法
              Level 1
              すみません。app.DoScriptじゃ意味が通りませんね。ついいつものくせで、、、
              app.DoScriptのところをind1.DoScriptと読み替えてください。
              • 4. Re: Duplicateの戻りオブジェクト取得方法
                Level 1
                何度もすみません。もっと簡単な方法を発見しました。
                もし、何も選択していない状態、もしくは選択が解除されてもいい場合には以下の方法ができます。

                ind1.Select(txt1.Duplicate(Array(100, 0)))
                Set txt2 = ind1.Selection(1)
                • 5. Re: Duplicateの戻りオブジェクト取得方法
                  Level 1
                  お〜まち 様

                  丁寧なご回答ありがとうございます。お礼が遅くなりまして失礼しました。

                  まず、最後の

                  ind1.Select(txt1.Duplicate(Array(100, 0)))
                  Set txt2 = ind1.Selection(1)

                  につきましては、1行目でやはり型が一致しないというエラーが発生してしまいました。

                  次に、
                  For i = 1 To doc1.TextFrames.Count
                  If doc1.TextFrames(i).x = 0+100 And doc1.TextFrames(i).y = 0+0 Then
                  Set txt2 = doc1.TextFrames(i)
                  Exit For
                  End If
                  Next i

                  では、どうやらxという部分でひっかかるようで、
                  「サポートされていないメソッドまたはプロパティ」というエラーが発生したのですが、
                  少し手を加えましたところ複製オブジェクトの取得に成功しました。

                  For i = 1 To doc1.TextFrames.Count
                  Set txt2 = doc1.TextFrames(i)
                  If txt2.GeometricBounds(1) = txt1.GeometricBounds(1) + 100 Then
                  ・・・複製オブジェクト(txt2)への処理・・・
                  Exit For
                  Else
                  Set txt2 = Nothing
                  End If
                  Next i

                  教えていただいておきながらえらそうに検証してしまいましたが、
                  お〜まち様のお力添えがなければとてもここまでたどり着けなかった
                  ことに変わりはなく、感謝しております。ありがとうございました。
                  • 6. Re: Duplicateの戻りオブジェクト取得方法
                    Level 1
                    >まず、最後の
                    >ind1.Select(txt1.Duplicate(Array(100, 0)))
                    >Set txt2 = ind1.Selection(1)
                    >につきましては、1行目でやはり型が一致しないというエラーが発生してしまいました。

                    悔しかったので改めて検証しました。(別にkanokoageさんに対してでなく、InDesignに対してです)
                    次のコードならきっと通るはず。

                    Dim ind1 As InDesign.Application
                    Dim doc1 As InDesign.Document
                    'Dim txt1 As InDesign.TextFrame ←ここコメントアウト
                    Dim txt2 As InDesign.TextFrame

                    Set ind1 = CreateObject("InDesign.Application.CS2_J")
                    Set doc1 = ind1.Documents("test.indd")
                    Set txt1 = doc1.TextFrames.Add
                    txt1.GeometricBounds = Array(0, 0, 100, 50)
                    txt1.Contents = "test text"
                    Set txt2 = txt1.Duplicate(Array(100, 0))
                    txt2.Contents = "test2 test2"

                    もしモジュールの最初に Option Explicit があったら削除してください。

                    InDesignではVBScriptで変数を明示的に宣言すると、エラーが発生するというケースがあったのを思い出しました。(過去にswatchで経験しています。それ以来、swatch を使用する時は変数宣言せずにいきなり使ってます)
                    今回のケースも変数を明示的に宣言したために型が一致しないというエラーが発生したものと思われます。
                    (と、もっともらしく言ってみたけどどうでしょう)
                    いすれにしろ、アプリケーションのバグには変わりないです。
                    • 7. Re: Duplicateの戻りオブジェクト取得方法
                      Level 1
                      お〜まち 様

                      アドバイス通りに宣言を外してみましたところ、意図する動作をしてくれました。いろいろとありがとうございます。

                      アプリケーションのバグや付属のリファレンスの不備など、ユーザーの力量によらないところで詰まってしまうことを、技術でいかようにもカバーできるお〜まちさんはすごいですね。