Skip to main content
DBarranca
Legend
September 23, 2016
Question

Targeting a layer when none is selected.

  • September 23, 2016
  • 6 replies
  • 5195 views

Hi,

this is probably so easy that I can't see it. Simple document:

Simple script that loops through layers and deletes the one that's hidden:

var doc = app.activeDocument;

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

    if (!doc.artLayers.visible) {

        doc.artLayers.remove();

    }

}

There are better ways I know, but it works.

Now try this as a starting point (no layers actually selected):

The above script fails with error "The Command Delete is not currently available".

I've added an extra line to make it active, but it doesn't (at least Photoshop CC2015.5, OSX)

var doc = app.activeDocument;

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

    if (!doc.artLayers.visible) {

        app.activeDocument.activeLayer = doc.artLayers;

        doc.artLayers.remove();

    }

}

Am I missing something here?

Thank you!

Davide

This topic has been closed for replies.

6 replies

Participant
September 16, 2022

Found the same problem after all these years... Has this bug been reported?

It happens both when no layer is selected and when all layers are selected.

So far, the solutions below work (a big thank you!), but it leaves kind of unnecessary code in the script...

Pedro Cortez Marques
Legend
May 25, 2018

Hi Davide,

I have the same error as you on the last version of Photoshop (19.1.4).

I know you said you don't want AM code, but somehow this will delete all the hidden layers with no error on the "delete".

deleteAllHiddenLayers();

function deleteAllHiddenLayers() {

  var c2t = function (s) { return app.charIDToTypeID(s); };

  var s2t = function (s) { return app.stringIDToTypeID(s); };

  var descriptor = new ActionDescriptor();

  var reference = new ActionReference();

  reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "hidden" ));

  descriptor.putReference( c2t( "null" ), reference );

  executeAction( s2t( "delete" ), descriptor, DialogModes.NO );

}

Legend
May 25, 2018

function reselect_active_layer()

    {

    var r = new ActionReference();  

    r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("layerID"));      

    r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));  

    var id = executeActionGet(r).getInteger(stringIDToTypeID("layerID"));

    var r = new ActionReference();

    r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));  

    var d = new ActionDescriptor();

    d.putReference(stringIDToTypeID("null"), r);

    try { executeAction(stringIDToTypeID("selectNoLayers"), d, DialogModes.NO); } catch(e) {}

    var r = new ActionReference();

    r.putIdentifier(stringIDToTypeID("layer"), id);

    var d = new ActionDescriptor();

    d.putReference(stringIDToTypeID("null"), r);

    d.putBoolean(stringIDToTypeID( "makeVisible"), activeDocument.activeLayer.visible);

    try { executeAction(stringIDToTypeID("select"), d, DialogModes.NO); } catch(e) {}

    }

Chuck Uebele
Community Expert
Community Expert
August 31, 2017

When you make a loop that deletes an element like a layer, you need to change what "i" is less than. The layers length is going to change as you delete layers. Put that into a variable then us that variable in the loop statement.

var Len = app.activeDocument.layers.length;

for (var i =0;i<Len;i++)

Kukurykus
Legend
September 23, 2016

I tired second case (no layer selected) with hidden layer[1] or background and it worked, but only then. The same was when I made a loop from end to beggining, so it failed when first (not bottom / background) layer was hidden.

When I checked which layer is active when none of them was selected it always said the first one, even if before I unselected any other that was below top layer. It must be bug.

It doesn't work also with simple:

activeDocument.activeLayer = activeDocument.layers[0]

no matter top layer is (in)visible, when all are unselected

it works only for any other layer beside first one in case of all (manually) unselected layers

DBarranca
DBarrancaAuthor
Legend
September 23, 2016

Let's step back and forget for a moment about the delete layer, which doesn't work if a layer (any) isn't selected.

I rephrase the issue: if no layer is selected, how do you select / make active a layer (possibly w/o ActionManager)?

Thank you,

Davide

JJMack
Community Expert
Community Expert
September 23, 2016

I can not help w/o ActionManager code. What I used was the Action Manager code for the shortcut Alt+.  Select front visible layer.

function selectFront() {

// Alt+. shortcut select ftont visible layer

var idslct = charIDToTypeID( "slct" );

    var desc250 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref207 = new ActionReference();

        var idLyr = charIDToTypeID( "Lyr " );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idFrnt = charIDToTypeID( "Frnt" );

        ref207.putEnumerated( idLyr, idOrdn, idFrnt );

    desc250.putReference( idnull, ref207 );

    var idMkVs = charIDToTypeID( "MkVs" );

    desc250.putBoolean( idMkVs, false );

executeAction( idslct, desc250, DialogModes.NO );

}

JJMack
JJMack
Community Expert
Community Expert
September 23, 2016

I do not think so.  I have had to catch that error in some scripts  when the user used the script and had nothing targeted. Even when the script was processing all layers. I had to catch that error I thought should not have happen because I was processing all layers in a recursive loop.  I had to target the top layer the use the scipt's main function to get the recursive loop to work.  I think your loop will also miss layers in layer groups that have their visibility off.

JJMack
DBarranca
DBarrancaAuthor
Legend
September 23, 2016

Hi JJMack​,

the script is for demo purposes only. The question remains – how to you select / make active *any* layer if even:

app.activeDocument.activeLayer = app.activeDocument.artLayers[0];

fails? I'd like to avoid actionmanager in this case.

Thank you!

Davide