Link in Zwischenablage kopieren
Kopiert
Hello,
I am trying to sort some layers within my document alphabetically. I have some scripts that work but they sort ALL layers and I would like to be able to sort only selected layers. Here is one of the scripts I have that work. Do you have a better code or do you know what I can add to this code to make it only work on selected layers?
#target photoshop
/**
* @copyright Copyright (c) 2020 Matthew Kimber. All rights reserved.
* @author Matthew Kimber <matthew.kimber@gmail.com>
* @version 1.1
* @license Apache Software License 2.0
*/
(function(app) {
if (isDocumentOpen()) {
main();
} else {
alert("Please open a document to run this script.");
}
/**
* @Desc Program entry point. Retrieves the active document, determines if layers exist, and then sorts all ArtLayer and LayerSet objects.
*/
function main() {
var activeDoc = app.activeDocument;
if (activeDoc.layers.length > 0) {
sortLayers(activeDoc.layers);
}
}
/**
* @Desc Sorts the layers in the current LayerSet.
* @Param {Layers} layers Collection of ArtLayer and LayerSet objects in the current scope.
*/
function sortLayers(layers) {
var layerBuffer = new Array(),
index = 0;
for (index = 0; index < layers.length; index++) {
if (!layers[index].isBackgroundLayer) {
layerBuffer.push(layers[index]);
// Check to see if we need to sort groups in the current layer set.
if (typeof layers[index].layers !== "undefined" && layers[index].layers.length > 0) {
sortLayers(layers[index].layers);
}
}
}
// Sort the buffer array using built-in natural sort comparer.
layerBuffer.sort(compareWithNumbers);
// Move each layer accordingly.
for (index = 0; index < layerBuffer.length; index++) {
layerBuffer[index].move(layers[index], ElementPlacement.PLACEBEFORE);
}
}
/**
* @Desc Checks to see if there is a document open.
* @Returns {Boolean}
*/
function isDocumentOpen() {
return app.documents.length > 0;
}
}(app));
Thank you for your help!
Alright, it took me awhile, but here's a script that I hope works to sort just the selected layers. As you mentioned, the layers will be all together, so if the selected layers aren't contiguous, the script will just move all the other layer after where ever the first selected layer is located.
#target photoshop
var doc = activeDocument;
var bkgn = hasBackground ();
var topLayerID//To hold top selected layer ID
var lyrSelIDX = (getSelectedLayersIdx ())//indexes of selected layers
var orgLay
...
Link in Zwischenablage kopieren
Kopiert
Just a question, for now: if your selected layers are not contiguous, do you want the sorted layers to keep the same arrangement with non selected layers between them?
Link in Zwischenablage kopieren
Kopiert
Hey, I've only needed this feature for layers that are grouped together so I don't see that ever being important for me.
Link in Zwischenablage kopieren
Kopiert
Slowly working on a solution, unless someone else comes up with one first. I have some old code about selecting multiple layers, just have to adapt it to this situation.
Link in Zwischenablage kopieren
Kopiert
Could you please post screenshots with the pertinent Panels (Toolbar, Layers, Options Bar, …) visible for the state you start with and the result you want to get?
Hey, I've only needed this feature for layers that are grouped together so I don't see that ever being important for me.
It makes a difference for a Script so please make a meaningful and unequivocal decision.
Should all the selected Layers be arranged at the Layer Stack-position the topmost selected one, the lowermost selected one, …?
Link in Zwischenablage kopieren
Kopiert
Here is an example of what I would need.
Could you please post screenshots with the pertinent Panels (Toolbar, Layers, Options Bar, …) visible for the state you start with and the result you want to get?
Hey, I've only needed this feature for layers that are grouped together so I don't see that ever being important for me.It makes a difference for a Script so please make a meaningful and unequivocal decision.
Should all the selected Layers be arranged at the Layer Stack-position the topmost selected one, the lowermost selected one, …?
By @c.pfaffenbichler
I am sorry I thought it was clear - No I do not need the script to take other layers into account. My layers will all be grouped.
Thank you for your help!
Link in Zwischenablage kopieren
Kopiert
I should have added this to the OP for more context.
There is this old thread that has code that is supposed to work, but I receive an error that I mentioned in the comments and I havent heard back:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/sort-order-selected-layers-alphabetic...
I get some numerical value expected error. Again, more detail in the comment section on that thread. Another person commented about the same error.
Link in Zwischenablage kopieren
Kopiert
I should have added this to the OP for more context.
There is this old thread that has code that is supposed to work, but I receive an error that I mentioned in the comments and I havent heard back:
https://community.adobe.com/t5/photoshop-ecosystem-discussions/sort-order-selected-layers-alphabetic...
I get some numerical value expected error. Again, more detail in the comment section on that thread. Another person commented about the same error.
By @happyplant1111
When Adobe changed the forum software, many scripts were broken as the new forum software removed critical bits such as references to variables in square brackets, such as [i] etc.
Link in Zwischenablage kopieren
Kopiert
Alright, it took me awhile, but here's a script that I hope works to sort just the selected layers. As you mentioned, the layers will be all together, so if the selected layers aren't contiguous, the script will just move all the other layer after where ever the first selected layer is located.
#target photoshop
var doc = activeDocument;
var bkgn = hasBackground ();
var topLayerID//To hold top selected layer ID
var lyrSelIDX = (getSelectedLayersIdx ())//indexes of selected layers
var orgLayA = getLayerSetsData(lyrSelIDX)//array of selected layer names and IDs
multiSelectByIDs (topLayerID);
var topLayer = doc.activeLayer;//top selected layer
moveUpLayer ();
var upLayer = doc.activeLayer
var upLayerIDX = getSelectedLayersIdx ()
multiSelectByIDs (orgLayA[0][1])
var firstLayer = doc.activeLayer
if(upLayerIDX<lyrSelIDX[lyrSelIDX.length-1])
{firstLayer.move (doc.layers[0], ElementPlacement.PLACEBEFORE)}
else
{firstLayer.move (topLayer, ElementPlacement.PLACEBEFORE) }
var lastLayer = doc.activeLayer
for(var i=1;i<orgLayA.length;i++){
multiSelectByIDs (orgLayA[i][1]);
nextLayer = doc.activeLayer;
nextLayer.move (lastLayer, ElementPlacement.PLACEAFTER)
lastLayer = doc.activeLayer
}
function hasBackground(){// function to check if there is a background layer
var res = undefined;
try{
var ref = new ActionReference();
ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID("Nm "));
ref.putIndex( charIDToTypeID("Lyr "), 0 );
executeActionGet(ref).getString(charIDToTypeID("Nm ") );
res = true;
}catch(e){ res = false}
return res;
}
//used in getSelectedLayersIds()
function getSelectedLayersIdx(){// get the selected layers index( positon in layer editor)
var selectedLayers = new Array;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
var desc = executeActionGet(ref);
var add = 1;
if(hasBackground()){add = 0}
if( desc.hasKey( stringIDToTypeID( 'targetLayers' ) ) ){
desc = desc.getList( stringIDToTypeID( 'targetLayers' ));
var c = desc.count
var selectedLayers = new Array();
for(var i=0;i<c;i++){
selectedLayers.push( (desc.getReference( i ).getIndex()) + add);
}
}else{
var ref = new ActionReference();
ref.putProperty( charIDToTypeID('Prpr') , charIDToTypeID( 'ItmI' ));
ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
srs = hasBackground()?executeActionGet(ref).getInteger(charIDToTypeID( 'ItmI' ))-1:executeActionGet(ref).getInteger(charIDToTypeID( 'ItmI' ));
selectedLayers.push( srs);
}
return selectedLayers;
}
function getLayerSetsData(layA)
{
var lyrSetsList = []
var lyrSets = [];
for(i=0;i<layA.length;i++){
var layerSets = layA[i]
//var layerSets = 4
ref = new ActionReference();
ref.putIndex(charIDToTypeID('Lyr '), layerSets);
var d1 = executeActionGet(ref)
var c2t = function (s){return app.charIDToTypeID(s);};
var s2t = function (s){return app.stringIDToTypeID(s);};
var lyrSet = {};
lyrSet.name = d1.getString(c2t("Nm "));
lyrSet.id = d1.getInteger(s2t("layerID"));
lyrSetsList.push ([lyrSet.name,lyrSet.id])
}
topLayerID = lyrSetsList[lyrSetsList.length -1][1]
lyrSetsList.sort ()
return lyrSetsList
};
//=========
function makeLayerActiveByLayerID(id){//is this needed?
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putIdentifier( charIDToTypeID( "Lyr " ), id );
desc.putReference( charIDToTypeID( "null" ), ref );
desc.putBoolean( charIDToTypeID( "MkVs" ), false );
executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );
};
//used in multiSelectByIDs(ids)
function doesIdExists( id ){// function to check if the id exists
var res = true;
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID('Lyr '), id);
try{var desc = executeActionGet(ref)}catch(err){res = false};
return res;
}
//uses doesIdExists(id)
function multiSelectByIDs(ids) {
if( ids.constructor != Array ) ids = [ ids ];
var layers = new Array();
var id54 = charIDToTypeID( "slct" );
var desc12 = new ActionDescriptor();
var id55 = charIDToTypeID( "null" );
var ref9 = new ActionReference();
for (var i = 0; i < ids.length; i++) {
if(doesIdExists(ids[i]) == true){// a check to see if the id stil exists
layers[i] = charIDToTypeID( "Lyr " );
ref9.putIdentifier(layers[i], ids[i]);
}
}
desc12.putReference( id55, ref9 );
var id58 = charIDToTypeID( "MkVs" );
desc12.putBoolean( id58, false );
executeAction( id54, desc12, DialogModes.NO );
}
//=======================
function moveUpLayer(){
var idslct = charIDToTypeID( "slct" );
var desc3 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref1 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idFrwr = charIDToTypeID( "Frwr" );
ref1.putEnumerated( idLyr, idOrdn, idFrwr );
desc3.putReference( idnull, ref1 );
var idMkVs = charIDToTypeID( "MkVs" );
desc3.putBoolean( idMkVs, false );
var idLyrI = charIDToTypeID( "LyrI" );
var list1 = new ActionList();
list1.putInteger( 3 );
desc3.putList( idLyrI, list1 );
executeAction( idslct, desc3, DialogModes.NO );
}
Link in Zwischenablage kopieren
Kopiert
You rock Chuck! I'll give it a try tomorrow and post back. Thanks!
Link in Zwischenablage kopieren
Kopiert
Just wanted to say this script works perfectly, thank you so much!!
I was just trying to use the ones from the older thread mentioned earlier and was getting the same error as OP (on PS 23.3.1), since that thread was so old I wasn't sure if it would be possible to find one that worked. This made my day!!
Link in Zwischenablage kopieren
Kopiert
Glad it's working for you, as well.
Link in Zwischenablage kopieren
Kopiert
works flawlessly, thanks!
Link in Zwischenablage kopieren
Kopiert
Thanks! Glad it worked for you.
Link in Zwischenablage kopieren
Kopiert
Hey! I don't know if anybody is looking for help in 2024 lol, but I've managed to get a working script for selected layers, ordering A-Z or Z-A depending on which option you choose from the dialog box that pops up.
// Sort selected layers alphabetically by name with a sorting order dialog
function sortSelectedLayersByName() {
var doc = activeDocument;
var selectedLayers = getSelectedLayers();
// Show a dialog box to choose sorting order
var sortingOrder = showSortingDialog();
if (sortingOrder === null) return; // Exit if the dialog was canceled
// Sort the selected layers by name based on the chosen order
selectedLayers.sort(function (a, b) {
var comparison = a.name.toLowerCase().localeCompare(b.name.toLowerCase());
return sortingOrder === "A-Z" ? comparison : -comparison;
});
// Move each layer to its new position
for (var i = 0; i < selectedLayers.length; i++) {
selectedLayers[i].move(doc, ElementPlacement.PLACEATEND);
}
// Function to get selected layers
function getSelectedLayers() {
var selLayers = [];
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var desc = executeActionGet(ref);
if (desc.hasKey(stringIDToTypeID("targetLayers"))) {
var list = desc.getList(stringIDToTypeID("targetLayers"));
for (var i = 0; i < list.count; i++) {
var layerIndex = list.getReference(i).getIndex();
activeDocument.activeLayer = activeDocument.layers[layerIndex];
selLayers.push(activeDocument.activeLayer);
}
} else {
selLayers.push(activeDocument.activeLayer);
}
return selLayers;
}
// Function to show sorting order dialog
function showSortingDialog() {
var dialog = new Window("dialog", "Sort Layers");
dialog.orientation = "column";
dialog.alignChildren = "left";
dialog.add("statictext", undefined, "Select sorting order:");
var dropdown = dialog.add("dropdownlist", undefined, ["A-Z", "Z-A"]);
dropdown.selection = 0; // Default to "A-Z"
var buttonGroup = dialog.add("group");
buttonGroup.alignment = "right";
var okButton = buttonGroup.add("button", undefined, "OK");
var cancelButton = buttonGroup.add("button", undefined, "Cancel");
okButton.onClick = function () {
dialog.close(1);
};
cancelButton.onClick = function () {
dialog.close(0);
};
if (dialog.show() == 1) {
return dropdown.selection.text;
} else {
return null; // Dialog was canceled
}
}
}
sortSelectedLayersByName();
Cheers!
Weitere Inspirationen, Events und Ressourcen finden Sie in der neuen Adobe Community
Jetzt ansehen