• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Script to run app.menuActions on all open documents

Community Beginner ,
Sep 19, 2024 Sep 19, 2024

Copy link to clipboard

Copied

I need to run a couple menuActions on a batch of documents and I'm not sure if what I've done is correct or if maybe there's a more common way to do it. Here's my script:

 

 

for (var i = 0; app.documents.length > i; i++) {
    sortByName();
    app.activeDocument = app.documents[1]; //go to the next document
}    

function sortByName() {
    app.menuActions.itemByID(8505).invoke(); //sort p-styles
    app.menuActions.itemByID(8511).invoke(); //sort c-styles
}

 

 

This will sort all the paragraph and character styles alphabetically in all open documents. It seems to work just fine, but I'm not sure about that 3rd line.

 

I'm familiar with processing documents by their index, like app.documents[i].blahblah, but in this case, that app.menuActions would just run those menuActions over and over on the activeDocument. I need to make each document active one-by-one to run the app.menuActions, but once I've changed the activeDocument, obviously the index numbers change and my "i" value is wrong. 

 

My solution was to just run the function, then make the next document the activeDocument, over and over as many times as there are open documents. 

 

Is that a reasonable solution? Or is there some better/more common way to do this?

 

Thanks!

TOPICS
Scripting

Views

742

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Sep 20, 2024 Sep 20, 2024

@Donald32516386092f 

 

Push names of open documents into an array - then loop through this array and use string from the element to "activate" document.

 

Votes

Translate

Translate
Community Expert ,
Sep 19, 2024 Sep 19, 2024

Copy link to clipboard

Copied

I think you can set the active doc to the current doc in the iteration:

app.activeDocument = app.documents[i];

 

I don't know why you are setting it to 1. 

Run your sort func after setting the active doc to i

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 20, 2024 Sep 20, 2024

Copy link to clipboard

Copied

That doesn't work. See my reply to Charu Rajput.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 19, 2024 Sep 19, 2024

Copy link to clipboard

Copied

Hi @Donald32516386092f ,

You need to change the constant 1 to i, so that it can switch to the next document one by one and then call the sortNames function. Try the following way if that helps.

 

for (var i = 0; app.documents.length > i; i++) {
    app.activeDocument = app.documents[i]; //go to the next document
    sortByName();
}

function sortByName() {
    app.menuActions.itemByID(8505).invoke(); //sort p-styles
    app.menuActions.itemByID(8511).invoke(); //sort c-styles
}

 

Best regards

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 20, 2024 Sep 20, 2024

Copy link to clipboard

Copied

But that doesn't work. As soon as the script changes the activeDocument, the index numbers of the collection of documents change based on the new activeDocument. 

 

Consider 3 documents named Doc1, Doc2, Doc3. Doc1 is the activeDocument, index 0. Doc2 is index 1. Doc3 is index 2. The script is going to run on index 0, then 1, then 2. 

 

  1. In the first interation, Doc1 in is the active document, or app.documents[0], and the function runs on it.
  2. In the second iteration, Doc2, or app.documents[1], becomes the active document and the function runs on it.
  3. In the third iteration, app.documents[2] becomes the active document, but that index number is based on the previous iteration where Doc2 had become app.documents[0]. Once Doc2 became the active document, app.documents[2] was actually Doc 1 again.

 

That make sense?

 

Think of it this way: if you had whole bunch of documents open, it would run them like this:

 

Doc1 (The next doc is +1)

Doc2 (The next doc is +2)

Doc4 (The next doc is +3)

Doc 7 (The next doc is +4)

Doc 11 ....

 

By solution was just to process the activeDocument+1 every time. 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 20, 2024 Sep 20, 2024

Copy link to clipboard

Copied

@Donald32516386092f 

 

Push names of open documents into an array - then loop through this array and use string from the element to "activate" document.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

I suppose that would work, but it seems far more complicated than just incrementing to app.documents[1] for app.documents.length number of times. I'm still far from confident with my scripting so I figured there might be a standard solution for this case, but that's looking like a no.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

It's not complicated at all. 

 

I'm on my phone right now so can't check - but you can always go in reverse - and only process last file of the collection - of course, you would have to do it only N-times, where N=initial number of open docs. 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

Or process and close ActiveDocument untill there are no more documents to process. 

 

There is always more than one way to skin the cat 😉 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

That's pretty much how my ID-Tasker works - you get list of elements, then process them in aways way / order you want - it doesn't matter what is the order of object / texts / tables / etc. in the document or documents in InDesign - references are already taken and don't change - unless item on the list has been destroyed.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

I don't know that reverse iteration would work here since activeDoc would become doc[0]. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

quote

I don't know that reverse iteration would work here since activeDoc would become doc[0]. 


By @brian_p_dts

 

app.activeDocument = app.documents[last] ;

 

In a loop. 

 

So in the next loop - there will be a new "last" Document. 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

Good point. Another solution is: 

var ids = app.documents.everyItem().id;

//returns an array of doc ids

for each in id, activeDoc = itemByID(ids[i])

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

Though I'd just go one step further, dump all docs in a folder, and iterate through that folder, opening and closing one at a time. Less bandwidth on your computer. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

quote

Though I'd just go one step further, dump all docs in a folder, and iterate through that folder, opening and closing one at a time. Less bandwidth on your computer. 


By @brian_p_dts

 

Yeah, but this would be way more complicated than processing an array...

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

A folder is how I usually do it, but these docs are stored in a CMS so the easiest way to target them is by opening them all first. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

quote

A folder is how I usually do it, but these docs are stored in a CMS so the easiest way to target them is by opening them all first. 


By @Donald32516386092f

 

Why? 

 

How do you get them from CMS? 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

It's WoodWing. Files are checked out via a web browser or panel within InDesign which initiates a download to a local temp folder and then they open from there. If there's a way to tartget a subset of files selected within either interface, I haven't figured it out yet.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

quote

It's WoodWing. Files are checked out via a web browser or panel within InDesign which initiates a download to a local temp folder and then they open from there. If there's a way to tartget a subset of files selected within either interface, I haven't figured it out yet.


By @Donald32516386092f

 

If they need to be selected through a website - then I don't understand what you mean by targeting a subset? 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

There may be a couple thousand files that make up all the various pieces of a product, but I only want to target, say the 100 files that make up one particular piece of that product. When I work on projects stored locally, I can just target that folder full of 100 files via a filepath to that folder. But I'm working within the CMS, all that data is in the cloud and there is no filepath I can target. Only when I open those files do they get downloaded to a local folder where I can target them, but at that point they're all open so I just target them as activeDocuments.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

@Donald32516386092f

 

So can you request only those 100 files?

 

And are you saying that ALL 100s/1000s files will be open?!?! 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

Nono. If I need to process 100 files stored in the CMS, I have to work in batches of like 20 or 30 becuase they all need to be open at the same time. If it weren't in the CMS, I'd just process the whole pile one at a time via the folder path.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

quote

Nono. If I need to process 100 files stored in the CMS, I have to work in batches of like 20 or 30 becuase they all need to be open at the same time. If it weren't in the CMS, I'd just process the whole pile one at a time via the folder path.


By @Donald32516386092f

 

When I was analyzing Akeneo PIM - all the linked files - images - are stored in very long and "strange" paths on the server - not in the database itself. Database just holds info about links to the files.

 

Not sure if WoodWing would store INDD/IDML files in the database - unless they only store IDML files and use / process them as text - so the files could be stored directly on the server - so if you can login to the FTP server you could access those files directly. 

 

But first, you would have to crack their naming and how links are stored in the database - unless it's more sensible than what is in Akeneo... 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

Ah, I always forget about IDs! This would be a great solution, too.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

quote

Ah, I always forget about IDs! This would be a great solution, too.


By @Donald32516386092f

 

By ID and by Name will work exactly the same. 

 

Unless you do Revert or some other operation that will result in the change of the ID - then by Name will be much safer. 

 

On the other hand - you can do SaveAs with a new name... 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines