20 Replies Latest reply on Nov 23, 2009 9:14 PM by markr72

    ID.CS3: Make Data Merge more useful?

    sam452sam452

      Data merge is a useful function of Indesign but its scriptability is limited. I've searched this forum and found some scripts that run a pre-linked ID document. I'm trying to script the linking of fields with known text strings.

       

      Looking at the dictionary I see that the only thing that has read/write is properties.

       

      My attempt to see what properties I can read/write seems to only point to its own reference.

       

      Is this part of data merge (assignin fields to text strings) just not scriptable? thanx, sam

        • 1. Re: ID.CS3: Make Data Merge more useful?
          Olav Martin Kvern Level 3

          Hi sam452sam452,

           

          Here's an example script (in JavaScript) that creates an example text data file, marks up a text frame with text data placeholders, and then imports the data file. Does this help?

           

          //Create an example data file.
          var myTextFile = File.saveDialog("Save Data File As", undefined);
          //If the user clicked the Cancel button, the result is null.
          if(myTextFile != null){
          //Open the file with write access.
          myTextFile.open("w");
          myString = "Name\tAddress\tCity\tState\r";
          for(var myCounter = 0;myCounter< 20; myCounter++){
            myString += "Record: " + myCounter + ", Field:" + 1 + "\t";
            myString += "Record: " + myCounter + ", Field:" + 2 + "\t";
            myString += "Record: " + myCounter + ", Field:" + 3 + "\t";
            myString += "Record: " + myCounter + ", Field:" + 4 + "\r";
          }
          myTextFile.writeln(myString);
          myTextFile.close();
          }
          var myDocument = app.documents.add();
          myDocument.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.points;
          myDocument.viewPreferences.verticalMeasurementUnits = MeasurementUnits.points;
          var myPage = myDocument.pages.item(0);
          var myTextFrame = myPage.textFrames.add({geometricBounds:[72, 72, 288, 288]});
          var myString = "Name:\rAddress:\rCity:\rState:\r";
          myTextFrame.contents = myString;
          myDocument.dataMergeProperties.selectDataSource(myTextFile);
          var myDataMergeProperties= myDocument.dataMergeProperties;
          var myStory = myTextFrame.parentStory;
          var myStoryOffset = myTextFrame.lines.item(0).insertionPoints.item(-2).index;
          var myNamePlaceHolder = myDocument.dataMergeTextPlaceholders.add(myStory, myStoryOffset, myDataMergeProperties.dataMergeFields.item(0));
          myStoryOffset = myTextFrame.lines.item(1).insertionPoints.item(-2).index;
          var myAddressPlaceHolder = myDocument.dataMergeTextPlaceholders.add(myStory, myStoryOffset, myDataMergeProperties.dataMergeFields.item(1));
          myStoryOffset = myTextFrame.lines.item(2).insertionPoints.item(-2).index;
          var myCityPlaceHolder = myDocument.dataMergeTextPlaceholders.add(myStory, myStoryOffset, myDataMergeProperties.dataMergeFields.item(2));
          myStoryOffset = myTextFrame.lines.item(3).insertionPoints.item(-2).index;
          var myStatePlaceHolder = myDocument.dataMergeTextPlaceholders.add(myStory, myStoryOffset, myDataMergeProperties.dataMergeFields.item(3));
          myDocument.dataMergeProperties.mergeRecords();

           

          I'm not aware of any part of the data merge feature that isn't scriptable.

           

          Thanks,

           

          Ole

          • 2. Re: ID.CS3: Make Data Merge more useful?
            sam452sam452 Level 1

            Thank you very much for this thoughtful reply. It does work as advertised and validates my approach.

             

            The only thing I'm needing is to apply myDataMergeProperties.dataMergeFields into the equivalent in Applescript. Not to say that this javascript is not needed, it's just that for the time I have I can build this same approach into my Applescript but I'm stuck with how to apply myDataMergeProperties.dataMergeFields. As I may have mentioned earlier, the properties seem to be opaque and my attempts to understand wha properties I can use/write are blunted. I'm sure my attempt to see these dataMergeFields is right there, but I'm not using the right key to unlock them.

             

            How would I dig into myDataMergeProperties.dataMergeFields?

             

            Thanks again, sam

            • 3. Re: ID.CS3: Make Data Merge more useful?
              sam452sam452 Level 1

              For instance, based on your working javascript and the dictionary the below should work.

               

              set myTextFile to "legitimate:path:to:RA9S2S09.txt" as alias

               

              tell application "Adobe InDesign CS3"

              tell document 1

              tell data merge properties

              select data source file myTextFile

              end tell --dm properties

              end tell --doc 1

              But it fails with the error:

              "Adobe InDesign CS3 got an error: Missing required parameter 'data source file' for event 'select data source'."

               

              The dictionary says "data source file alias or text : The path to the data source file." so I'm hoping this is a simple answer as I dig into adpating this in Applescript, thanx, sam

              • 4. Re: ID.CS3: Make Data Merge more useful?
                sam452sam452 Level 1

                With a minor modification, I can get the data to be attached. Now if I can get help with the Insertion Points.

                 

                set myTextFile to "legitimate:path:to:RA9S2S09.txt" as alias

                 

                tell application "Adobe InDesign CS3"

                tell document 1

                tell data merge properties

                select data source source file myTextFile --now it works

                set myDataMergeProperties to properties.

                end tell --dm properties

                end tell --doc 1

                end tell --app
                Martin's javascript drills down to get the offset before the string that will be the Text Placeholder.
                So how to adapt what he's done to Applescript. This is how I translate it from the above:
                set nameObj to -- object reference of the string I want to use as a text placeholder
                set myStory to parent of nameObj
                set myFrame to parent text frames of nameObj
                set myNamePlaceholder to add (myStory, nameObj, (item 1 of data merge field of myDataMergeProperties))
                The last line is where it all breaks down. I'm unable to drill into the properties of data merge. It returns a circular reference to itself. How would I assign a text placeholder using a certain field and my nameObj?
                thanx, sam

                • 5. Re: ID.CS3: Make Data Merge more useful?
                  sam452sam452 Level 1

                  OK, here is my latest attempt to take what Olav's javascript uses and apply it to Applescript. I'm stuck on applying the myNamePlaceholder as notedby  by myNamePlaceholder:

                   

                  It yields no placeholder. But I believe I've done it right because I've followed the record generated when I manually make a placeholder and get the data merge text placeholders of document 1. What am I missing?

                   

                  thanx, sam

                   

                  set myTextFile to ("path:to:working:date.txt") as alias --I'm using a text file that works manually.

                   

                  tell application "Adobe InDesign CS3"

                  set {find text preferences's find what, find change text options} to {"[Sample Name]", nothing}

                  tell document 1

                  tell data merge properties

                  select data source data source file myTextFile

                  set myDataMergeProperties to properties

                  end tell

                  set allObj to (find text)

                  set objCt to count of allObj

                  repeat with thisObj from 1 to objCt

                  set NameObj to item thisObj of allObj

                  set myStory to parent of NameObj

                  set myFrame to parent text frames of NameObj

                  set NameObjOffset to item -2 of insertion points of NameObj --of myFrame

                  set dmFcount to count of every data merge field of data merge 1

                   

                  repeat with i from 1 to dmFcount

                  if field name of data merge field i of data merge 1 is "FirstName" then set myNamefield to object reference of data merge field i of data merge 1

                  end repeat --dmFcount

                  set myNamePlaceholder to {story offset:NameObjOffset, field:myNamefield}

                  set {myNamePlaceholder} to end of data merge text placeholders

                  return properties of data merge text placeholders

                  --yields {} if I have no placeholders manually made. If I have manually made a placeholder, it yields only the manually made placeholder. What am I missing?

                   

                  tell myStory

                  end tell

                  end repeat -- iterate over each instance of obj

                  end tell --doc1

                  end tell --app

                  • 6. Re: ID.CS3: Make Data Merge more useful?
                    sstanleyau Level 4

                    I suspect you need something more like:

                     

                    set myNamePlaceholder to make new data merge text placeholder at document 1 with properties {story offset:NameObjOffset, field:myNamefield}

                    --

                    Shane Stanley <sstanley@myriad-com.com.au>

                    AppleScript Pro Sessions <http://scriptingmatters.com/aspro>

                    1 person found this helpful
                    • 7. Re: ID.CS3: Make Data Merge more useful?
                      sam452sam452 Level 1

                      Thank you, thank you this is guidance that is helpful. It does get me closer and does insert a text placeholder.

                       

                      To understand what goes on, I've manually made a text placeholder and run its data merge text placeholder properties. From that record, I model it as you've seen above. What I'm finding is happening is  that it follows the insertion point, which is good, but is inserting rather than overwriting the text which is indicated by the Find(text) object. So I added the length: property to the text placeholder, which is called for in the example properties I mentione earlier. But it's still not overwriting it.

                       

                      I'm unsure of the tactical move I need to do to ensure that it's overwriting the string. I've compared the properties result for both my manual and the one generated by the script but I cannot see any difference.

                       

                      So I'm thinking:

                       

                       

                      set NameObjLength to length of NameObjOffset

                      tell characters of NameObj

                      set myNamePlaceholder to make new data merge text placeholder of document 1 with properties {story offset:NameObjOffset, field:myNamefield, parent story:myStory, length:NameObjLength}

                       

                      end tell

                       

                      And it fails to make a text placeholder. I just don't have the experience to know how to use the info from an object reference, thanx, sam

                      • 8. Re: ID.CS3: Make Data Merge more useful?
                        sstanleyau Level 4

                        If the dictionary's definition of "length" is correct, it's not going to help you.

                         

                        To be honest, the only time I've looked at data merge, I've run away fast. For a scripter, I reckon it makes much more sense to do the job using "raw" scripting -- search for placeholders, and set their contents.

                         

                        --

                        Shane Stanley <sstanley@myriad-com.com.au>

                        AppleScript Pro Sessions <http://scriptingmatters.com/aspro>

                        • 9. Re: ID.CS3: Make Data Merge more useful?
                          sam452sam452 Level 1

                          Thanks to Shane and Olav, I'm really close. I've gotten text placeholders to work. When I attempt images, I get a "Make" error, which is modeled after the working text scriptlet, properties and the dictionary.

                           

                          This works with text:

                           

                          tell "Adobe Indesign CS3"

                          tell document 1

                           

                          set ct16Obj to object reference of selected text

                          set ct16ObjOffset to offset of ct16Obj

                          set thisField to 1

                          set myStory to parent text of ct16Obj

                           

                          set myCT16Placeholder to make new data merge text placeholder with properties {story offset:ct16ObjOffset, field:(object reference of data merge field thisField of data merge 1), parent story:myStory}

                           

                          --the below errors out with "Adobe InDesign CS3 got an error: Missing required parameter 'placeholder' for event 'make'."

                           

                          --set myImagePlaceholder to make new data merge image placeholder with properties {field: ( object reference of data merge field 2 of data merge 1), parent:data merge properties}

                           

                          end tell --doc 1

                          end tell --app

                           

                          So, looking at the dictionary, I don't think I'm missing anything that would appear to help. I have a picture frame with a working data merge image placeholder and its properties are all self referenced. It doesn't list a page item, so it's not included above. The parent just calls for data merge properties of document 1. It didn't help either.

                          What am I overlooking?, thanx, sam

                          • 10. Re: ID.CS3: Make Data Merge more useful?
                            sstanleyau Level 4

                            My *guess* is that you also ned to specify the "placeholder page item" property (and you should never need to specify a parent property).

                             

                            --

                            Shane Stanley <sstanley@myriad-com.com.au>

                            AppleScript Pro Sessions <http://scriptingmatters.com/aspro>

                            • 11. Re: ID.CS3: Make Data Merge more useful?
                              sam452sam452 Level 1

                              You're right, Shane. However, my frustration is that I cannot find that property to model it. The dictionary was not a help.

                               

                              Running the below on a picture frame inside the page trim with a valid image placeholder yields: "Can't get placeholder page item of data merge field 9 of data merge 1 of document 1."

                               

                              tell application "Adobe InDesign CS3"

                              return placeholder page item of data merge field 9 of data merge 1 of document 1

                              end tell

                               

                              thanx, sam

                              • 12. Re: ID.CS3: Make Data Merge more useful?
                                guyenInDesignFakAdobe

                                Hi Olav

                                You have posted a helpful example here, I used yours to merge a external data source into indesign placeholder. But once I implement your code only the first set of entries from the source .csv file seem to be imported and displayed there is no way to browse the second ones and so on.

                                Usually if I select the data source file manually (without using script) and place the placeholders the data merge toolbar provides the prev next buttons to browse the entries, which does not seem to be happening (preview check box in toolbar is still dimmed after executing the script) if I use your script. Could you give me more hints on this? Thanks!

                                • 13. Re: ID.CS3: Make Data Merge more useful?
                                  sam452sam452 Level 1

                                  I still cannot let this go. It's the last bit of puzzle for my solution.

                                   

                                  As I stated elsewhere, I usually make an example and use AS to find its properties. I then reproduce it and figure it out. My goal is to take a list of data merge fields in an ID 3 document and iterate through each one to find its match in text and image boxes. The text works great and was my model for the image portion. But they're failing to work for the image boxes. I use a Script Label for a box that matches the field name.

                                   

                                  So to get it working, I looked again at the dictionary and constructed the following which would appear to work on paper. Perhaps some kind soul can see what I'm failing to see, thanx, sam

                                   

                                  ------ CODE begin

                                   

                                  tell application "Adobe InDesign CS3"

                                  set c to object reference of document 1

                                  set a to object reference of selection --> selected picture frame

                                  set b to object reference of data merge field 11 of data merge properties of document 1 -->found through properties of data merge of document

                                  set myImagePlaceholder to make new data merge image placeholder with properties {field:b, placeholder page item:a, parent:c} --> result: "Adobe InDesign CS3 got an error: Can't make class data merge image placeholder."

                                  end tell --app

                                   

                                  -------CODE end

                                   

                                  I've tried enclosing the imagePlaceholder within a tell block of data merge 1 of data merge properties. What should I try next?, thanx, sam

                                  • 14. Re: ID.CS3: Make Data Merge more useful?
                                    sstanleyau Level 4

                                    There's no obvious problem in your code that I can see. I suspect it just doesn't work -- file a bug.

                                    • 15. Re: ID.CS3: Make Data Merge more useful?
                                      Dirk Becker Level 4

                                      This works for me.

                                       

                                      You have to tell the parent ( document ) rather than specify it in properties

                                      The field must have the appropriate type - controlled by the "@" in the name

                                      Do not run this script twice, though. It will crash InDesign probably because the image is already taken.

                                       

                                      a b @img

                                      1 2 Desktop:datamerge:Bild.png

                                      tell application "Adobe InDesign CS3"

                                      tell active document

                                      set myPI to parent of item 1 of all graphics

                                      set fld to first data merge field of data merge properties whose field type is image field

                                      set myImagePlaceholder to make new data merge image placeholder with properties {field:fld, placeholder page item:myPI}

                                      get properties of fld

                                      end tell

                                      end tell


                                      • 16. Re: ID.CS3: Make Data Merge more useful?
                                        markr72

                                        Hi, I have 3 page document with data-merged data for 90 lines of data. I have merged the document to a 270-page document and exported to PDF just fine, but what I would really like is to have 90 separate 3-page PDF documents.

                                         

                                        Is this something that can be achieved through Javascript or Applescript? Or is there another way to split the 270-page docu up?

                                         

                                        You guys seem to know what you are doing so I thought I would ask. Thanks.

                                        • 17. Re: ID.CS3: Make Data Merge more useful?
                                          Ildhund Level 3

                                          Could Loic's scripts (3 and/or 4 of11) do what you want? He posted the link only a few hours ago:

                                           

                                          http://www.loicaigon.com/en/auto.php?goTo=2

                                           

                                          You'll need your school French to decipher the dialog...

                                           

                                          Noel

                                          • 18. Re: ID.CS3: Make Data Merge more useful?
                                            [Jongware] Most Valuable Participant

                                            I knew I'd seen something like that recently. Without looking into a dictionary, top to bottom:

                                             

                                            "Export personalized PDF - Loic Agon - 2009"

                                            "Select your export options:"

                                            "Export in series of ... pages"

                                            "Select range to be exported:"

                                            "From page .. to page .."

                                            "Select your PDF Export preset:"

                                            (.. and here you'll find the standard export presets, plus the aditional ones you created)

                                            "Select the export destination:"

                                            "Folder of this file"

                                            "Other folder"

                                            (and in the script itself, destFolder=Folder.selectDialog("Select a folder to export to");)

                                             

                                            You can safely change all of these in the javascript itself.

                                             

                                            Voila (as the French are known to say).

                                            • 19. Re: ID.CS3: Make Data Merge more useful?
                                              markr72 Level 1

                                              Thanks to the both of you for your quick reply and that useful link + translation.

                                               

                                              Script #3 is very close to what I want, however it didn't change the data merged variables with each export. If I can figure that out I'd be very happy

                                               

                                              I'm new to scripting within ID so I'm gonna give it a try and see if I can come up with anything. Maybe this is a no-brainer for someone out there, though.

                                               

                                              A specific question would be: How can I increment the record number so the content changes before each export?

                                               

                                              Thanks

                                              • 20. Re: ID.CS3: Make Data Merge more useful?
                                                markr72 Level 1

                                                Here is what I have come up with. It works to loop through and export 90 times, but I can't figure out how to increment the Record Number so that the 90 documents are actually different.

                                                 

                                                Any help is appreciated. Thank you!

                                                 

                                                ----------------

                                                 

                                                var myDocument = app.open(File("/Users/mark/Desktop/document.indd"));

                                                 

                                                // this is the number of rows in my source file, 90 in this case

                                                num_records = 90;

                                                 

                                                for(var i=0; i<num_records; i++){

                                                 

                                                     // export to PDF

                                                     myDocument.exportFile(ExportFormat.pdfType, myPDFFile, false);

                                                 

                                                     // increment index of merged data so that data from row 2 of my source data is now populated in the document

                                                     // this should be the equivalent of clicking "preview" in the Automation >> data merge panel

                                                     i++;

                                                     // I can't figure out how to do this!!! I've tried a lot of things like:

                                                     //DataMerge.dataMergePreferences.dataMergePreference.recordNumber = i;

                                                     //myDocument.DataMerge.dataMergePreferences.dataMergePreference.recordNumber = i;

                                                     //dataMergePreference.recordNumber = i;

                                                     //DataMerge.dataMergePreference.recordNumber = i;

                                                     //myDocument.DataMerge.dataMergePreference.recordNumber = i;

                                                 

                                                     // An alternative which I also can't figure out would be to increment the record Number

                                                     // and do a myDocument.dataMergeProperties.mergeRecords(); on 1 record and then export

                                                }