Skip to main content
Known Participant
June 28, 2022
Answered

getByName option not working if layer is inside group

  • June 28, 2022
  • 7 replies
  • 1540 views

Hello Everyone
I have one script which move and place currently selected layer above the "LOGO" layer (LOGO is layer's name). Script is working perfectly when logo layer is not inside any group but if logo layer is inside any group this script doesn't work and give error
Error1302:NO such element 
Line:6
-> var layerRef=app.activeDocument.layers.getByName('LOGO');
What changes are required in this script ? Kindly help. I am using photoshop cs3
Below is my current script

var doc=app.activeDocument;

var moveLayer = doc.activeLayer;  

var layerRef = app.activeDocument.layers.getByName( 'LOGO' );

var targetLayer = layerRef;

moveLayer.move(targetLayer,ElementPlacement.PLACEBEFORE);  



This topic has been closed for replies.
Correct answer Chuck Uebele

Try this. You need to start with the layer you want to move selected.

#target photoshop
var doc = activeDocument;
var moveLay = doc.activeLayer
var curLayer
var targetLay
goThroughLayers (doc);

doc.activeLayer = moveLay;
moveLay.move (targetLay, ElementPlacement.PLACEBEFORE)

function goThroughLayers(parentLayer){
    for(var i=0;i<parentLayer.layers.length;i++){
        curLayer = parentLayer.layers[i];
        doc.activeLayer = curLayer;
        if(curLayer.typename =='LayerSet'){goThroughLayers (curLayer)}
        else{
            if(curLayer.name=='LOGO'){
                targetLay = curLayer}
            }//end else
        }//end for loop
    }//end function

 

7 replies

Chuck Uebele
Community Expert
Chuck UebeleCommunity ExpertCorrect answer
Community Expert
June 28, 2022

Try this. You need to start with the layer you want to move selected.

#target photoshop
var doc = activeDocument;
var moveLay = doc.activeLayer
var curLayer
var targetLay
goThroughLayers (doc);

doc.activeLayer = moveLay;
moveLay.move (targetLay, ElementPlacement.PLACEBEFORE)

function goThroughLayers(parentLayer){
    for(var i=0;i<parentLayer.layers.length;i++){
        curLayer = parentLayer.layers[i];
        doc.activeLayer = curLayer;
        if(curLayer.typename =='LayerSet'){goThroughLayers (curLayer)}
        else{
            if(curLayer.name=='LOGO'){
                targetLay = curLayer}
            }//end else
        }//end for loop
    }//end function

 

Known Participant
June 30, 2022

Thank you so much sir. Its working perfectly according to my requirements. Thanks for the big help ❤️

Stephen Marsh
Community Expert
Community Expert
June 28, 2022

This AM based function will select the first layer found by name, even if it is inside nested layer sets of the same name (it only selected layers, not groups/sets).

 

// Select layer by name, not set/group of same name
selectLayerName("LOGO");

function selectLayerName(lyrName) {
var idselect = stringIDToTypeID( "select" );
    var desc266 = new ActionDescriptor();
    var idnull = stringIDToTypeID( "null" );
        var ref59 = new ActionReference();
        var idlayer = stringIDToTypeID( "layer" );
        ref59.putName( idlayer, lyrName );
    desc266.putReference( idnull, ref59 );
    var idmakeVisible = stringIDToTypeID( "makeVisible" );
    desc266.putBoolean( idmakeVisible, false );
    var idlayerID = stringIDToTypeID( "layerID" );
        var list41 = new ActionList();
        list41.putInteger( 3 );
    desc266.putList( idlayerID, list41 );
executeAction( idselect, desc266, DialogModes.NO );
}

 

And here it is "beautified" through Clean SL:

// Select layer by name, not set/group of same name
selectLayerName("LOGO");

function selectLayerName(lyrName) {
	var s2t = function (s) {
		return app.stringIDToTypeID(s);
	};
	var descriptor = new ActionDescriptor();
	var list = new ActionList();
	var reference = new ActionReference();
	reference.putName( s2t( "layer" ), lyrName );
	descriptor.putReference( s2t( "null" ), reference );
	descriptor.putBoolean( s2t( "makeVisible" ), false );
	list.putInteger( 3 );
	descriptor.putList( s2t( "layerID" ), list );
	executeAction( s2t( "select" ), descriptor, DialogModes.NO );
}
Known Participant
June 28, 2022

Hello sir, Thanks for the reply but your code is selecting  first layer found by name, even if it is inside nested layer sets of the same name (it only selected layers, not groups/sets).
Selecting LOGO layer is not an issue. I think I am not able to convey my message properly. Please check my original post. I want to move active layer above LOGO layer. I dont want to select LOGO layer. Please check the screenshot attached. The script which is posted in main post move the activelayer above LOGO layer if LOGO layer is not inside any group. Script doesnt work if LOGO layer is inside any group. In my original LOGO layer is used as layer referenece in line 6 

var layerRef = app.activeDocument.layers.getByName( 'LOGO' ); 
I want to know how to make LOGO layer reference layer if it is inside group. Please check the screenshot attacted in my post.

)
Thanks & Regards 

Stephen Marsh
Community Expert
Community Expert
June 28, 2022

@Amelia24456658fkpp wrote:

Selecting LOGO layer is not an issue. I think I am not able to convey my message properly.


 

I thought it was as you originally wrote:

 

Script is working perfectly when logo layer is not inside any group but if logo layer is inside any group this script doesn't work and give error...

 

Apologies, there are probably better ways, however, by selecting the LOGO layer, you can get it's layer ID, then you can move your target layer to the layer ID position above the LOGO layer... Or so I was thinking, I haven't had time to test that though.

 

Looks like Chuck has come to the rescue again!

Chuck Uebele
Community Expert
Community Expert
June 28, 2022

I will have to check later, as I'maway from my computer.. There was an issue with one of the place locations that didn't work with a group. 

Chuck Uebele
Community Expert
Community Expert
June 28, 2022
Known Participant
June 28, 2022

Sir I checked the code which you mentioned. I am trying to learn. This is what I found

var doc = activeDocument;
var curLayer
goThroughLayers (doc);

function goThroughLayers(parentLayer){
    for(var i=0;i<parentLayer.layers.length;i++){
        curLayer = parentLayer.layers[i];
        doc.activeLayer = curLayer;
        if(curLayer.typename =='LayerSet'){goThroughLayers (curLayer)}
        else{
            if(curLayer.name=='LOGO'){
                if(curLayer.name.match (/[e]/ig)){alert('match')
           
           

//sorry but My question is how to place previously selected above matched layer if match found. I mean this step >> moveLayer.move(targetLayer,ElementPlacement.PLACEBEFORE);  
//How to make the matched layer Reference layer in this link or my posted code >>>> var layerRef = app.activeDocument.layers.getByName( 'LOGO' );

           
           
           
            }
                }//end if
            }//end else
        }//end loop
    }//end function

Known Participant
June 28, 2022

The script mentioned in your link is searching the LOGO layer perfectly  but I am not able to place previously selected layer above logo layer. Please check the screenshot I uploaded with my main post.

Chuck Uebele
Community Expert
Community Expert
June 28, 2022
Known Participant
June 28, 2022

Thank you sir..Let me check the link and try.

Chuck Uebele
Community Expert
Community Expert
June 28, 2022

You have to search within the group. Using AM code. To search the entire document, I generally us a recursive function that will go through all layers, and if it comes across a group, it will restart the search within that group. There are faster ways, by using AM code, but I would have to look that up, as I'm not that proficient with it.

Known Participant
June 28, 2022

Thank you @Chuck Uebele sir. Let me try few more time according to your suggestion.

Known Participant
June 28, 2022

Hello sir I found one script which select the LOGO layer no matter it is inside group or outside group but I don't know how to make it layer Reference
I mean this ///var layerRef = app.activeDocument.layers.getByName( 'LOGO' );)

here is that script

function makeLayerActiveByName(nm) {
    function cTID(s) { return app.charIDToTypeID(s); };
 
    try {
 
      var desc5 = new ActionDescriptor();
          var ref4 = new ActionReference();
          ref4.putName( cTID('Lyr '),  nm);
      desc5.putReference( cTID('null'), ref4 );
      desc5.putBoolean( cTID('MkVs'), false );
      executeAction( cTID('slct'), desc5, DialogModes.NO );
   
 
      return true;
 
   } catch (e) {
 

     return false;
 
   }
  };
 

 
   makeLayerActiveByName("LOGO");

   

(Sorry if I am trying to solve the problem in a wrong way)


Known Participant
June 28, 2022

Update : Currently selected layer could be anything like text layer, smart object layer etc