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

Photoshop Scripting: Group Document Layers/Group Into One Group

Community Beginner ,
Feb 16, 2018 Feb 16, 2018

Copy link to clipboard

Copied

Hi,

I have a script that I'm trying to build upon and streamline. This current script works in this way:

  • Creates a new document called "Clipped Group."
  • Iterates through all open documents.
  • If there is one group in each document, and that group is called "Group 1," duplicate that group into the "Clipped Group" document.

This script works great, but it involves some setup by the user in order for it to work. The setup that I would like to eliminate is having the user go through each open document beforehand and group all of the layers they need into a group called "Group 1." I would like to just have all layers and groups added to the new "Group 1" group as they are in the document by building on my current script. This is the part of the script that works fine, but requires some setup:

var docRef = app.activeDocument;   

   

function makePackageDoc(filename) {   

    if (app.documents.length > 0) {   

        var docHeight = 4000;   

        var docWidth = 6000;   

        app.documents.add(docWidth, docHeight, 300, "Clipped Group", NewDocumentMode.RGB, DocumentFill.TRANSPARENT, 1.0, BitsPerChannelType.EIGHT, "test");   

    };   

};   

   

function moveComponentGroup() {   

    for (var i = 0; i < app.documents.length; i++) {  //Script iterates through all open documents.   

        docRef = app.documents;

        if (docRef.name == "Clipped Group") {

            continue;   

        };   

        var x = docRef.layerSets.length;   

        if ((x > 0) && (docRef.layerSets[0].name == "Group 1" )) {   

            app.activeDocument = docRef; 

            docRef.layerSets[0].duplicate(app.documents["Clipped Group"].layers[0], ElementPlacement.PLACEBEFORE);        

        };   

    };   

};   

   

makePackageDoc("Clipped Group");   

moveComponentGroup();

Here is what I've come up with in trying to get write the script so that it instead automatically groups all of the current document's layers and groups (as they are) into a new group:

var docRef = app.activeDocument;   

   

function makePackageDoc(filename) {   

    if (app.documents.length > 0) {   

        var docHeight = 4000;   

        var docWidth = 6000;   

        app.documents.add(docWidth, docHeight, 300, "Clipped Group", NewDocumentMode.RGB, DocumentFill.TRANSPARENT, 1.0, BitsPerChannelType.EIGHT, "test");   

    };   

};

function groupLayers () {

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

       

        var newGroup = docRef.layerSets.add();

        newGroup.name = "New Group";

       

        var numOfLayers = docRef.layers.length;

       

        for (var k = 0; k < numOfLayers; k++) {

            var currentLayer = docRef.layers;

            if (currentLayer.name != "New Group" ) {

                docRef.layerSets["New Group"].move(currentLayer, ElementPlacement.INSIDE);

            };

        };

    };

};

   

function moveComponentGroup() {   

    for (var i = 0; i < app.documents.length; i++) {  //Script iterates through all open documents.   

        docRef = app.documents;

        if (docRef.name == "Clipped Group") {

            continue;   

        };   

        var x = docRef.layerSets.length;   

        if ((x > 0) && (docRef.layerSets[0].name == "New Group" )) {   

            app.activeDocument = docRef; 

            docRef.layerSets[0].duplicate(app.documents["Clipped Group"].layers[0], ElementPlacement.PLACEBEFORE);        

        };   

    };   

};

groupLayers();

makePackageDoc("Clipped Group");

moveComponentGroup();

It's definitely getting messed up in the groupLayers function, but I'm quite stuck and can't figure out how to fix this. I think part of the issue is that I'm not sure how to reference the "New Group" group in order to move the layers/groups into it. Am I on the right track? Any advice would be appreciated. Txhank you.

TOPICS
Actions and scripting

Views

6.1K

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
Adobe
Contributor ,
Feb 17, 2018 Feb 17, 2018

Copy link to clipboard

Copied

Hi,

Please be conscious of the scope of variables. "docRef" variable is strange.

And, The target will be reverse.

// Bad: Put a layerset in the layer.

docRef.layerSets["New Group"].move(currentLayer, ElementPlacement.INSIDE);

// OK: Put a layer in the layerset.

currentLayer.move(docRef.layerSets["New Group"], ElementPlacement.INSIDE);

Does this following script work fine?

(function () {

   

    var DOCUMENT_NAME = 'Clipped Group',

        GROUP_NAME = 'New Group';

   

    function makePackageDoc(filename) {

        var docHeight = 4000,

            docWidth = 6000;

        if (app.documents.length > 0) {

            app.documents.add(docWidth, docHeight, 300, filename, NewDocumentMode.RGB, DocumentFill.TRANSPARENT, 1.0, BitsPerChannelType.EIGHT, "test");

        }

    }

    function groupLayers() {

        var i,

            max;

       

        function collect(docRef) {

            var newGroup,

                i,

                min;

            app.activeDocument = docRef;

            newGroup = docRef.layerSets.add();

            newGroup.name = GROUP_NAME;

            for (i = docRef.layers.length - 1, min = 0; min < i; i -= 1) {

                docRef.layers.move(newGroup, ElementPlacement.INSIDE);

            }

        }

       

        for (i = 0, max = app.documents.length; i < max; i += 1) {

            collect(app.documents);

        }

    }

    function moveComponentGroup() {

        var docRef,

            i,

            max;

        for (i = 0, max = app.documents.length; i < max; i += 1) {

            docRef = app.documents;

            if (docRef.name === DOCUMENT_NAME) {

                continue;

            }

            if ((docRef.layerSets.length > 0) && (docRef.layerSets[0].name === GROUP_NAME)) {

                app.activeDocument = docRef;

                docRef.layerSets[0].duplicate(app.documents[DOCUMENT_NAME].layers[0], ElementPlacement.PLACEBEFORE);

            }

        }

    }

    function main() {

        groupLayers();

        makePackageDoc(DOCUMENT_NAME);

        moveComponentGroup();

    }

   

    main();

   

}());

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 ,
Feb 21, 2018 Feb 21, 2018

Copy link to clipboard

Copied

Thanks for the input OMOTI. I tried to use the script you gave, but it runs into an error on Line 30 whenever I try to run it: "Undefined is not an object." I think I can still glean some useful things from your input though, especially since I was reversing the target you mentioned above.

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
Contributor ,
Feb 21, 2018 Feb 21, 2018

Copy link to clipboard

Copied

Hi,

Please open one or more documents and execute the script.

The layers of these opened documents are duplicated to the new document 'Clipped Group'.

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 ,
Feb 22, 2018 Feb 22, 2018

Copy link to clipboard

Copied

Hi OMOTI,

Whoops, I wasn't executing the script correctly. I no longer get the error "Undefined is not an object" when I execute, but I did get an error based on line 26 that indicated that if there is a "Background" layer, this layer can't be moved like normal layers. This shouldn't be an issue for me since I can ignore "Background" layers in my particular workflow for this, so I added an exception to the for loop to skip trying to move that layer:

for (i = docRef.layers.length - 1, min = 0; min < i; i -= 1) {

    if (docRef.layers.name == "Background") {

        continue;

    } else {

        docRef.layers.move(newGroup, ElementPlacement.INSIDE);

I was able to run the script again when I added that exception, but then I got an error at the very end of the script:

}());  // error: ) does not have a value


In any case, the script errors out and nothing happens in Ps, though I'm testing on a group of images with many layers and layersets. Does the exception I added make sense? And should there be a value added to the final parentheses?

Thanks for all the help.

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
Contributor ,
Feb 23, 2018 Feb 23, 2018

Copy link to clipboard

Copied

Hi mollys,

Close, but not right.

docRef.layers is 'Layers'.

docRef.layers is 'Layer'.

Does it work as follows?

for (i = docRef.layers.length - 1, min = 0; min < i; i -= 1) {

    if (docRef.layers.name === "Background") {

        continue;

    } else {

        docRef.layers.move(newGroup, ElementPlacement.INSIDE);

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 ,
Feb 23, 2018 Feb 23, 2018

Copy link to clipboard

Copied

OMOTI, of course, that makes way more sense, thank you. I updated the script again to include that change. I tried running it again with some complex PSDs open in Ps, but I still get an error on the final line. I included the script again with changes below, and the error coming up at line 63. Any thoughts on this? Thanks again.

(function () { 

     

    var DOCUMENT_NAME = 'Clipped Group', 

        GROUP_NAME = 'New Group'; 

     

    function makePackageDoc(filename) { 

        var docHeight = 4000, 

            docWidth = 6000; 

        if (app.documents.length > 0) { 

            app.documents.add(docWidth, docHeight, 300, filename, NewDocumentMode.RGB, DocumentFill.TRANSPARENT, 1.0, BitsPerChannelType.EIGHT, "test"); 

        } 

    } 

 

    function groupLayers() { 

        var i, 

            max; 

         

        function collect(docRef) { 

            var newGroup, 

                i, 

                min; 

            app.activeDocument = docRef; 

            newGroup = docRef.layerSets.add(); 

            newGroup.name = GROUP_NAME; 

            for (i = docRef.layers.length - 1, min = 0; min < i; i -= 1) { 

                if (docRef.layers.name === "Background") { 

                   continue; 

                } else { 

                   docRef.layers.move(newGroup, ElementPlacement.INSIDE); 

            } 

        }

         

        for (i = 0, max = app.documents.length; i < max; i += 1) { 

            collect(app.documents); 

        } 

    } 

 

    function moveComponentGroup() { 

        var docRef, 

            i, 

            max; 

        for (i = 0, max = app.documents.length; i < max; i += 1) { 

            docRef = app.documents

            if (docRef.name === DOCUMENT_NAME) { 

                continue; 

            } 

            if ((docRef.layerSets.length > 0) && (docRef.layerSets[0].name === GROUP_NAME)) { 

                app.activeDocument = docRef; 

                docRef.layerSets[0].duplicate(app.documents[DOCUMENT_NAME].layers[0], ElementPlacement.PLACEBEFORE); 

            } 

        } 

    } 

 

 

    function main() { 

        groupLayers(); 

        makePackageDoc(DOCUMENT_NAME); 

        moveComponentGroup(); 

    } 

     

    main(); 

     

}());  // error: ') does not have a value'

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
Contributor ,
Feb 23, 2018 Feb 23, 2018

Copy link to clipboard

Copied

The closing brackets for 'else block' is not enough at line 30.

function collect(docRef) {

    var newGroup,

        i,

        min;

    app.activeDocument = docRef;

    newGroup = docRef.layerSets.add();

    newGroup.name = GROUP_NAME;

    for (i = docRef.layers.length - 1, min = 0; min < i; i -= 1) {

        if (docRef.layers.name === "Background") {

            continue;

        } else {

            docRef.layers.move(newGroup, ElementPlacement.INSIDE);

        } // <- here

    }

}

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 ,
Feb 25, 2018 Feb 25, 2018

Copy link to clipboard

Copied

Hi OMOTI,

I added that missing bracket. I'm unfortunately getting this error now, shown in comment below:

function collect(docRef) {   

            var newGroup,   

                i,   

                min;   

            app.activeDocument = docRef;   

            newGroup = docRef.layerSets.add();   

            newGroup.name = GROUP_NAME;   

            for (i = docRef.layers.length - 1, min = 0; min < i; i -= 1) {   

                if (docRef.layers.name === "Background") {   

                   continue;   

                } else {   

                   docRef.layers.move(newGroup, ElementPlacement.INSIDE);//ERROR: illegal argument

                }

So I think I know what might be the problem here. When I try and run this script on a complex PSD that has a mixture of groups and plain layers (layers that aren't in any groups whatsoever), only the layers that aren't in any groups move to the "New Group" group that's being created from this script. I think the reason for that is the script only knows how to move plain layers that aren't in a group, but not actual layer sets, which is why it says that line is an illegal argument. Just having the "layers" property doesn't seem to be enough for the script to be able to move everything into the new group. What I thought could fix this is if the script could tell when it's dealing with a layer (ArtLayer) or a group (LayerSet). I tried tweaking the function collect(docRef) to try and solve this:

function collect(docRef) { 

            var newGroup, 

                i, 

                min; 

            app.activeDocument = docRef; 

            newGroup = docRef.layerSets.add(); 

            newGroup.name = GROUP_NAME;

            for (i = docRef.artLayers.length - 1, min = 0; min < i; i -= 1) {

                docRef.activeLayer = docRef.artLayers;

                if (docRef.artLayers.name === "Background") { 

                   continue; 

                } else if (docRef.activeLayer.typename === 'ArtLayer') {

                    docRef.artLayers.move(newGroup, ElementPlacement.INSIDE);

                } else if (docRef.activeLayer.typename === 'LayerSet') {

                    docRef.artLayers.move(newGroup, ElementPlacement.INSIDE);

                }

            } 

        }

I actually got the script to go all the way to making the "Clipped Group" document, and adding all of the New Groups to that document (yay), and some of the groups even had layers in them. However, I still ran into the same issue where it's only grabbing plain layers not within any group and moving them to the "New Group" group. It's not picking up actual groups/layersets and also moving those to the "New Group" group.

I think we're getting pretty close, if you had any more thoughts or insight that would be awesome. Otherwise, I'll keep picking away at this.

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
Contributor ,
Feb 25, 2018 Feb 25, 2018

Copy link to clipboard

Copied

LATEST

For your information.

Re: Move LayerSet to another

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