Skip to main content
Participating Frequently
December 5, 2017
Answered

Help With Ps Script: Copy Group to a New PSD

  • December 5, 2017
  • 2 replies
  • 1659 views

Hi,

I'm trying to create a script that does the following:

  1. Checks for any open PSDs; if so, creates a new document named "Clipped Group."
  2. Iterates through all open PSDs.
  3. Checks for a group located at the top of the layer stack in current document called "Group 1." (should skip "Clipped Group" PSD)
  4. Copies "Group 1" (and any contents or masks attached to the group folder) and pastes it into the "Clipped Group" PSD.

I have gotten this far. The script breaks down starting at Line 28. I get an error message saying that "docRef.layerSets[0].copy" is not a function. I've been trying to piece together how to accomplish the above steps by reading the Adobe Photoshop Scripting guide, and checking forums, but I think I lack an understanding of how to use copy() and paste() or if those are even the methods I need. I'm pretty new at this -- if there was a way to work with what I have written so far, that would be great. Any help would be greatly appreciated. Thanks!

//Set Photoshop to use pixel measurements

app.preferences.rulerUnits = Units.PIXELS

app.preferences.typeUnits = TypeUnits.PIXELS

var docRef = app.activeDocument;

function makePackageDoc(filename) {

    if (app.documents.length > 0) {

        var docHeight = 2000;

        var docWidth = 2000;

        app.documents.add(docHeight, docWidth, 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;

        var n = app.documents.length;

        if (n > 0) {

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

                continue;

            };

            var x = docRef.layerSets.length;

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

                docRef.layerSets[0].copy();

                app.documents["Clipped Group"].paste();           

            };

        };

    };

};

makePackageDoc("Clipped Group");

moveComponentGroup();

This topic has been closed for replies.
Correct answer r-bin

The function copy() is available only for ArtLayers. Thus the document should be active (frontmost).

For paste(), it is also necessary that the document for which it is invoked is active.

In your case, you can use the duplicate() function. It also requires activate a document with a layer.

Your script with minor changes:

//Set Photoshop to use pixel measurements 

app.preferences.rulerUnits = Units.PIXELS 

app.preferences.typeUnits = TypeUnits.PIXELS // NOR NEED

var docRef = app.activeDocument; 

 

function makePackageDoc(filename) { 

    if (app.documents.length > 0) { 

        var docHeight = 2000; 

        var docWidth = 2000; 

        app.documents.add(docHeight, docWidth, 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

        var n = app.documents.length;  // FOR WHAT ??

        if (n > 0) { 

            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(); 

2 replies

Participating Frequently
December 6, 2017

Thank you both! This is extremely helpful. I ran some tests myself and this works great!!

Kukuryku - You're right, I also saw some oddities with the layer naming once the groups were added to the "Clipped Group" document. Fortunately, this doesn't impact my use for the script, but good to know for future reference.

r-bin- Saw your comment in the script, it does look like line 18 above is redundant and doesn't add anything to the script. Thanks for pointing that out, I will edit it accordingly. Also, thank you for explaining how those functions work, I was really stuck with this!

r-binCorrect answer
Legend
December 5, 2017

The function copy() is available only for ArtLayers. Thus the document should be active (frontmost).

For paste(), it is also necessary that the document for which it is invoked is active.

In your case, you can use the duplicate() function. It also requires activate a document with a layer.

Your script with minor changes:

//Set Photoshop to use pixel measurements 

app.preferences.rulerUnits = Units.PIXELS 

app.preferences.typeUnits = TypeUnits.PIXELS // NOR NEED

var docRef = app.activeDocument; 

 

function makePackageDoc(filename) { 

    if (app.documents.length > 0) { 

        var docHeight = 2000; 

        var docWidth = 2000; 

        app.documents.add(docHeight, docWidth, 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

        var n = app.documents.length;  // FOR WHAT ??

        if (n > 0) { 

            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(); 

Kukurykus
Legend
December 5, 2017

I found a bug. There are 2 documents. 1st just with background, and second with background and and layerSet: 'Group 1'. You want to duplicate document[1] layerSet with its content (four layers) to document[0]. When those layers are named by you (for example: 'a', 'b', 'c', 'd'), then all is okey. But when they are not, so they are by default: 'Layer 1', 'Layer 2', 'Layer 3', 'Layer 4' and you duplicate their parent (Group 1) together with them to first document they keep physical order but with reverted order of names. So now they are named in first document as follows:  'Layer 4', 'Layer 3', 'Layer 2', 'Layer 1'.

Just create two documents. First leave like it is and in second one create layer set. Add to it 4 layers (without changing their names). Leave  second document as active and run following code:

(doc = documents)[1].layerSets[0].duplicate(doc[0], ElementPlacement.PLACEATEND)

That's not everything. When you duplicate the same group (without changed names), then another group of layers in document[0] get layers with growed index. So under another 'Group 1' layerSet there will be  'Layer 8', 'Layer 7', 'Layer 6', 'Layer 5'. And what is really ununderstandable, default names of layer sets are left with their original names. So duplicated 'Group 1'  for second time keep its name in document[0] (that you duplicate to) though there is already 'Group 1' name. Well it should be so after all like it, not like with layers it happens, but still, it has no logic. If default layer names index is changing then why not groups too?

Legend
December 6, 2017

Whatta freaks