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

PS script moving layers and folders to another folder

Community Beginner ,
Mar 25, 2023 Mar 25, 2023

Im trying to write a script that searches layer and group names for BOOK and COMP then make a new group called FINAL and move the layers and groups named BOOK and COMP into the new folder called FINAL.

This is what i have so far. The problem is only the layers BOOK and COMP are moved into the FINAL folder. I also have folders called BOOK and COMP but they are not moved.

 

// Define the search terms
var searchTerms = ["BOOK", "COMP"];

// Get a reference to the active document
var doc = app.activeDocument;

// Check if the "FINAL" group exists, and create it if it doesn't
var finalGroup;
try {
  finalGroup = doc.layerSets.getByName("FINAL");
} catch (e) {
  finalGroup = doc.layerSets.add();
  finalGroup.name = "FINAL";
}

// Loop through all layers and groups in the document
for (var i = 0; i < doc.layers.length; i++) {
  var layer = doc.layers[i];

  // Check if the layer or group name contains any of the search terms
  var nameContainsSearchTerm = false;
  for (var j = 0; j < searchTerms.length; j++) {
    if (layer.name.indexOf(searchTerms[j]) !== -1) {
      nameContainsSearchTerm = true;
      break;
    }
  }

  if (nameContainsSearchTerm) {
    // Move the layer or group into the FINAL group
    layer.move(finalGroup, ElementPlacement.INSIDE);
  }
}
TOPICS
Actions and scripting
6.7K
Translate
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 , Mar 26, 2023 Mar 26, 2023

I ignored your last point but the other things should be addressed. 

// 2023, use it at your own risk;
// Define the search terms
var searchTerms = ["BOOK", "COMP"];
// Get a reference to the active document;
var doc = app.activeDocument;
// Check if the "FINAL" group exists, and create it if it doesn't;
var finalGroup;
try {
    finalGroup = doc.layerSets.getByName("FINAL");
    doc.activeLayer = finalGroup;
} catch (e) {
    finalGroup = doc.layerSets.add();
    finalGroup.name = "FINAL";
};
v
...
Translate
Adobe
Community Expert ,
Mar 25, 2023 Mar 25, 2023

Please attach a sample PSD file, it only needs to be 1x1 px in size as this is all about the layer structure, not the canvas size. A screenshot of the layers panel that clearly illustrates the before and after result would also be helpful to those volunteering their time to help.

Translate
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 ,
Mar 26, 2023 Mar 26, 2023

Attached is a before and after PSD.

Screen shots of before and after below

Script_Before.pngScript_After.png

 

I actually want to get the FINAL folder to replace the location of the COMP folder but i can't figure out how to do that yet either.

Translate
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 ,
Mar 26, 2023 Mar 26, 2023

I ignored your last point but the other things should be addressed. 

// 2023, use it at your own risk;
// Define the search terms
var searchTerms = ["BOOK", "COMP"];
// Get a reference to the active document;
var doc = app.activeDocument;
// Check if the "FINAL" group exists, and create it if it doesn't;
var finalGroup;
try {
    finalGroup = doc.layerSets.getByName("FINAL");
    doc.activeLayer = finalGroup;
} catch (e) {
    finalGroup = doc.layerSets.add();
    finalGroup.name = "FINAL";
};
var finalId = getLayerIndex ();
// Loop through all layers and groups in the document;
var theLayers = collectLayersByNames (searchTerms);
for (var i = 0; i < theLayers.length; i++) {
    moveLayerTo(theLayers[i][2], finalId);
};
////////////////////////////////////
////// collect layers with certain name //////
function collectLayersByNames (theNames) {
    // the file;
    var myDocument = app.activeDocument;
    // get number of layers;
    var ref = new ActionReference();
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
    var applicationDesc = executeActionGet(ref);
    var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
    // process the layers;
    var theLayers = new Array;
    for (var m = 0; m <= theNumber; m++) {
    try {
    var ref = new ActionReference();
    ref.putIndex( charIDToTypeID( "Lyr " ), m);
    var layerDesc = executeActionGet(ref);
    var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
    var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
    // if group collect values;
    if (layerSet != "layerSectionEnd" /*&& layerSet != "layerSectionStart" && isBackground != true*/) {
    var theName = layerDesc.getString(stringIDToTypeID('name'));
    var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
    var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
    for (var x = 0; x < theNames.length; x++) {
        if (theName.indexOf(theNames[x]) != -1) {theLayers.push([theName, theIndex, theID])}
    }
    };
    }
    catch (e) {};
    };
    return theLayers
    };
////// move active layer in front of other layer in layer stack //////
function moveLayerTo (thisLayerId, theIndex) {
   selectLayerByID(thisLayerId, false);
var idlayer = stringIDToTypeID( "layer" );
    var desc58 = new ActionDescriptor();
        var ref19 = new ActionReference();
        ref19.putEnumerated( idlayer, stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ) );
    desc58.putReference( stringIDToTypeID( "null" ), ref19 );
        var ref20 = new ActionReference();
        ref20.putIndex( idlayer, theIndex );
    desc58.putReference( stringIDToTypeID( "to" ), ref20 );
    desc58.putBoolean( stringIDToTypeID( "adjustment" ), false );
    desc58.putInteger( stringIDToTypeID( "version" ), 5 );
        var list11 = new ActionList();
        list11.putInteger(thisLayerId);
    desc58.putList( stringIDToTypeID( "layerID" ), list11 );
executeAction( stringIDToTypeID( "move" ), desc58, DialogModes.NO );
};
////// based on code by mike hale and paul riggott //////
function selectLayerByID(index,add){ 
    add = undefined ? add = false:add 
    var ref = new ActionReference();
        ref.putIdentifier(charIDToTypeID("Lyr "), index);
        var desc = new ActionDescriptor();
        desc.putReference(charIDToTypeID("null"), ref );
            if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) ); 
            desc.putBoolean( charIDToTypeID( "MkVs" ), false ); 
        try{
        executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
    }catch(e){
    alert(e.message); 
    }
    };
////// by mike hale, via paul riggott //////
function getLayerIndex(){
    var ref = new ActionReference(); 
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('itemIndex'));
//    ref.putIdentifier(charIDToTypeID("Lyr "), theId); 
    ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt")); 
    d = executeActionGet(ref);
    return (d.getInteger(stringIDToTypeID('itemIndex'))-1); 
    };

 

Translate
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 ,
Mar 26, 2023 Mar 26, 2023

Thanks for that, it does work well.

One question though, how do you read it to understand it, also how did you create it? By moving the layers with script listener or something?

 

I wanted to edit the top line with a regex string and i just seem to break it.

Translate
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 ,
Mar 26, 2023 Mar 26, 2023
quote

Thanks for that, it does work well.

One question though, how do you read it to understand it, also how did you create it? By moving the layers with script listener or something?

And then wrapping the code in functions that take the appropriate arguments to be able to apply them efficiently. 

Also a lot of advice by the Photoshop-Scripting-old-time-regulars. 

 

quote

I wanted to edit the top line with a regex string and i just seem to break it.

If you want help with this you will have to provide more relevant information. 

Translate
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 ,
Mar 27, 2023 Mar 27, 2023

I tried to edit line 3 to this but it just breaks

var searchTerms = [(/^BOOK_[A-Za-z0-9]+_[A-Za-z0-9]+$/, /[A-Za-z0-9]+_[A-Za-z0-9]_COMP$/)];

 I need the script to be able to find BOOK and COMP with additional words before or after them seperated by an underscore.

I also tried

var searchTerms = [(/\w*COMP\w*/), (/\w*BOOK\w*/)];

But that didn't work either

Translate
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 ,
Mar 27, 2023 Mar 27, 2023

Arent’t the letters and the underscore irrelevant then, anyway? 

 

var searchTerms = [/COMP/i, /BOOK/i];
var theName = "aaaBoOK";
for (var x = 0; x < searchTerms.length; x++) {
    if (theName.match(searchTerms[x]) != undefined) {alert ("match")}
};

 

 

Translate
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 ,
Mar 27, 2023 Mar 27, 2023

I don't think i really understand it.

Using your script above i got a match alert.

 

but if i use the following line in the main script

var searchTerms = [/COMP/i, /BOOK/i];

 Then no layers are moved

Translate
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 ,
Mar 27, 2023 Mar 27, 2023

Did you change the if-clause in the function

collectLayersByNames

to check a »match« instead of »indexOf«? 

Translate
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 ,
Mar 27, 2023 Mar 27, 2023

I didn't. But if i do change the line to

        if (theName.match(theNames[x]) != -1) {theLayers.push([theName, theIndex, theID])}

 I get this error.

Screen Shot 2023-03-27 at 1.01.23 PM.png

Translate
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 ,
Mar 27, 2023 Mar 27, 2023

Why »-1«? 

Please see the if-clause in the Script I posted about 2 hours ago. 

Translate
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 ,
Mar 27, 2023 Mar 27, 2023

If i replace the whole line i get a different error.

Screen Shot 2023-03-27 at 1.24.37 PM.png

If i take the catch line out i then get another error.

Sorry, im a little lost

Translate
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 ,
Mar 27, 2023 Mar 27, 2023

Please post the Script instead of trying to describe what you changed. 

Translate
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 ,
Mar 27, 2023 Mar 27, 2023
// 2023, use it at your own risk;
// Define the search terms
//var searchTerms = [(/^BOOK_[A-Za-z0-9]+_[A-Za-z0-9]+$/, /[A-Za-z0-9]+_[A-Za-z0-9]_COMP$/)];
var searchTerms = [/COMP/i, /BOOK/i];

// Get a reference to the active document;
var doc = app.activeDocument;
// Check if the "#Comp0" group exists, and create it if it doesn't;
var finalGroup;
try {
    finalGroup = doc.layerSets.getByName("FINAL");
    doc.activeLayer = finalGroup;
} catch (e) {
    finalGroup = doc.layerSets.add();
    finalGroup.name = "FINAL";
};
var finalId = getLayerIndex ();
// Loop through all layers and groups in the document;
var theLayers = collectLayersByNames (searchTerms);
for (var i = 0; i < theLayers.length; i++) {
    moveLayerTo(theLayers[i][2], finalId);
};
////////////////////////////////////
////// collect layers with certain name //////
function collectLayersByNames (theNames) {
    // the file;
    var myDocument = app.activeDocument;
    // get number of layers;
    var ref = new ActionReference();
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
    var applicationDesc = executeActionGet(ref);
    var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
    // process the layers;
    var theLayers = new Array;
    for (var m = 0; m <= theNumber; m++) {
    try {
    var ref = new ActionReference();
    ref.putIndex( charIDToTypeID( "Lyr " ), m);
    var layerDesc = executeActionGet(ref);
    var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
    var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
    // if group collect values;
    if (layerSet != "layerSectionEnd" /*&& layerSet != "layerSectionStart" && isBackground != true*/) {
    var theName = layerDesc.getString(stringIDToTypeID('name'));
    var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
    var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
   for (var x = 0; x < searchTerms.length; x++) {
    if (theName.match(searchTerms[x]) != undefined) {alert ("match")}
    };
    }
    //catch (e) {};
    //};
    return theLayers
    };
////// move active layer in front of other layer in layer stack //////
function moveLayerTo (thisLayerId, theIndex) {
   selectLayerByID(thisLayerId, false);
var idlayer = stringIDToTypeID( "layer" );
    var desc58 = new ActionDescriptor();
        var ref19 = new ActionReference();
        ref19.putEnumerated( idlayer, stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ) );
    desc58.putReference( stringIDToTypeID( "null" ), ref19 );
        var ref20 = new ActionReference();
        ref20.putIndex( idlayer, theIndex );
    desc58.putReference( stringIDToTypeID( "to" ), ref20 );
    desc58.putBoolean( stringIDToTypeID( "adjustment" ), false );
    desc58.putInteger( stringIDToTypeID( "version" ), 5 );
        var list11 = new ActionList();
        list11.putInteger(thisLayerId);
    desc58.putList( stringIDToTypeID( "layerID" ), list11 );
executeAction( stringIDToTypeID( "move" ), desc58, DialogModes.NO );
};
////// based on code by mike hale and paul riggott //////
function selectLayerByID(index,add){ 
    add = undefined ? add = false:add 
    var ref = new ActionReference();
        ref.putIdentifier(charIDToTypeID("Lyr "), index);
        var desc = new ActionDescriptor();
        desc.putReference(charIDToTypeID("null"), ref );
            if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) ); 
            desc.putBoolean( charIDToTypeID( "MkVs" ), false ); 
        try{
        executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
    }catch(e){
    alert(e.message); 
    }
    };
////// by mike hale, via paul riggott //////
function getLayerIndex(){
    var ref = new ActionReference(); 
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('itemIndex'));
//    ref.putIdentifier(charIDToTypeID("Lyr "), theId); 
    ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt")); 
    d = executeActionGet(ref);
    return (d.getInteger(stringIDToTypeID('itemIndex'))-1); 
    };
Translate
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 ,
Mar 27, 2023 Mar 27, 2023

You

• replaced the whole line instead of the condition (the stuff in the round brackets) of the if-clause (this you would get an alert instead of a meaningful array of the layers),

• you removed a closing bracket and

• you commented out the catch of the try-clause (which naturally messes things up). 

 

// 2023, use it at your own risk;
// Define the search terms
//var searchTerms = [(/^BOOK_[A-Za-z0-9]+_[A-Za-z0-9]+$/, /[A-Za-z0-9]+_[A-Za-z0-9]_COMP$/)];
var searchTerms = [/COMP/i, /BOOK/i];

// Get a reference to the active document;
var doc = app.activeDocument;
// Check if the "#Comp0" group exists, and create it if it doesn't;
var finalGroup;
try {
    finalGroup = doc.layerSets.getByName("FINAL");
    doc.activeLayer = finalGroup;
} catch (e) {
    finalGroup = doc.layerSets.add();
    finalGroup.name = "FINAL";
};
var finalId = getLayerIndex ();
// Loop through all layers and groups in the document;
var theLayers = collectLayersByNames (searchTerms);
for (var i = 0; i < theLayers.length; i++) {
    moveLayerTo(theLayers[i][2], finalId);
};
////////////////////////////////////
////// collect layers with certain name //////
function collectLayersByNames (theNames) {
    // the file;
    var myDocument = app.activeDocument;
    // get number of layers;
    var ref = new ActionReference();
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
    var applicationDesc = executeActionGet(ref);
    var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
    // process the layers;
    var theLayers = new Array;
    for (var m = 0; m <= theNumber; m++) {
    try {
    var ref = new ActionReference();
    ref.putIndex( charIDToTypeID( "Lyr " ), m);
    var layerDesc = executeActionGet(ref);
    var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
    var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
    // if group collect values;
    if (layerSet != "layerSectionEnd" /*&& layerSet != "layerSectionStart" && isBackground != true*/) {
    var theName = layerDesc.getString(stringIDToTypeID('name'));
    var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
    var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
    for (var x = 0; x < theNames.length; x++) {
        if (theName.match(searchTerms[x]) != undefined) {theLayers.push([theName, theIndex, theID])}
    }
    };
    }
    catch (e) {};
    };
    return theLayers
    };
////// move active layer in front of other layer in layer stack //////
function moveLayerTo (thisLayerId, theIndex) {
   selectLayerByID(thisLayerId, false);
var idlayer = stringIDToTypeID( "layer" );
    var desc58 = new ActionDescriptor();
        var ref19 = new ActionReference();
        ref19.putEnumerated( idlayer, stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ) );
    desc58.putReference( stringIDToTypeID( "null" ), ref19 );
        var ref20 = new ActionReference();
        ref20.putIndex( idlayer, theIndex );
    desc58.putReference( stringIDToTypeID( "to" ), ref20 );
    desc58.putBoolean( stringIDToTypeID( "adjustment" ), false );
    desc58.putInteger( stringIDToTypeID( "version" ), 5 );
        var list11 = new ActionList();
        list11.putInteger(thisLayerId);
    desc58.putList( stringIDToTypeID( "layerID" ), list11 );
executeAction( stringIDToTypeID( "move" ), desc58, DialogModes.NO );
};
////// based on code by mike hale and paul riggott //////
function selectLayerByID(index,add){ 
    add = undefined ? add = false:add 
    var ref = new ActionReference();
        ref.putIdentifier(charIDToTypeID("Lyr "), index);
        var desc = new ActionDescriptor();
        desc.putReference(charIDToTypeID("null"), ref );
            if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) ); 
            desc.putBoolean( charIDToTypeID( "MkVs" ), false ); 
        try{
        executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
    }catch(e){
    alert(e.message); 
    }
    };
////// by mike hale, via paul riggott //////
function getLayerIndex(){
    var ref = new ActionReference(); 
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('itemIndex'));
//    ref.putIdentifier(charIDToTypeID("Lyr "), theId); 
    ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt")); 
    d = executeActionGet(ref);
    return (d.getInteger(stringIDToTypeID('itemIndex'))-1); 
    }

 

Translate
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 ,
Mar 27, 2023 Mar 27, 2023

That works great, thanks you so much!

Out of interest which lines move layers? I was trying to figure out how to move the FINAL folder to be in the location of the COMP folder (either just above or just below) but i always seem to end up with the same issue i have always had, the code to move folders that is readable and that i had before you helped doesn't work.

Translate
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 ,
Mar 28, 2023 Mar 28, 2023

The line 

moveLayerTo(theLayers[i][2], finalId);

moves one Layer (identified by its Identifier) in front of another (identified by Index). 

 

quote

I also need to understand how to only search an move root level layers and folders. I will have a situation with duplicate names inside groups which using the current script get moved out of their subfolders within COMP and end up directly inside the FINAL folder therefore breaking the structure

You can either amend the function collectLayersByNames to disregard Layers and Groups in Groups or revert back to a DOM-approach. 

Translate
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 ,
Mar 28, 2023 Mar 28, 2023

 

quote

I also need to understand how to only search an move root level layers and folders. I will have a situation with duplicate names inside groups which using the current script get moved out of their subfolders within COMP and end up directly inside the FINAL folder therefore breaking the structure

You can either amend the function collectLayersByNames to disregard Layers and Groups in Groups or revert back to a DOM-approach. 

quote

The line 

moveLayerTo(theLayers[i][2], finalId);

moves one Layer (identified by its Identifier) in front of another (identified by Index). 

 

quote

I also need to understand how to only search an move root level layers and folders. I will have a situation with duplicate names inside groups which using the current script get moved out of their subfolders within COMP and end up directly inside the FINAL folder therefore breaking the structure

You can either amend the function collectLayersByNames to disregard Layers and Groups in Groups or revert back to a DOM-approach. 


By @c.pfaffenbichler

Sorry to be a pain but i can't read it, the DOM-approach wouldn't move groups so i can't go back to that.

I can see the function collectLayerByNames is split with comments

// get number of layers;
// process the layers;
// if group collect values;

Do i need to comment out something below one of these sections?

 

Translate
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 ,
Mar 28, 2023 Mar 28, 2023

No, in AM code Groups aren’t parental to their filial Layers so much as they enclose them; so one would need to track the »layerSectionStart«-Layers against the »layerSectionEnd«-Layers and only collect the Layers and Groups at a »depth« of 0. 

 

A bit of a hassle but certainly doable with an Integer as a variable that is additionally used in the if-clause (for example). 

Start with 0, for every layerSectionStart add 1, for every layerSectionEnd subtract 1 and only push a Layer/Group’s [theName, theIndex, theID] to the Array if the number is equal to 0. 

Translate
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 ,
Mar 28, 2023 Mar 28, 2023

Your scripting skill level far exceeds that of mine. I wouldn't have a clue where to start!

Translate
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 ,
Mar 28, 2023 Mar 28, 2023
////// collect layers with certain name that are not in groups themselves //////
function collectLayersByNamesInTopLevel (theNames) {
    // the file;
    var myDocument = app.activeDocument;
    // get number of layers;
    var ref = new ActionReference();
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
    var applicationDesc = executeActionGet(ref);
    var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
    // process the layers;
    var theLayers = new Array;
    var theCounter = 0;
    for (var m = 0; m <= theNumber; m++) {
    try {
    var ref = new ActionReference();
    ref.putIndex( charIDToTypeID( "Lyr " ), m);
    var layerDesc = executeActionGet(ref);
    var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
    var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
    // if group collect values;
    if (layerSet == "layerSectionEnd") {theCounter = theCounter-1};
    if (layerSet == "layerSectionStart") {theCounter = theCounter+1};
    if (layerSet != "layerSectionEnd" /*&& layerSet != "layerSectionStart" && isBackground != true*/) {
    var theName = layerDesc.getString(stringIDToTypeID('name'));
    var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
    var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
    for (var x = 0; x < theNames.length; x++) {
        if (theName.match(searchTerms[x]) != undefined && theCounter == 0) {
            theLayers.push([theName, theIndex, theID])
        }
    };
    };
    }
    catch (e) {};
    };
    return theLayers
    };
Translate
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 ,
Mar 28, 2023 Mar 28, 2023

Thank you so much, amazing!

If only i could get it to put this FINAL folder in place of the COMP folder, the script would be complete. I've tried but i can't get my head around it

Translate
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 ,
Mar 29, 2023 Mar 29, 2023
// 2023, use it at your own risk;
// Define the search terms
var searchTerms = [/COMP/i, /BOOK/i];
// Get a reference to the active document;
var doc = app.activeDocument;
// Check if the "FINAL" group exists, and create it if it doesn't;
var finalGroup;
try {
    finalGroup = doc.layerSets.getByName("FINAL");
    doc.activeLayer = finalGroup;
} catch (e) {
    finalGroup = doc.layerSets.add();
    finalGroup.name = "FINAL";
};
//var finalId = getLayerIndex ();
// move final-group;
var theComp = collectLayersByNamesInTopLevel ([/COMP/i]);
for (var y = 0; y < theComp.length; y++) {
    if (theComp[y][3] == "layerSectionStart") {
        moveLayerTo(getLayerId (), theComp[y][1])
        }
    };
var finalId = getLayerIndex ();
// Loop through all layers and groups in the document;
var theLayers = collectLayersByNamesInTopLevel (searchTerms);
for (var i = 0; i < theLayers.length; i++) {
    moveLayerTo(theLayers[i][2], finalId);
};
////////////////////////////////////
////// collect layers with certain name that are not in groups themselves //////
function collectLayersByNamesInTopLevel (theNames) {
    // the file;
    var myDocument = app.activeDocument;
    // get number of layers;
    var ref = new ActionReference();
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
    var applicationDesc = executeActionGet(ref);
    var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
    // process the layers;
    var theLayers = new Array;
    var theCounter = 0;
    for (var m = 0; m <= theNumber; m++) {
    try {
    var ref = new ActionReference();
    ref.putIndex( charIDToTypeID( "Lyr " ), m);
    var layerDesc = executeActionGet(ref);
    var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
    var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
    // if group collect values;
    if (layerSet == "layerSectionEnd") {theCounter = theCounter-1};
    if (layerSet == "layerSectionStart") {theCounter = theCounter+1};
    if (layerSet != "layerSectionEnd" /*&& layerSet != "layerSectionStart" && isBackground != true*/) {
    var theName = layerDesc.getString(stringIDToTypeID('name'));
    var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
    var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
    for (var x = 0; x < theNames.length; x++) {
        if (theName.match(searchTerms[x]) != undefined && theCounter == 0) {
            theLayers.push([theName, theIndex, theID, layerSet])
        }
    };
    };
    }
    catch (e) {};
    };
    return theLayers
    };
////// move active layer in front of other layer in layer stack //////
function moveLayerTo (thisLayerId, theIndex) {
   selectLayerByID(thisLayerId, false);
var idlayer = stringIDToTypeID( "layer" );
    var desc58 = new ActionDescriptor();
        var ref19 = new ActionReference();
        ref19.putEnumerated( idlayer, stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ) );
    desc58.putReference( stringIDToTypeID( "null" ), ref19 );
        var ref20 = new ActionReference();
        ref20.putIndex( idlayer, theIndex );
    desc58.putReference( stringIDToTypeID( "to" ), ref20 );
    desc58.putBoolean( stringIDToTypeID( "adjustment" ), false );
    desc58.putInteger( stringIDToTypeID( "version" ), 5 );
        var list11 = new ActionList();
        list11.putInteger(thisLayerId);
    desc58.putList( stringIDToTypeID( "layerID" ), list11 );
executeAction( stringIDToTypeID( "move" ), desc58, DialogModes.NO );
};
////// based on code by mike hale and paul riggott //////
function selectLayerByID(index,add){ 
    add = undefined ? add = false:add 
    var ref = new ActionReference();
        ref.putIdentifier(charIDToTypeID("Lyr "), index);
        var desc = new ActionDescriptor();
        desc.putReference(charIDToTypeID("null"), ref );
            if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) ); 
            desc.putBoolean( charIDToTypeID( "MkVs" ), false ); 
        try{
        executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
    }catch(e){
    alert(e.message); 
    }
    };
////// by mike hale, via paul riggott //////
function getLayerIndex(){
    var ref = new ActionReference(); 
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('itemIndex'));
//    ref.putIdentifier(charIDToTypeID("Lyr "), theId); 
    ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt")); 
    d = executeActionGet(ref);
    return (d.getInteger(stringIDToTypeID('itemIndex'))-1); 
    };
////// get active layer’s id //////
function getLayerId () {
    var ref = new ActionReference();
    ref.putProperty (stringIDToTypeID ("property"), stringIDToTypeID ("layerID"));
    ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
    return executeActionGet(ref).getInteger(stringIDToTypeID("layerID"));
};
Translate
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 ,
Mar 29, 2023 Mar 29, 2023

wow! Thanks again.

could you explain how the script moves the folder. I wanted to add another new folder under the FINAL folder but I couldn't make any sense of the code.

 

have you noticed when you use breakpoints in VScode the catch doesn't seem to work when creating the final folder?

i really want to learn more but find it so difficult when the code isn't ledgable

Translate
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