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

Customized script to open/edit linked files is not working as expected

New Here ,
Oct 25, 2022 Oct 25, 2022

Copy link to clipboard

Copied

Dear community
I am at a loss here and can't find a solution. This is part of a script which opens linked InDesign files, changes the layer visibility on the documents placed in the opened links.

 

If I put an alert() somewhere between opening and saving the document, everything works fine. If I remove the alert() I get an error, telling me that the file is already open.  The error points to the last command in the changeLayerVisibility() Function: layer.currentVisibility = checklist[ft][k].checkedState;

 

I'm thinking it has something to do with async or timeouts. The alert slowing the process, allowing the loop to finish. But I can't understand why it would ever try to open the same file again...

 

Here's the relevant part of the script. I hope someone sees where I'm going wrong. If not I can try to create a reduced version of the thing.

 

function changeNestedLayers(linksArr) {
  var thisLink,
      thisFile,
      thisFileName,
      thisDoc;

  for (var l = 0; l < linksArr.length; l++) {
    thisLink = linksArr[l];
    thisFile = File(thisLink.filePath);
    thisFileName = thisFile.fullName;
    thisDoc = app.open(thisFile, true);

    var currentLink, 
        currentLinkname,
        currentLayer,
        currentChecklistItem;

    for(var s = 0; s < thisDoc.links.length; s++) {
      currentLink = thisDoc.links[s];
      currentLinkname = currentLink.parent.itemLink.name;

      if (currentLink.parent.constructor.name == "ImportedPage" && currentLink.parent.itemLink != null && currentLink.parent.itemLink.linkType == "InDesign Format Name") {

        if(hasSubstring(currentLinkname, "FiletypeA")) {
          changeLayerVisibility(currentLink, "FiletypeA");
          count++;
        }
        else {
          changeLayerVisibility(currentLink, "FiletypeB");
          count++;
        }
      }
    }

    thisDoc.save(new File(thisFileName));
    thisDoc.close(SaveOptions.NO);

  }
}

function changeLayerVisibility(thisLink, filetype) {
  var ft = filetype.toLowerCase();
  var layer;
  for (var k = 0; k < layertypes[ft].length; k++) {
    layer = thisLink.parent.graphicLayerOptions.graphicLayers.item(layertypes[ft][k].name);
    if (layer.isValid) {
      layer.currentVisibility = checklist[ft][k].checkedState;
    }
  }
}

 

 

Thanks!

TOPICS
Scripting

Views

1.4K

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 ,
Nov 01, 2022 Nov 01, 2022

Copy link to clipboard

Copied

That might be good. Can you share the simplified file and script that isn't working? It'll be quicker for us to troubleshoot. 
- Mark

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
New Here ,
Nov 03, 2022 Nov 03, 2022

Copy link to clipboard

Copied

Ok. So here is the simplified (well, as simple as possible) example. Open the "Overview.indd" and run the script on that file. Which should open the "Product" files and change layer visibility on placed files therein.

 

Right now apparently it only creates an error when there's a difference. So you need to uncheck something in the Dialog.

 

And here's the script, thanks for any help!

// object containing the layers we have in the different kinds of files.
var layertypes = {
    techinfo: [
      {name: "Container", showDefault: true},
      {name: "Information", showDefault: true}
      ],
    layout: [
      {name: "Badge", showDefault: true},
      {name: "Artwork", showDefault: true}
      ]
};

// stores the desired visibility.
var checklist = {
    techinfo: [],
    layout: []
    };

var doc,
    settings;

// Collection for the "Product" files we want to open.
var products = [];

var thisLink,
    thisFile,
    thisFileName,
    thisDoc,
    thisDocLinks;

var currentLink, 
    currentLinkname,
    currentLayer,
    currentChecklistItem;

var ft,
    layer;

Main();

function Main() {
  if(app.documents.length == 0){
    alert("No documents are open. Please open a document and try again.");
    exit();
  }
  else {
    doc = app.activeDocument;
    settings = saveSettings();
    app.linkingPreferences.checkLinksAtOpen = false;

    myDialog();

    restoreSettings(settings);
  }
}

// Dialog gets constructe from the layertypes object.
function myDialog() {
  var myDialog = app.dialogs.add({name:"Show / Hide Layers", canCancel: true});
  with(myDialog) {
    with(dialogColumns.add()) {
      with(dialogRows.add()) {
        staticTexts.add({ staticLabel: "Techinfo" });
        for (var i = 0; i < layertypes.techinfo.length; i++) {
          with(dialogRows.add())
            checklist.techinfo.push(checkboxControls.add({ 
              staticLabel: layertypes.techinfo[i].name, 
              checkedState: layertypes.techinfo[i].showDefault 
            }));
        }
      }
    }
    with(dialogColumns.add()) {
      with(dialogRows.add()) {
        staticTexts.add({ staticLabel: "Layout" });
        for (var i = 0; i < layertypes.layout.length; i++) {
          with(dialogRows.add())
            checklist.layout.push(checkboxControls.add({ 
              staticLabel: layertypes.layout[i].name, 
              checkedState: layertypes.layout[i].showDefault 
            }));
        }
      }
    }
  }
  if (myDialog.show() == true) {

    checkLinks(doc.links);
    
    if(products.length > 0) {
      changeNestedLayers(products);
    }

    alert("Done!");
  } else {
    myDialog.destroy();
  }
}

// The problematic function.
function changeNestedLayers(linksArr) {
  for (l = linksArr.length - 1; l >= 0; l--) {

    thisLink = linksArr[l];
    thisFile = File(thisLink.filePath);
    thisFileFullPath = thisFile.fullName;

    thisDoc = app.open(thisFile, true);
    $.writeln("Opened: " + thisFile);


    thisDocLinks = thisDoc.links;

    for(var s = thisDocLinks.length - 1; s >= 0; s--) {
      currentLink = thisDocLinks[s];
      currentLinkname = currentLink.parent.itemLink.name;

      if (currentLink.parent.constructor.name == "ImportedPage" && currentLink.parent.itemLink != null && currentLink.parent.itemLink.linkType == "InDesign Format Name") {

        if(hasSubstring(currentLinkname, "Techinfo")) {
          changeLayerVisibility(currentLink, "Techinfo");
        }
        if(hasSubstring(currentLinkname, "Layout")) {
          changeLayerVisibility(currentLink, "Layout");
        }

      }
    }

    if (thisDoc.converted) {
      thisDoc.save(File(thisFileFullPath))
    } else {
      thisDoc.save()
    }    
    $.writeln("Closing: " + thisDoc.fullName);
    thisDoc.close(SaveOptions.NO);

    if (thisLink.status == LinkStatus.LINK_OUT_OF_DATE) {
      thisLink.update();
    }
  }
}

// the other problematic function.
function changeLayerVisibility(thisLink, filetype) {
  ft = filetype.toLowerCase();
  for (var k = 0; k < layertypes[ft].length; k++) {
    layer = thisLink.parent.graphicLayerOptions.graphicLayers.item(layertypes[ft][k].name);
    if (layer.isValid) {
      $.writeln(layer.currentVisibility);
      $.writeln(checklist[ft][k].checkedState);
      // If the following line is commented out, all goes well.
      // Otherwise error, pointing to line 149. File already open...
      layer.currentVisibility = checklist[ft][k].checkedState;
    }
  }
}

// check and change layer visibility for direct links (Not in use right now).
// push products to separate list for opening (in use).
function checkLinks(linksArr) {
  for (var l = 0; l < linksArr.length; l++) {

    var thisLink = linksArr[l];
    var linkname = thisLink.parent.itemLink.name;

    if (thisLink.parent.constructor.name == "ImportedPage" && thisLink.parent.itemLink != null && thisLink.parent.itemLink.linkType == "InDesign Format Name") {

      if(hasSubstring(linkname, "Product")) {
        products.push(thisLink);
      } 
      else if(hasSubstring(linkname, "Techinfo")) {
        changeLayerVisibility(thisLink, "Techinfo");
      } 
      else if(hasSubstring(linkname, "Layout")) {
        changeLayerVisibility(thisLink, "Layout");
      } 
    }
  }
}

// Utility Functions
function hasSubstring(string, substring) {
  if(string.indexOf(substring) !== -1) return true;
}

function saveSettings() {
  var settingsTemp = {
    checkLinksAtOpen: app.linkingPreferences.checkLinksAtOpen
  };
  return settingsTemp;
}

function restoreSettings(settings) {
  app.linkingPreferences.checkLinksAtOpen = settings.checkLinksAtOpen;
  app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;
}

 

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
New Here ,
Nov 03, 2022 Nov 03, 2022

Copy link to clipboard

Copied

Ok, working a bit more with the simplified version I found out, that the thing breaks as soon as

layer.currentVisibility = checklist[ft][k].checkedState;

actually means a change to layer.currentVisibility. If both values are the same, it runs through until the end. Still no clue as to why — I've used this method on scripts for direct links a thousand times.

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
Guide ,
Oct 26, 2022 Oct 26, 2022

Copy link to clipboard

Copied

While the SaveOptions change sounds like the solution, you can solve the problem suspected with the .links collection by iterating a copy of that collection, produced by the getElements() method.

    var thisDocLinks = thisDoc.links.getElements();
    for(var s = 0; s < thisDocLinks.length; s++) {
      currentLink = thisDocLinks[s];

 

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
New Here ,
Oct 27, 2022 Oct 27, 2022

Copy link to clipboard

Copied

This could be something. I'll try it later.

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
New Here ,
Nov 03, 2022 Nov 03, 2022

Copy link to clipboard

Copied

Hey @Dirk Becker, I tried this. But apparently getElements() is not a supported method for links.

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 ,
Nov 03, 2022 Nov 03, 2022

Copy link to clipboard

Copied

Hi @dersenn ,

it's

thisDoc.links.everyItem().getElements();

 

Regards,
Uwe Laubender
( Adobe Community Expert )

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
New Here ,
Nov 04, 2022 Nov 04, 2022

Copy link to clipboard

Copied

Ah, Thanks @Laubender, will try that.

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 ,
Nov 03, 2022 Nov 03, 2022

Copy link to clipboard

Copied

Hi @dersenn, I had a bit of a look into this issue and there are some complications including a bug in Indesign. Have you had a look at this answer? It includes a great script by crazyPanda and also a bug report noted by @Laubender.

- Mark

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
New Here ,
Nov 04, 2022 Nov 04, 2022

Copy link to clipboard

Copied

Hey @m1b, thanks for looking into this. I'm pretty sure I was looking into the thread above and crazyPandas script when I did the first Versions of the script (for direct links). In the end I ended up with a modified Version for Kasyans batch processor and eventually wrote a simplified standalone version. But it has been a few years.
I will look into that thread, script and bug report in detail. Thanks!

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 ,
Nov 04, 2022 Nov 04, 2022

Copy link to clipboard

Copied

I can see the bug when I recursively open the linked ID files. With this I get 6 documents reported when only 3 are open:

 

 

var doc = app.documents[0]
getImported(doc);
alert("There are " +app.documents.length + " documents open")



/**
* Gets imported ID layers 
* @ param the document 
* @ return value 
* 
*/
function getImported(d){
    var ld, ldl, fp, fn;
    var p = d.rectangles.everyItem().importedPages.everyItem().getElements();

    for (var i = 0; i < p.length; i++){
        fp = p[i].parent.allGraphics[0].itemLink.filePath;
        fn = p[i].parent.allGraphics[0].itemLink.name;

        ld = app.open(fp);
        if (ld.links.length == 0) {
            ld.close();
        }else{
            ldl = ld.rectangles.everyItem().importedPages.everyItem().getElements();
            if (ldl.length > 0) {
                getImported(ld)
            }
        }
    };   
}

 

 

 

Screen Shot 1.png

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 ,
Nov 05, 2022 Nov 05, 2022

Copy link to clipboard

Copied

Hi Rob,

what result do you see with:

app.documents.everyItem().windows.add()

 

Regards,
Uwe Laubender
( Adobe Community Expert )

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 ,
Nov 05, 2022 Nov 05, 2022

Copy link to clipboard

Copied

Do you mean in the alert()? If I add it to the alert ID crashes.

 

If I count windows instead of documents I get the expected 3 not 6:

 

 

 

alert("There are " +app.layoutWindows.length + " documents open")

 

 

 

So you would think I could loop thru the three windows and get their parents then do something, but I continue to get the "in use" error

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 ,
Nov 11, 2022 Nov 11, 2022

Copy link to clipboard

Copied

Hi Rob,

was bussy all the week so I missed your answer.

It's not about the alert. It's just in case a document is open without a layout window.

I thought of adding a layout window to every open document could finally show all the 6 documents and not only the 3 ones you see a layout window from.

 

Regards,
Uwe Laubender
( Adobe Community Expert )

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
New Here ,
Nov 11, 2022 Nov 11, 2022

Copy link to clipboard

Copied

Hey Rob & Uwe,
I also finally had the time to quickly run this testing script. And it gets weirder every time.
First run, from ID: 6 Documents.
Second run, from ID: also 6.
Third run, from Visual Studio: 3.
Fourth run, from ID: 3.

Quit Indesign. Another run from Indesign: 8(!) Documents...

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
New Here ,
Nov 11, 2022 Nov 11, 2022

Copy link to clipboard

Copied

And now I've gotten consistently 3 as a result. Several restarts of Indesign...
Also, if I put a writeln in there:

fn = p[i].parent.allGraphics[0].itemLink.name;
$.writeln(fn);

It reports the expected 6 files:

Product 01.indd
Layout 01.indd
Techinfo A.indd
Product 02.indd
Layout 02.indd
Techinfo A.indd

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
New Here ,
Jan 26, 2023 Jan 26, 2023

Copy link to clipboard

Copied

Hi everybody. I'm back on this Issue, still with no success. But I found a Bug Report by Peter Kahrel from late 2018, which is more or less exactly the issue here. Unfortunately without any resolve. Interesting that I never saw this before.
I also worked my way through the other threads mentioned above, but since the script is working on direct links and the error messages correlate I think it's more the issue of not being able to process layers in files opened by script... but at least it's a new direction to dig in.

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 ,
Jan 27, 2023 Jan 27, 2023

Copy link to clipboard

Copied

LATEST

Thanks for the update.

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