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

script search by name with the union of similar serial numbers into a group

Community Beginner ,
Apr 05, 2023 Apr 05, 2023

Copy link to clipboard

Copied

Hi, I'm trying to write a script to search and merge layers and groups by matching sequence numbers, then merge the groups and set the group name

played with chatgpt, but since I have little knowledge in javascript, nothing works =((

given:

layers and groups named:
"step_n_n"
"mask_n_n"
"back_n_n"
n = sequence number

task:
group layers and groups with similar serial numbers and name the group "[slot] step-n-n"

example.png



That's what chatgpt suggested 😃

function findSimilarStepNums() {
  var stepLayers = app.activeDocument.layers;
  varstepNums = [];
  
  // Search for all layers with a name containing "step"
  for (var i = 0; i < stepLayers.length; i++) {
    if (stepLayers[i].name.indexOf("step") !== -1) {
      // Extract the number from the layer name and add it to the array
var num = parseInt(stepLayers[i].name.match(/\d+/)[0]);
      stepNums.push(num);
    }
  }
  
  // Search for duplicate numbers
  var similarNums = [];
  for (var j = 0; j < stepNums.length; j++) {
    for (var k = j + 1; k < stepNums.length; k++) {
      if (stepNums[j] === stepNums[k]) {
        similarNums.push(stepNums[j]);
        break;
}
    }
  }
  
  // Output found duplicate numbers
  if (similarNums.length > 0) {
    alert("Found similar sequence numbers for layers named 'step': " + similarNums.join(", "));
  } else {
    alert("Similar sequence numbers were not found for layers named 'step'.");
  }
  
  // Combining layers into a group and setting a name
var slotGroup = app.activeDocument.layerSets.add();
  slotGroup.name = "[slot] step-" + (stepNums.length + 1);
  for (var l = 0; l < stepLayers.length; l++) {
    if (stepLayers[l].name.indexOf("step") !== -1) {
      stepLayers[l].move(slotGroup, ElementPlacement.INSIDE);
    }
  }
}




TOPICS
Actions and scripting , Windows

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

correct answers 1 Correct answer

Community Expert , Apr 07, 2023 Apr 07, 2023

Quite frankly I think you may want to work on your manners. 

Screenshot 2023-04-07 at 16.06.19.pngScreenshot 2023-04-07 at 16.06.30.png

 

// select selected layers the name of which ends in "_xx_xx" and group them in groups ending in the same numbers;
// 2023, use it at your own risk;
if (app.documents.length > 0) {
// search layers with regexp;
var theLayers = collectSelectedLayersByNames([/_\d{1,2}_\d{1,2}$/], 2);
// process layers;
    if (theLayers.length > 0) {
        for (var d = 0; d < theLayers.length; d++) {
            selectLayerByID(theLayers[d][0][2], fa
...

Votes

Translate

Translate
Adobe
Community Expert ,
Apr 05, 2023 Apr 05, 2023

Copy link to clipboard

Copied

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 ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

something goes wrong, throws an error

Max_red_cat_0-1680773705259.png

 

// Create a function to compare sequence numbers
function compareNumbers(a, b) {
  // Extract serial numbers from layer names
  var aNum = parseInt(a.name.match(/_(\d+)_(\d+)/)[2]);
  var bNum = parseInt(b.name.match(/_(\d+)_(\d+)/)[2]);
  // Compare numbers and return the result
  return aNum - bNum;
}

// Create an array from all layers in the document
var layers = doc.layers;

// Filter layers by given patterns and create new arrays
var stepLayers = layers.filter(function(layer) {
  return layer.name.match(/^step_\d+_\d+$/);
});
var maskLayers = layers.filter(function(layer) {
  return layer.name.match(/^mask_\d+_\d+$/);
});
var backLayers = layers.filter(function(layer) {
  return layer.name.match(/^back_\d+_\d+$/);
});

// Sort arrays by serial numbers
stepLayers.sort(compareNumbers);
maskLayers.sort(compareNumbers);
backLayers.sort(compareNumbers);

// Create groups for layers
var stepGroup = doc.layerSets.add();
stepGroup.name = "[slot] step-" + stepLayers[0].name.match(/_(\d+)_(\d+)/)[1];

// Move the layers to their respective groups
for (var i = 0; i < stepLayers.length; i++) {
  stepLayers[i].move(stepGroup, ElementPlacement.PLACEATEND);
}
for (var i = 0; i < maskLayers.length; i++) {
  maskLayers[i].move(stepGroup, ElementPlacement.PLACEATEND);
}
for (var i = 0; i < backLayers.length; i++) {
  backLayers[i].move(stepGroup, ElementPlacement.PLACEATEND);
}

 

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 ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

If you don’t define the variable »doc« then referring to it to define an Array of Layers cannot work. 

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 ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

error appeared elsewhere

Max_red_cat_0-1680785163987.png

 

// Create a function to compare sequence numbers
function compareNumbers(a, b) {
  // Extract serial numbers from layer names
  var aNum = parseInt(a.name.match(/_(\d+)_(\d+)/)[2]);
  var bNum = parseInt(b.name.match(/_(\d+)_(\d+)/)[2]);
  // Compare numbers and return the result
  return aNum - bNum;
}

// Create an array from all layers in the document
var doc = app.activeDocument;
var layers = doc.layers;

// Filter layers by given patterns and create new arrays
var stepLayers = layers.filter(function(layer) {
  return layer.name.match(/^step_\d+_\d+$/);
});
var maskLayers = layers.filter(function(layer) {
  return layer.name.match(/^mask_\d+_\d+$/);
});
var backLayers = layers.filter(function(layer) {
  return layer.name.match(/^back_\d+_\d+$/);
});

// Sort arrays by serial numbers
stepLayers.sort(compareNumbers);
maskLayers.sort(compareNumbers);
backLayers.sort(compareNumbers);

// Create groups for layers
var stepGroup = doc.layerSets.add();
stepGroup.name = "[slot] step-" + stepLayers[0].name.match(/-(\d+)-(\d+)/)[1];

// Move the layers to their respective groups
for (var i = 0; i < stepLayers.length; i++) {
  stepLayers[i].move(stepGroup, ElementPlacement.PLACEATEND);
}
for (var i = 0; i < maskLayers.length; i++) {
  maskLayers[i].move(stepGroup, ElementPlacement.PLACEATEND);
}
for (var i = 0; i < backLayers.length; i++) {
  backLayers[i].move(stepGroup, ElementPlacement.PLACEATEND);
}

 

 

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 ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

JavaScript/ExtendScript is case sensitive:

 

steplayers

 

vs

 

stepLayers

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 ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

changed L to lowercase, the error did not go away =(

// Create a function to compare sequence numbers
function compareNumbers(a, b) {
  // Extract serial numbers from layer names
  var aNum = parseInt(a.name.match(/_(\d+)_(\d+)/)[2]);
  var bNum = parseInt(b.name.match(/_(\d+)_(\d+)/)[2]);
  // Compare numbers and return the result
  return aNum - bNum;
}

// Create an array from all layers in the document
var doc = app.activeDocument;
var layers = doc.layers;

// Filter layers by given patterns and create new arrays
  var steplayers = layers.filter(function(layer) {
  });
var steplayers = layers.filter(function(layer) {
  return layer.name.match(/^step_\d+_\d+$/);
});
var masklayers = layers.filter(function(layer) {
  return layer.name.match(/^mask_\d+_\d+$/);
});
var backlayers = layers.filter(function(layer) {
  return layer.name.match(/^back_\d+_\d+$/);
});

// Sort arrays by serial numbers
steplayers.sort(compareNumbers);
masklayers.sort(compareNumbers);
backlayers.sort(compareNumbers);

// Create groups for layers
var stepGroup = doc.layerSets.add();
stepGroup.name = "[slot] step-" + stepLayers[0].name.match(/-(\d+)-(\d+)/)[1];

// Move the layers to their respective groups
for (var i = 0; i < steplayers.length; i++) {
  steplayers[i].move(stepGroup, ElementPlacement.PLACEATEND);
}
for (var i = 0; i < masklayers.length; i++) {
  masklayers[i].move(stepGroup, ElementPlacement.PLACEATEND);
}
for (var i = 0; i < backlayers.length; i++) {
  backlayers[i].move(stepGroup, ElementPlacement.PLACEATEND);
}

 

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 ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

Again: Two opening brackets with only one closing bracket cannot work. 

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 ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

sorry, can't find that bracket

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 ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

quote

sorry, can't find that bracket


By @Max_red_cat

The alert tells you which line the missing bracket is in, doesn’t it? 

Screenshot 2023-04-06 at 17.28.11.png

 

Edit: opening bracket: (

closing bracket: )

square brackets: []

curly brackets: {}

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 ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

Two opening brackets and one closing one cannot work. 

Is that more worthless ChatGPT-code? 

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 ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

Sorry, mistake on my part. 

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 ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

You can try this. 

 

// select layers the name of which ends in "_xx_xx";
// 2023, use it at your own risk;
if (app.documents.length > 0) {
// search layers with regexp;
var theLayers = collectLayersByNames([/_\d{1,2}_\d{1,2}$/], 2);
// process layers;
    if (theLayers.length > 0) {
        for (var d = 0; d < theLayers.length; d++) {
            selectLayerByID(theLayers[d][0][2], false);
            for (var e = 1; e < theLayers[d].length; e++) {
                selectLayerByID(theLayers[d][e][2], true)
                };
// group the active layer;
            groupSelectedLayers ("stuff_"+String(theLayers[d][0][0].match(/_\d{1,2}_\d{1,2}$/)));
            };
        } else {alert ("no such layer")}
    };
////////////////////////////////////
////// collect layers and/or groups with certain name, 0 layers, 1 groups, 2 both //////
function collectLayersByNames (theNames, layersOrGroups) {
// 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;
    var theCheck = false;
        switch (Number(layersOrGroups)) {
            case 0:
                if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart") {theCheck = true}
            break;
            case 1:
                if (layerSet == "layerSectionStart") {theCheck = true}
            break;
            default:
                if (layerSet != "layerSectionEnd") {theCheck = true}
            break;
        };
    if (theCheck == true && isBackground != true) {
    var theName = layerDesc.getString(stringIDToTypeID('name'));
    var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
    var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
// check name;
    for (var x = 0; x < theNames.length; x++) {
        var theNumbers = theName.match(theNames[x]);
        if (theNumbers != null) {
            var theCheck = false;
            for (var y = 0; y < theLayers.length; y++) {
                if (theNumbers == String(theLayers[y][0][0].match(theNames[x]))) {
                    theLayers[y].push([theName, theIndex, theID]);
                    theCheck = true;
                };
            };
            if (theCheck ==  false) {
                theLayers.push([[theName, theIndex, theID]])
            }
            }
        }
    };
    }
    catch (e) {};
    };
    return theLayers
    };
////// based on code by mike hale and paul riggott //////
function selectLayerByID(theID,add){ 
    add = undefined ? add = false:add 
    var ref = new ActionReference();
        ref.putIdentifier(charIDToTypeID("Lyr "), theID);
        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); 
    }
    };
////// group //////
function groupSelectedLayers (theName) {
    var desc159 = new ActionDescriptor(); 
    var ref114 = new ActionReference(); 
    var idlayer = stringIDToTypeID( "layer" );
    var idordinal = stringIDToTypeID( "ordinal" );
    var idtargetEnum = stringIDToTypeID( "targetEnum" );
    var idnull = stringIDToTypeID( "null" );
    var idname = stringIDToTypeID( "name" );
    ref114.putEnumerated(idlayer, idordinal, idtargetEnum); 
    desc159.putReference(idnull, ref114 );
    desc159.putString(idname, "aaa" );
    executeAction( stringIDToTypeID( "groupLayersEvent" ), desc159, DialogModes.NO );
    var desc63 = new ActionDescriptor();
    var ref37 = new ActionReference();
    ref37.putEnumerated( idlayer, idordinal, idtargetEnum );
    desc63.putReference( idnull, ref37 );
    var desc64 = new ActionDescriptor();
    desc64.putString(idname, theName);
    desc63.putObject(stringIDToTypeID( "to" ), idlayer, desc64);
    executeAction(stringIDToTypeID( "set" ), desc63, DialogModes.NO)
};

Screenshot 2023-04-06 at 17.25.01.pngScreenshot 2023-04-06 at 17.25.17.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 Beginner ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

oh cool!
I slightly corrected the search filter by adding (mask|back|step), so I got rid of the accidental hit of other layers with numbering

but I don't know how to fix the following problem.
now each layer is placed in its own group, but all 3 (mask, back, step) should have a group and the numbering of the new group is now "_", but you need "-"
I am attaching the screenshot and the corrected code, I hope it helps)

Max_red_cat_0-1680808428499.png

 

// select layers the name of which ends in "_xx_xx";
// 2023, use it at your own risk;
if (app.documents.length > 0) {
// search layers with regexp;
var theLayers = collectLayersByNames([/(mask|back|step)_\d{1,2}_\d{1,2}$/], 2);
// process layers;
    if (theLayers.length > 0) {
        for (var d = 0; d < theLayers.length; d++) {
            selectLayerByID(theLayers[d][0][2], false);
            for (var e = 1; e < theLayers[d].length; e++) {
                selectLayerByID(theLayers[d][e][2], true)
                };
// group the active layer;
            groupSelectedLayers ("step"+String(theLayers[d][0][0].match(/_\d{1,2}_\d{1,2}$/)));
            };
        } else {alert ("no such layer")}
    };
////////////////////////////////////
////// collect layers and/or groups with certain name, 0 layers, 1 groups, 2 both //////
function collectLayersByNames (theNames, layersOrGroups) {
// 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;
    var theCheck = false;
        switch (Number(layersOrGroups)) {
            case 0:
                if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart") {theCheck = true}
            break;
            case 1:
                if (layerSet == "layerSectionStart") {theCheck = true}
            break;
            default:
                if (layerSet != "layerSectionEnd") {theCheck = true}
            break;
        };
    if (theCheck == true && isBackground != true) {
    var theName = layerDesc.getString(stringIDToTypeID('name'));
    var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
    var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
// check name;
    for (var x = 0; x < theNames.length; x++) {
        var theNumbers = theName.match(theNames[x]);
        if (theNumbers != null) {
            var theCheck = false;
            for (var y = 0; y < theLayers.length; y++) {
                if (theNumbers == String(theLayers[y][0][0].match(theNames[x]))) {
                    theLayers[y].push([theName, theIndex, theID]);
                    theCheck = true;
                };
            };
            if (theCheck ==  false) {
                theLayers.push([[theName, theIndex, theID]])
            }
            }
        }
    };
    }
    catch (e) {};
    };
    return theLayers
    };
////// based on code by mike hale and paul riggott //////
function selectLayerByID(theID,add){ 
    add = undefined ? add = false:add 
    var ref = new ActionReference();
        ref.putIdentifier(charIDToTypeID("Lyr "), theID);
        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); 
    }
    };
////// group //////
function groupSelectedLayers (theName) {
    var desc159 = new ActionDescriptor(); 
    var ref114 = new ActionReference(); 
    var idlayer = stringIDToTypeID( "layer" );
    var idordinal = stringIDToTypeID( "ordinal" );
    var idtargetEnum = stringIDToTypeID( "targetEnum" );
    var idnull = stringIDToTypeID( "null" );
    var idname = stringIDToTypeID( "name" );
    ref114.putEnumerated(idlayer, idordinal, idtargetEnum); 
    desc159.putReference(idnull, ref114 );
    desc159.putString(idname, "aaa" );
    executeAction( stringIDToTypeID( "groupLayersEvent" ), desc159, DialogModes.NO );
    var desc63 = new ActionDescriptor();
    var ref37 = new ActionReference();
    ref37.putEnumerated( idlayer, idordinal, idtargetEnum );
    desc63.putReference( idnull, ref37 );
    var desc64 = new ActionDescriptor();
    desc64.putString(idname, theName);
    desc63.putObject(stringIDToTypeID( "to" ), idlayer, desc64);
    executeAction(stringIDToTypeID( "set" ), desc63, DialogModes.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 ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

The Script I posted collected the Layers of the same »end-numbers« (»_xx_xx«) in Arrays in the returned Array. 

You changed that so that the other name parts (»step« etc.) are included in the match and therefore the Array does not collect the Layers of corresponding numbers anymore. 

 

I would recommend to 

• either change the regExp for the collect-function back to the previous state and include a check for the other name parts in the for-clause 

        for (var d = 0; d < theLayers.length; d++) {

• or change the collect-function to do two separate matches based on two distinct arguments (the words and the numbering). 

 

Maybe someone else can provide a more efficient approach, though. 

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 ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

@Stephen_A_Marsh can you help me figure this out?

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 ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

quote

@Stephen_A_Marsh can you help me figure this out?


By @Max_red_cat

 

This is a little advanced for me, I'm glad that @c.pfaffenbichler could solve the issue!

 

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 ,
Apr 08, 2023 Apr 08, 2023

Copy link to clipboard

Copied

LATEST

You may have used anbother approach but I trust you could have achieved the intended result anyway. 

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 ,
Apr 06, 2023 Apr 06, 2023

Copy link to clipboard

Copied

Found a way to replace the "_" sign with "-":
"groupSelectedLayers("[slot] step" + String(theLayers[d][0][0].match(/_\d{1,2}_\d{1,2}$/)).replace(/_/g, "-"));"

But with the rest it is more difficult, I see 2 ways to solve it:
1. if you remove from sorting (mask|back|step), then you need the script to apply only to selected layers and groups
2. how to fix the method (mask|back|step), but I don't know how))

// select layers the name of which ends in "_xx_xx";
// 2023, use it at your own risk;
if (app.documents.length > 0) {
// search layers with regexp;
var theLayers = collectLayersByNames([/_\d{1,2}_\d{1,2}$/], 2);
// process layers;
    if (theLayers.length > 0) {
        for (var d = 0; d < theLayers.length; d++) {
            selectLayerByID(theLayers[d][0][2], false);
            for (var e = 1; e < theLayers[d].length; e++) {
                selectLayerByID(theLayers[d][e][2], true)
                };
// group the active layer;
           groupSelectedLayers("[slot] step" + String(theLayers[d][0][0].match(/_\d{1,2}_\d{1,2}$/)).replace(/_/g, "-"));
            };
        } else {alert ("no such layer")}
    };
////////////////////////////////////
////// collect layers and/or groups with certain name, 0 layers, 1 groups, 2 both //////
function collectLayersByNames (theNames, layersOrGroups) {
// 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;
    var theCheck = false;
        switch (Number(layersOrGroups)) {
            case 0:
                if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart") {theCheck = true}
            break;
            case 1:
                if (layerSet == "layerSectionStart") {theCheck = true}
            break;
            default:
                if (layerSet != "layerSectionEnd") {theCheck = true}
            break;
        };
    if (theCheck == true && isBackground != true) {
    var theName = layerDesc.getString(stringIDToTypeID('name'));
    var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
    var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
// check name;
    for (var x = 0; x < theNames.length; x++) {
        var theNumbers = theName.match(theNames[x]);
        if (theNumbers != null) {
            var theCheck = false;
            for (var y = 0; y < theLayers.length; y++) {
                if (theNumbers == String(theLayers[y][0][0].match(theNames[x]))) {
                    theLayers[y].push([theName, theIndex, theID]);
                    theCheck = true;
                };
            };
            if (theCheck ==  false) {
                theLayers.push([[theName, theIndex, theID]])
            }
            }
        }
    };
    }
    catch (e) {};
    };
    return theLayers
    };
////// based on code by mike hale and paul riggott //////
function selectLayerByID(theID,add){ 
    add = undefined ? add = false:add 
    var ref = new ActionReference();
        ref.putIdentifier(charIDToTypeID("Lyr "), theID);
        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); 
    }
    };
////// group //////
function groupSelectedLayers (theName) {
    var desc159 = new ActionDescriptor(); 
    var ref114 = new ActionReference(); 
    var idlayer = stringIDToTypeID( "layer" );
    var idordinal = stringIDToTypeID( "ordinal" );
    var idtargetEnum = stringIDToTypeID( "targetEnum" );
    var idnull = stringIDToTypeID( "null" );
    var idname = stringIDToTypeID( "name" );
    ref114.putEnumerated(idlayer, idordinal, idtargetEnum); 
    desc159.putReference(idnull, ref114 );
    desc159.putString(idname, "aaa" );
    executeAction( stringIDToTypeID( "groupLayersEvent" ), desc159, DialogModes.NO );
    var desc63 = new ActionDescriptor();
    var ref37 = new ActionReference();
    ref37.putEnumerated( idlayer, idordinal, idtargetEnum );
    desc63.putReference( idnull, ref37 );
    var desc64 = new ActionDescriptor();
    desc64.putString(idname, theName);
    desc63.putObject(stringIDToTypeID( "to" ), idlayer, desc64);
    executeAction(stringIDToTypeID( "set" ), desc63, DialogModes.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 ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

Screenshot 2023-04-07 at 09.36.42.pngScreenshot 2023-04-07 at 09.36.48.png

// select layers the name of which ends in "_xx_xx", start with some other words and group them in groups eending in the same numbers;
// 2023, use it at your own risk;
if (app.documents.length > 0) {
// search layers with regexp;
var theLayers = collectLayersByNames([/_\d{1,2}_\d{1,2}$/], /^(mask|back|step)/, 2);
// process layers;
    if (theLayers.length > 0) {
        for (var d = 0; d < theLayers.length; d++) {
            selectLayerByID(theLayers[d][0][2], false);
            for (var e = 1; e < theLayers[d].length; e++) {
                selectLayerByID(theLayers[d][e][2], true)
                };
// group the active layer;
            groupSelectedLayers ("step"+String(theLayers[d][0][0].match(/_\d{1,2}_\d{1,2}$/)));
            };
        } else {alert ("no such layer")}
    };
////////////////////////////////////
////// collect layers and/or groups with certain name, 0 layers, 1 groups, 2 both //////
function collectLayersByNames (theNames, theNames2, layersOrGroups) {
// 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;
    var theCheck = false;
        switch (Number(layersOrGroups)) {
            case 0:
                if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart") {theCheck = true}
            break;
            case 1:
                if (layerSet == "layerSectionStart") {theCheck = true}
            break;
            default:
                if (layerSet != "layerSectionEnd") {theCheck = true}
            break;
        };
    if (theCheck == true && isBackground != true) {
    var theName = layerDesc.getString(stringIDToTypeID('name'));
    var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
    var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
// check name;
    var theName2 = theName.match(theNames2);
    for (var x = 0; x < theNames.length; x++) {
        var theNumbers = theName.match(theNames[x]);
        if (theNumbers != null && theName2 != null) {
            var theCheck = false;
            for (var y = 0; y < theLayers.length; y++) {
                if (theNumbers == String(theLayers[y][0][0].match(theNames[x]))) {
                    theLayers[y].push([theName, theIndex, theID]);
                    theCheck = true;
                };
            };
            if (theCheck ==  false) {
                theLayers.push([[theName, theIndex, theID]])
            }
            }
        }
    };
    }
    catch (e) {};
    };
    return theLayers
    };
////// based on code by mike hale and paul riggott //////
function selectLayerByID(theID,add){ 
    add = undefined ? add = false:add 
    var ref = new ActionReference();
        ref.putIdentifier(charIDToTypeID("Lyr "), theID);
        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); 
    }
    };
////// group //////
function groupSelectedLayers (theName) {
    var desc159 = new ActionDescriptor(); 
    var ref114 = new ActionReference(); 
    var idlayer = stringIDToTypeID( "layer" );
    var idordinal = stringIDToTypeID( "ordinal" );
    var idtargetEnum = stringIDToTypeID( "targetEnum" );
    var idnull = stringIDToTypeID( "null" );
    var idname = stringIDToTypeID( "name" );
    ref114.putEnumerated(idlayer, idordinal, idtargetEnum); 
    desc159.putReference(idnull, ref114 );
    desc159.putString(idname, "aaa" );
    executeAction( stringIDToTypeID( "groupLayersEvent" ), desc159, DialogModes.NO );
    var desc63 = new ActionDescriptor();
    var ref37 = new ActionReference();
    ref37.putEnumerated( idlayer, idordinal, idtargetEnum );
    desc63.putReference( idnull, ref37 );
    var desc64 = new ActionDescriptor();
    desc64.putString(idname, theName);
    desc63.putObject(stringIDToTypeID( "to" ), idlayer, desc64);
    executeAction(stringIDToTypeID( "set" ), desc63, DialogModes.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 Beginner ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

cool, but I forgot about some nuances, sorry

Can you change this script so that it does not apply the action to the entire document, but only to the selected layers?...I think this will be the perfect way for the project 😃

// select layers the name of which ends in "_xx_xx";
// 2023, use it at your own risk;
if (app.documents.length > 0) {
// search layers with regexp;
var theLayers = collectLayersByNames([/_\d{1,2}_\d{1,2}$/], 2);
// process layers;
    if (theLayers.length > 0) {
        for (var d = 0; d < theLayers.length; d++) {
            selectLayerByID(theLayers[d][0][2], false);
            for (var e = 1; e < theLayers[d].length; e++) {
                selectLayerByID(theLayers[d][e][2], true)
                };
// group the active layer;
           groupSelectedLayers("[slot] step" + String(theLayers[d][0][0].match(/_\d{1,2}_\d{1,2}$/)).replace(/_/g, "-"));
            };
        } else {alert ("no such layer")}
    };
////////////////////////////////////
////// collect layers and/or groups with certain name, 0 layers, 1 groups, 2 both //////
function collectLayersByNames (theNames, layersOrGroups) {
// 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;
    var theCheck = false;
        switch (Number(layersOrGroups)) {
            case 0:
                if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart") {theCheck = true}
            break;
            case 1:
                if (layerSet == "layerSectionStart") {theCheck = true}
            break;
            default:
                if (layerSet != "layerSectionEnd") {theCheck = true}
            break;
        };
    if (theCheck == true && isBackground != true) {
    var theName = layerDesc.getString(stringIDToTypeID('name'));
    var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
    var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
// check name;
    for (var x = 0; x < theNames.length; x++) {
        var theNumbers = theName.match(theNames[x]);
        if (theNumbers != null) {
            var theCheck = false;
            for (var y = 0; y < theLayers.length; y++) {
                if (theNumbers == String(theLayers[y][0][0].match(theNames[x]))) {
                    theLayers[y].push([theName, theIndex, theID]);
                    theCheck = true;
                };
            };
            if (theCheck ==  false) {
                theLayers.push([[theName, theIndex, theID]])
            }
            }
        }
    };
    }
    catch (e) {};
    };
    return theLayers
    };
////// based on code by mike hale and paul riggott //////
function selectLayerByID(theID,add){ 
    add = undefined ? add = false:add 
    var ref = new ActionReference();
        ref.putIdentifier(charIDToTypeID("Lyr "), theID);
        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); 
    }
    };
////// group //////
function groupSelectedLayers (theName) {
    var desc159 = new ActionDescriptor(); 
    var ref114 = new ActionReference(); 
    var idlayer = stringIDToTypeID( "layer" );
    var idordinal = stringIDToTypeID( "ordinal" );
    var idtargetEnum = stringIDToTypeID( "targetEnum" );
    var idnull = stringIDToTypeID( "null" );
    var idname = stringIDToTypeID( "name" );
    ref114.putEnumerated(idlayer, idordinal, idtargetEnum); 
    desc159.putReference(idnull, ref114 );
    desc159.putString(idname, "aaa" );
    executeAction( stringIDToTypeID( "groupLayersEvent" ), desc159, DialogModes.NO );
    var desc63 = new ActionDescriptor();
    var ref37 = new ActionReference();
    ref37.putEnumerated( idlayer, idordinal, idtargetEnum );
    desc63.putReference( idnull, ref37 );
    var desc64 = new ActionDescriptor();
    desc64.putString(idname, theName);
    desc63.putObject(stringIDToTypeID( "to" ), idlayer, desc64);
    executeAction(stringIDToTypeID( "set" ), desc63, DialogModes.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 ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

Quite frankly I think you may want to work on your manners. 

Screenshot 2023-04-07 at 16.06.19.pngScreenshot 2023-04-07 at 16.06.30.png

 

// select selected layers the name of which ends in "_xx_xx" and group them in groups ending in the same numbers;
// 2023, use it at your own risk;
if (app.documents.length > 0) {
// search layers with regexp;
var theLayers = collectSelectedLayersByNames([/_\d{1,2}_\d{1,2}$/], 2);
// process layers;
    if (theLayers.length > 0) {
        for (var d = 0; d < theLayers.length; d++) {
            selectLayerByID(theLayers[d][0][2], false);
            for (var e = 1; e < theLayers[d].length; e++) {
                selectLayerByID(theLayers[d][e][2], true)
                };
// group the active layer;
            groupSelectedLayers("[slot] step" + String(theLayers[d][0][0].match(/_\d{1,2}_\d{1,2}$/)).replace(/_/g, "-"));
            };
        } else {alert ("no such layer")}
    };
////////////////////////////////////
////// based on code by mike hale and paul riggott //////
function selectLayerByID(theID,add){ 
    add = undefined ? add = false:add 
    var ref = new ActionReference();
        ref.putIdentifier(charIDToTypeID("Lyr "), theID);
        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); 
    }
    };
////// group //////
function groupSelectedLayers (theName) {
    var desc159 = new ActionDescriptor(); 
    var ref114 = new ActionReference(); 
    var idlayer = stringIDToTypeID( "layer" );
    var idordinal = stringIDToTypeID( "ordinal" );
    var idtargetEnum = stringIDToTypeID( "targetEnum" );
    var idnull = stringIDToTypeID( "null" );
    var idname = stringIDToTypeID( "name" );
    ref114.putEnumerated(idlayer, idordinal, idtargetEnum); 
    desc159.putReference(idnull, ref114 );
    desc159.putString(idname, "aaa" );
    executeAction( stringIDToTypeID( "groupLayersEvent" ), desc159, DialogModes.NO );
    var desc63 = new ActionDescriptor();
    var ref37 = new ActionReference();
    ref37.putEnumerated( idlayer, idordinal, idtargetEnum );
    desc63.putReference( idnull, ref37 );
    var desc64 = new ActionDescriptor();
    desc64.putString(idname, theName);
    desc63.putObject(stringIDToTypeID( "to" ), idlayer, desc64);
    executeAction(stringIDToTypeID( "set" ), desc63, DialogModes.NO)
};
////// collect selected layers matching names //////
function collectSelectedLayersByNames (theNames) {
// get selected layers;
    var selectedLayers = new Array;
    var ref = new ActionReference();
    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
    var desc = executeActionGet(ref);
    if (desc.getBoolean(stringIDToTypeID("hasBackgroundLayer")) == true) {var theAdd =0}
    else {var theAdd = 1};
    if( desc.hasKey( stringIDToTypeID( 'targetLayers' ) ) ){
    desc = desc.getList( stringIDToTypeID( 'targetLayers' ));
    var c = desc.count;
    var selectedLayers = new Array();
// run through selected layers;
    for(var i=0;i<c;i++){
    var theIndex = desc.getReference( i ).getIndex()+theAdd;
// get id for layers;
    try {
    var ref = new ActionReference();
    ref.putIndex( charIDToTypeID("Lyr "), theIndex ); 
    var layerDesc = executeActionGet(ref);
    var theName = layerDesc.getString(stringIDToTypeID('name'));
    var thisIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
    var theIdentifier = layerDesc.getInteger(stringIDToTypeID ("layerID"));
////////////////////////////////////
// check name;
for (var x = 0; x < theNames.length; x++) {
    var theNumbers = theName.match(theNames[x]);
    if (theNumbers != null) {
        var theCheck = false;
        for (var y = 0; y < selectedLayers.length; y++) {
            if (theNumbers == String(selectedLayers[y][0][0].match(theNames[x]))) {
                selectedLayers[y].push([theName, thisIndex, theIdentifier]);
                theCheck = true;
            };
        };
        if (theCheck ==  false) {
            selectedLayers.push([[theName, thisIndex, theIdentifier]])
        }
    }
};
////////////////////////////////////
        } catch (e) {};
        };
    // if only one:
        }else{
        alert ("only one layer selected");
        var ref = new ActionReference();
        ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
        var layerDesc = executeActionGet(ref);
        try {
        var theName = layerDesc.getString(stringIDToTypeID('name'));
        var thisIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
        var theIdentifier = layerDesc.getInteger(stringIDToTypeID ("layerID"));
////////////////////////////////////
// check name;
for (var x = 0; x < theNames.length; x++) {
    var theNumbers = theName.match(theNames[x]);
    if (theNumbers != null) {
        var theCheck = false;
        for (var y = 0; y < selectedLayers.length; y++) {
            if (theNumbers == String(selectedLayers[y][0][0].match(theNames[x]))) {
                selectedLayers[y].push([theName, thisIndex, theIdentifier]);
                theCheck = true;
            };
        };
        if (theCheck ==  false) {
            selectedLayers = [[[theName, thisIndex, theIdentifier]]]
        }
    }
};
////////////////////////////////////
        } catch (e) {};
        };
        return selectedLayers;
    };

 

 

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 ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

Thank you very much, you are the best! everything works perfect!
I'm sorry if I said something wrong, translation difficulties, English is not my native language

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 ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

No sweat, I am being nitpicky, I guess. 

 

Glad it is sorted now. 

If you should decide to delve deeper into Scripting I expect the code could still be improved for efficiency and brevity. 

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