Beenden
  • Globale Community
    • Sprache:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티

Get group by name

Neu hier ,
Apr 01, 2019 Apr 01, 2019

I have an array of group names and I am trying to iterate through them and get each specific group, but I am not understanding how to.

grp_name is a string that is the name of the group I wish to get.  I've tried this, but it is complaining:

app.activeDocument.activeLayer = app.activeDocument.layers.itemByName(grp_name);

app.activeDocument.activeLayer = app.activeDocument.layers.itemByName("My Group"); 

THEMEN
Aktionen und Skripte
5.6K
Übersetzen
Melden
Community-Richtlinien
Seien Sie freundlich und respektvoll, geben Sie die ursprüngliche Quelle der Inhalte an und suchen Sie vor dem Absenden Ihres Beitrags nach Duplikaten. Weitere Informationen
community guidelines

correct answers 1 richtige Antwort

Enthusiast , Apr 02, 2019 Apr 02, 2019

Oh that helps to understand what you're doing. It seems your code for "getSelectedLayers" function will do what you need without ever needing to know the layer names. Doesn't that function return an array of layer objects? If so then you have the layers you need. There is no need to know the names and then go find them again -- you already have them, in an array.

So now it all depends on what you want to do with the layers selected. For an example, let's say you want to add something to the names

...
Übersetzen
Adobe
Community Expert ,
Apr 01, 2019 Apr 01, 2019
Übersetzen
Melden
Community-Richtlinien
Seien Sie freundlich und respektvoll, geben Sie die ursprüngliche Quelle der Inhalte an und suchen Sie vor dem Absenden Ihres Beitrags nach Duplikaten. Weitere Informationen
community guidelines
Enthusiast ,
Apr 02, 2019 Apr 02, 2019

Not sure what you're trying to do but I'll guess it is to iterate through the art layers in the indicated group "My Group". If so, goes like this...

var layerSet = app.activeDocument.layers.itemByName("My Group"); // Revise as needed.

for (var i = 0; i < layerSet.layers.length; i++) {

  var layer = layerSet.layers;

  // Object 'layer' is one of the layers in the layer set (group).

  // Next time through the for loop, it will be the next layer in the layer set.

  // Do as you will with 'layer' object and let loop repeat for each.

}

Is this what you are after? Or have I misunderstood?

William Campbell
Übersetzen
Melden
Community-Richtlinien
Seien Sie freundlich und respektvoll, geben Sie die ursprüngliche Quelle der Inhalte an und suchen Sie vor dem Absenden Ihres Beitrags nach Duplikaten. Weitere Informationen
community guidelines
Neu hier ,
Apr 02, 2019 Apr 02, 2019

What exactly am I not understanding?  This seems pretty rudimentary.  It errors out no matter on line's 3 and 4...

alert(app.activeDocument.layers);  --> Just outputs the string [LAYERS] no matter what is selected

alert(app.activeDocument.activeLayer.layers);   --> Just outputs the string [LAYERS] no matter what is selected

//var myLayerset = app.activeDocument.layers.itemByName("Blah");

var myLayerset = app.activeDocument.layerSets.getByName("Blah");

blah.png

Error 1302: No such element

Line: 3

->  var myLayerset = app.activeDocument.layers.itemByName("Blah");

Error 1302: No such element

Line: 4

->  var myLayerset = app.activeDocument.layerSets.getByName("Blah");

Übersetzen
Melden
Community-Richtlinien
Seien Sie freundlich und respektvoll, geben Sie die ursprüngliche Quelle der Inhalte an und suchen Sie vor dem Absenden Ihres Beitrags nach Duplikaten. Weitere Informationen
community guidelines
Enthusiast ,
Apr 02, 2019 Apr 02, 2019

Is the group "Blah" at the top level of the document layers? Or is it inside another group? I can't tell without an image of the entire panel top to bottom. Seems it might be indented slightly (not sure) which could mean it's a sub-group (group inside another group).

If it is a sub-group, you have to first get the top group, then the group "Blah" within it, then the layers you want.

Example:

Group 1

    Layer 1

    Layer 2

    Group 2

          Layer 3

          Layer 4

To get layers 3 and 4, you have to dig down into the hierarchy some...

var group1 = app.activeDocument.layerSets.getByName("Group 1");

var group2 = group1.layerSets.getByName("Group 2");

var layer3 = group2.layers.getByName("Layer 3")

etc.

FYI it is also acceptable in the example above to use "layers" in place of "layerSets." Each object's layers collection is any kind of layer, either artLayer or LayerSet.

Does that help?

Forgive the added confusion in the last message I used "itemByName". That's InDesign. Photoshop is "getByName". I'm yanked from one to the other constantly so I slip occasionally when writing untested code snippets. Sorry about that. Use "getByName"

William Campbell
Übersetzen
Melden
Community-Richtlinien
Seien Sie freundlich und respektvoll, geben Sie die ursprüngliche Quelle der Inhalte an und suchen Sie vor dem Absenden Ihres Beitrags nach Duplikaten. Weitere Informationen
community guidelines
Neu hier ,
Apr 02, 2019 Apr 02, 2019

That stinks.  Yes, these are underneath a top most folder that I will not know the name of or be selecting.  Here is essentially what I am doing and I wasn't getting anywhere, feel free to suggest.

-Getting all selected (selected will be groups underneath a top most group)

-Iterating through all selected to perform a series of operations related to resizing

blah.png

var layers = getSelectedLayers();

alert("Layers Selected = "+layers)

//For loop on selected

for(var i=0; i<layers.length; i++) {

    grp_name = String(layers).split('LayerSet ').pop();

    grp_name = grp_name.replace(/\[|\]/g,'');

    alert(grp_name)

    //app.activeDocument.activeLayer = doc.layers.itemByName("[Blah]");

    app.activeDocument.activeLayer = app.activeDocument.layers.itemByName(grp_name);

    //Do resize stuff after this

}

function getSelectedLayers(){

  var resultLayers=new Array();

  try{

    var idGrp = stringIDToTypeID( "groupLayersEvent" );

    var descGrp = new ActionDescriptor();

    var refGrp = new ActionReference();

    refGrp.putEnumerated(charIDToTypeID( "Lyr " ),charIDToTypeID( "Ordn" ),charIDToTypeID( "Trgt" ));

    descGrp.putReference(charIDToTypeID( "null" ), refGrp );

    executeAction( idGrp, descGrp, DialogModes.NO );

    for (var ix=0;ix<app.activeDocument.activeLayer.layers.length;ix++){resultLayers.push(app.activeDocument.activeLayer.layers[ix])}

    var id8 = charIDToTypeID( "slct" );

    var desc5 = new ActionDescriptor();

    var id9 = charIDToTypeID( "null" );

    var ref2 = new ActionReference();

    var id10 = charIDToTypeID( "HstS" );

    var id11 = charIDToTypeID( "Ordn" );

    var id12 = charIDToTypeID( "Prvs" );

    ref2.putEnumerated( id10, id11, id12 );

    desc5.putReference( id9, ref2 );

    executeAction( id8, desc5, DialogModes.NO );

  } catch (err) { }

  return resultLayers;

}  

Übersetzen
Melden
Community-Richtlinien
Seien Sie freundlich und respektvoll, geben Sie die ursprüngliche Quelle der Inhalte an und suchen Sie vor dem Absenden Ihres Beitrags nach Duplikaten. Weitere Informationen
community guidelines
Community Expert ,
Apr 02, 2019 Apr 02, 2019

Recursion is need

if (!processArtLayers(activeDocument,"Blah")) alert("Blah Layer set not found:");

   

function processArtLayers(obj,lookfor) {   

found = false;

for( var i = obj.artLayers.length-1; 0 <= i; i--) {processLayers(obj.artLayers);}   

for( var i = obj.layerSets.length-1; 0 <= i; i--) {

if (obj.layerSets.name === lookfor ) {

found = true 

app.activeDocument.activeLayer = obj.layerSets

break

}

else processArtLayers(obj.layerSets,lookfor); // Process Layer Set Layers

}

return found

}  

function processLayers(layer) {  

switch (layer.kind){ 

default : break; // none process layer types catch all 

}

JJMack
Übersetzen
Melden
Community-Richtlinien
Seien Sie freundlich und respektvoll, geben Sie die ursprüngliche Quelle der Inhalte an und suchen Sie vor dem Absenden Ihres Beitrags nach Duplikaten. Weitere Informationen
community guidelines
Enthusiast ,
Apr 02, 2019 Apr 02, 2019

It's unclear what you're trying to accomplish. And the example code seems overly complicated for what should be pretty straightforward.

If you don't know the group name of the top level, that's OK. You can get there other ways. You don't have to have the name. If it's always the top group, then it easy to get by its index, which first (top) is zero.

var topGroup = app.activeDocument.layers[0]

Likewise, the bottom, usually "Background" (if flattened) is the last index (length of array minus 1). Not using names get it like this...

var background = app.activeDocument.layers[app.activeDocument.layers.length - 1]

See my reply in this thread for some ideas. Accessing all the layers in all the layer sets

Not sure if that helps, but it shows how to iterate through all layers in a document.

If you're trying to dig down and get a particular layer, here is the general idea of how to do that. Then once you have the desired layer or group in a variable to reference the object, you can do what you want with it, or to the layers it contains if a layer set (group).

var myLayer = getLayer("Blah"); // Set name as desired.

if (myLayer) {

     alert("Layer found is named: " + myLayer.name);

} else {

     alert("Didn't find the layer");

}

function getLayer(named) {

    return searchForLayer(app.activeDocument, named);

    // If returns undefined, didn't find the layer anywhere in the document.

    function searchForLayer(o, named) {

        var i;

        var layer;

        var result;

        for (i = 0; i < o.layers.length; i++) {

            layer = o.layers;

            if (layer.name == named) {

                result = layer;

                break;

            } else if (layer instanceof LayerSet) {

                // If layer set, recurse (call self).

                result = searchForLayer(layer, named);

                if (result) {

                    break;

                }

            }

        }

        return result;

    }

}

William Campbell
Übersetzen
Melden
Community-Richtlinien
Seien Sie freundlich und respektvoll, geben Sie die ursprüngliche Quelle der Inhalte an und suchen Sie vor dem Absenden Ihres Beitrags nach Duplikaten. Weitere Informationen
community guidelines
Neu hier ,
Apr 02, 2019 Apr 02, 2019

Thanks for this.  The purpose of my code was the user was selecting specific groups, then running it.  The code would first get the selected groups, throw the names of those groups into an array, and then iterate through that array one by one (obviously having to find the group again by name) to do something.

I copied the code to get selected groups because I couldn't figure out how to do that.. and I couldn't figure out how to tweak that code to fashion in my action anytime it got a selected, so I instead just utilized what it returned to find each item again by name.

The above code helps me to find based on name, which I will use.

Übersetzen
Melden
Community-Richtlinien
Seien Sie freundlich und respektvoll, geben Sie die ursprüngliche Quelle der Inhalte an und suchen Sie vor dem Absenden Ihres Beitrags nach Duplikaten. Weitere Informationen
community guidelines
Enthusiast ,
Apr 02, 2019 Apr 02, 2019

Oh that helps to understand what you're doing. It seems your code for "getSelectedLayers" function will do what you need without ever needing to know the layer names. Doesn't that function return an array of layer objects? If so then you have the layers you need. There is no need to know the names and then go find them again -- you already have them, in an array.

So now it all depends on what you want to do with the layers selected. For an example, let's say you want to add something to the names. Add this test to your script, select some layers, and launch the script.

// Assuming you've included your code for the function 'getSelectedLayers' (and it works; I haven't tested it)

var selectedLayers = getSelectedLayers();

for (var i = 0; i < selectedLayers.length; i++) {

    selectedLayers.name = selectedLayers.name + "_xx"; // Meaningless suffix just to demonstrate it is working.

    // Here in place of this demo name change anything that can be done

    // to a layer can be done to this element of the selectedLayers array.

    // The array element IS a layer object.

}

There is no need to get the names, save them anywhere, and use them to find the layers again. You should already have the layers (again, if that function is working correctly -- I haven't tried it).

Doing an alert to test if the function works isn't much use -- the result will be either undefined (if no layers are returned) or "[LAYER]", meaning, an array of LAYER objects (the correct result).

Either use the change name trick to see something happen, or do an alert this way:

alert(selectedLayers[0].name);

(the name property of the array element at index 0). It should be the name of one of the layers selected (not sure which, I'd guess top, but again not sure haven't tried your code).

See if that helps make things clearer.

William Campbell
Übersetzen
Melden
Community-Richtlinien
Seien Sie freundlich und respektvoll, geben Sie die ursprüngliche Quelle der Inhalte an und suchen Sie vor dem Absenden Ihres Beitrags nach Duplikaten. Weitere Informationen
community guidelines
Neu hier ,
Apr 02, 2019 Apr 02, 2019

I see.  Ok I am a bumbling idiot.  I thought it was simply returning the names of the layer, rather than the object.  Thanks so much.

Übersetzen
Melden
Community-Richtlinien
Seien Sie freundlich und respektvoll, geben Sie die ursprüngliche Quelle der Inhalte an und suchen Sie vor dem Absenden Ihres Beitrags nach Duplikaten. Weitere Informationen
community guidelines
Enthusiast ,
Apr 02, 2019 Apr 02, 2019
AKTUELL

Don't beat yourself up too much. I spent many years bumbling around to figure out this stuff, and I still knock my head against the desk some days. Nothing about it is easy, or always obvious. At least, before you know how it works. Only once you realize how it works then in hindsight it seems so obvious, like "Doh!" Been there myself.

Also, I am assuming your function returns layer objects, not names. Probably. The little test to change the layer names is a good way to know if it's working. Good luck!

William Campbell
Übersetzen
Melden
Community-Richtlinien
Seien Sie freundlich und respektvoll, geben Sie die ursprüngliche Quelle der Inhalte an und suchen Sie vor dem Absenden Ihres Beitrags nach Duplikaten. Weitere Informationen
community guidelines