Skip to main content
jimm7329411
Known Participant
January 7, 2020
Answered

Run action based on text value

  • January 7, 2020
  • 7 replies
  • 10177 views

Hello,

I'm trying to run actions based on data from an Excel (csv) file using variables in Photoshop.

The only way I could think of doing that was to make a text layer for each data item, then using variables, the data would be in the document itself.  That is working fine but I'm stuck on scripting.

 

So my question is.....  What would be the script to run an action based on the value of a specific text layer?

 

Here is what I have so far.

 

#target photoshop
 
var doc = app.activeDocument;
if(doc.layer._5x7.value=1){
doAction("5x7 - 1TEST", "Automations");
}else{doAction("nothing", "Automations");
}

 

Thanks for any help!!!!!

And if there is a better way to use CSV data please let me know.

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

Ok, so this script will make the layer named "_5x7" active and read the contents of the layer. You set up the switch correctly, but make sure you use the actual name of the action set that contains your actions.

#target photoshop
var doc = activeDocument;

var textLayer = doc.activeLayer = doc.layers.getByName('_5x7')
var layerContent = textLayer.textItem.contents

switch(layerContent){
    case '1':
        playAction('My action set', 'save1-5x7')
        break;
    case '2':
        playAction('My action set', 'save2-5x7')
        break; 
    case '3':
        playAction('My action set', 'save3-5x7')
        break;  
    case '4':
        playAction('My action set', 'save4-5x7')
        break;
    case '5':
        playAction('My action set', 'save5-5x7')
        break; 
    case '6':
        playAction('My action set', 'save6-5x7')
        break;   
    }//end switch

function playAction(actionSet, actionName){
    var idPly = charIDToTypeID( "Ply " );
        var desc2 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref1 = new ActionReference();
            var idActn = charIDToTypeID( "Actn" );
            ref1.putName( idActn, actionName );
            var idASet = charIDToTypeID( "ASet" );
            ref1.putName( idASet, actionSet );
        desc2.putReference( idnull, ref1 );
    executeAction( idPly, desc2, DialogModes.NO );    
    }

7 replies

Participant
May 12, 2021

Ok, so this script will make the layer named "_5x7" active and read the contents of the layer. You set up the switch correctly, but make sure you use the actual name of the action set that contains your actions. #target photoshop var doc = activeDocument; var textLayer = doc.activeLayer = doc.layers.getByName('_5x7') var layerContent = textLayer.textItem.contents switch(layerContent){ case '1': playAction('My action set', 'save1-5x7') break; case '2': playAction..

Legend
May 8, 2021

jimm7329411 , the topic is marked as resolved.

Can you explain what your problem is? What should the script do step by step? Explain what you would do manually instead of a script. What are the initial conditions, for example, are there any open documents?

jimm7329411
Known Participant
May 8, 2021

I see that it is resolved, but I think that is just because this was from so long ago and this whole project of mine went on hold because of covid. It is not resolved.

 

Here is what it should do...

 

1- Check the active document for the text that is in the "Group" layer.

2- The text will look like this... g001, g002, g003 and so on to g300 (it could also be "0" which would do nothing).

3- For each one of those cases, it will place one of two .psd's with the corresponding name within the active document. 

4- There will be two folders for it to search.  The .psd will only be in one of the two folders.

 

For example, if Group layer has "g127", it will look for "g127.psd" in the first folder, if it is there it will place it into the active document.

If it is not there, it will look for it in the second folder and then place that one.

 

And that is all.  To keep the code short while pasting it here in the forum, I'm only showing code for 2 of the 300 cases. Once it is working, then I will copy the cases out to 300.  

 

Also, I'm sorry if this is outside the scope of this community support forum.  I don't know where else to look for help. I am reading through the Adobe scripting guide and have done some tutorials but it is still difficult for me.  

 

Thank you for your assistance!

Legend
May 9, 2021

Transcribe your statement: "it will place it into the active document". Does this mean to execute the "Place" command above the currently active layer of the open document?

 

Second. The script ends like? You only have the modified current open document, right?

 

------------------------

If the text is the same as the name of the file you want (without the extension), then there is no need to fence a million cases of "switch" or "if". It is enough to form the file name based on the text. But there is not enough information to write the script. I asked to describe step by step, not like this: "I opened the file and did the work I needed."

Chuck Uebele
Community Expert
Community Expert
March 28, 2020

Okay, so I redid your code and tried it. You only have one item in your switch, which runs code if the text contents of a layer called "Group" is 01. If you just have one condition like that, you don't need a switch. That is for multiple choices. You do need to have a break at the end of each case statement, to denote that you are done with that selection of code.

I removed the returns on the if statements, as that was stopping the code from continuing if the 01.psd file was not in the first folder. Now it will check for it in the first, and if it's not there, it will check the second folder. I removed all the functions from within the switch. They don't belong there. Just the call to them does, which is in this case: main().

 

#target photoshop
var doc = activeDocument;

var textLayer = doc.activeLayer = doc.layers.getByName('Group')
var layerContent = textLayer.textItem.contents

switch(layerContent){
        case '01':
        main();
        break;//break needed after each use of "case"
    };//end switch

function selectAllLayers() {
    var desc29 = new ActionDescriptor();
        var ref23 = new ActionReference();
        ref23.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
    desc29.putReference( charIDToTypeID('null'), ref23 );
    executeAction( stringIDToTypeID('selectAllLayers'), desc29, DialogModes.NO );
    };//end function

function main(){
    if(documents.length != 1) return;
    // Open psd with the layers to copy
    //Amend filename to suit
    var PSD = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!HV/01.psd")
    var PSD2 = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!VV/01.psd");
    if(PSD.exists){
        open(PSD);
        selectAllLayers();
        activeDocument.activeLayer.duplicate(documents[0]);
        app.activeDocument.close(SaveOptions.DONOTSAVECHANGES)
        }
    else if(PSD2.exists){
        open(PSD2);
        selectAllLayers();
        activeDocument.activeLayer.duplicate(documents[0]);
        app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
        }  
    };//end function
jimm7329411
Known Participant
March 28, 2020

Hi Chuck,

Actually, I was just showing you the first piece of the code because it was so long.  I was just trying to get the first case to work, then once that worked I could copy it to the rest of the 300 cases.  I'll shrink it down to 3 cases just to show you here, that way you can see the beginning, middle, and end.  (All the cases are the same except the case number and document name.  They are from 01 - 0300)

 

So here is the code, without conditons, that works now.  I would like to add the conditions I mentioned where IF the document is missing from the first folder THEN it will open the one from the second.  

 

Thanks, and sorry for the confusion!

 

#target photoshop
var doc = activeDocument;

var textLayer = doc.activeLayer = doc.layers.getByName('Group')
var layerContent = textLayer.textItem.contents

switch(layerContent){
        case '01':
        function main(){
if(documents.length != 1) return;
// Open psd with the layers to copy
//Amend filename to suit
var PSD = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!HV/01.psd");
if(!PSD.exists) return;
open(PSD);
selectAllLayers();
activeDocument.activeLayer.duplicate(documents[0]);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
function selectAllLayers() {
    var desc29 = new ActionDescriptor();
        var ref23 = new ActionReference();
        ref23.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
    desc29.putReference( charIDToTypeID('null'), ref23 );
    executeAction( stringIDToTypeID('selectAllLayers'), desc29, DialogModes.NO );
}
main();
        break;
        case '02':
        function main(){
if(documents.length != 1) return;
// Open psd with the layers to copy
//Amend filename to suit
var PSD = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!HV/02.psd");
if(!PSD.exists) return;
open(PSD);
selectAllLayers();
activeDocument.activeLayer.duplicate(documents[0]);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
function selectAllLayers() {
    var desc29 = new ActionDescriptor();
        var ref23 = new ActionReference();
        ref23.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
    desc29.putReference( charIDToTypeID('null'), ref23 );
    executeAction( stringIDToTypeID('selectAllLayers'), desc29, DialogModes.NO );
}
main();
        break;
        case '03':
        function main(){
if(documents.length != 1) return;
// Open psd with the layers to copy
//Amend filename to suit
var PSD = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!HV/03.psd");
if(!PSD.exists) return;
open(PSD);
selectAllLayers();
activeDocument.activeLayer.duplicate(documents[0]);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
function selectAllLayers() {
    var desc29 = new ActionDescriptor();
        var ref23 = new ActionReference();
        ref23.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
    desc29.putReference( charIDToTypeID('null'), ref23 );
    executeAction( stringIDToTypeID('selectAllLayers'), desc29, DialogModes.NO );
}
main();
        break;
             
        
        
    }//end switch

function playAction(actionSet, actionName){
    var idPly = charIDToTypeID( "Ply " );
        var desc2 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref1 = new ActionReference();
            var idActn = charIDToTypeID( "Actn" );
            ref1.putName( idActn, actionName );
            var idASet = charIDToTypeID( "ASet" );
            ref1.putName( idASet, actionSet );
        desc2.putReference( idnull, ref1 );
    executeAction( idPly, desc2, DialogModes.NO );    
    }

 

 

Chuck Uebele
Community Expert
Community Expert
March 27, 2020

Not sure why it is placing the second file, if you have both, as it looks like your code will place the contents of both files. However, you need to change your if statements. You have them so if the first file isn't in the first folder, then the function quits with the return statement. You should use an if-else statement with an else if, or an if within the else.

switch(layerContent){
        case '01':
        function main(){
            if(documents.length != 1) return;
            // Open psd with the layers to copy
            //Amend filename to suit
            var PSD = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!HV/01.psd")
            var PSD2 = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!VV/01.psd");
            if(PSD.exists) {
                open(PSD);
                selectAllLayers();
                activeDocument.activeLayer.duplicate(documents[0]);
                app.activeDocument.close(SaveOptions.DONOTSAVECHANGES)
                }
            else if(PSD2.exists) {
                open(PSD2);
                selectAllLayers();
                activeDocument.activeLayer.duplicate(documents[0]);
                app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                }
            break;//need a break after each case
            }
jimm7329411
Known Participant
March 27, 2020

Thank you!  

It is giving an error...

 

Error 10: Illegal break or continue outside a loop.

->              break;//need a break after each case

 

There are many cases like before.  It doesn't seem to like the way the break is there.

Chuck Uebele
Community Expert
Community Expert
March 27, 2020

Well, then remove the break. But you have a function within the switch, which I don't think is a good idea.

Chuck Uebele
Community Expert
Community Expert
January 9, 2020

Since I learned scripting, I rarely use actions, unless it's just some simple thing. I do record actions to run my scripts, just so it's easier than going to the menu. However, I'm not sure if this is still the case, but I always had troubles running an action within an action. So if you're running an action to run the script, and the script runs actions, that might be your issue. As far as the path to the script in the action, that's okay, and should do that. but again, if you change version of PS the links can get broken - again, another reason I just write scripts.

jimm7329411
Known Participant
January 10, 2020

Thanks Chuck,

I realized that utilizing scripting more would be better.  But since I don't know how to script very well I just use actions as much as I can and as little scripting as I can get away with.  I was able to get the code you sent me to work though (It took me all day!).  I haven't had issues runing actions from actions or mixing scripts with actions.  My issues have just been recording and playing back the script. Many times I would get an error when playing back a script that worked as I was recording it.  The solution was...

 

When you go to record the script within the action.  Choose File > Scripts > then choose the script from the list.

My problem was I had so many scripts in the list that the script I wanted to use could not show in that list.  I always had to choose browse and pull the script from it's location. This caused a naming issue within the action.  It would say Name: "" at the end of the script name.  So I just cleared out the Phtotoshop > Presets > Scripts folder enough to allow the scripts I was using show.  It seems like a silly fix to me, but it worked.

Chuck Uebele
Community Expert
Community Expert
January 10, 2020

Ummm, that's odd. I use browse all the time to record a script in an action. I don't think I've seen it say name at the end, but then I may not have looked to closely. I keep all my scripts in a folder on my desktop, as the list has gotten big, like you said, and I get tired of moving them to a new version of PS.

Chuck Uebele
Community Expert
Chuck UebeleCommunity ExpertCorrect answer
Community Expert
January 8, 2020

Ok, so this script will make the layer named "_5x7" active and read the contents of the layer. You set up the switch correctly, but make sure you use the actual name of the action set that contains your actions.

#target photoshop
var doc = activeDocument;

var textLayer = doc.activeLayer = doc.layers.getByName('_5x7')
var layerContent = textLayer.textItem.contents

switch(layerContent){
    case '1':
        playAction('My action set', 'save1-5x7')
        break;
    case '2':
        playAction('My action set', 'save2-5x7')
        break; 
    case '3':
        playAction('My action set', 'save3-5x7')
        break;  
    case '4':
        playAction('My action set', 'save4-5x7')
        break;
    case '5':
        playAction('My action set', 'save5-5x7')
        break; 
    case '6':
        playAction('My action set', 'save6-5x7')
        break;   
    }//end switch

function playAction(actionSet, actionName){
    var idPly = charIDToTypeID( "Ply " );
        var desc2 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref1 = new ActionReference();
            var idActn = charIDToTypeID( "Actn" );
            ref1.putName( idActn, actionName );
            var idASet = charIDToTypeID( "ASet" );
            ref1.putName( idASet, actionSet );
        desc2.putReference( idnull, ref1 );
    executeAction( idPly, desc2, DialogModes.NO );    
    }
jimm7329411
Known Participant
January 8, 2020

I deleted this post...

Chuck Uebele
Community Expert
Community Expert
January 8, 2020

You would need something along these lines where you get the contents of the layer, then use a switch function to select what you want to do based on the contents of the layer. You need to make sure you enter both the name of the action set and the action to call the function in the switch.

#target photoshop
var doc = activeDocument;

var layerContent = doc.activeLayer.textItem.contents

switch(layerContent){
    case '5X7':
        playAction('My action set', 'Crop 5X7')
        break;
    case '8X10':
        playAction('My action set', 'Crop 8X10')
        break;    
    }//end switch

function playAction(actionSet, actionName){
    var idPly = charIDToTypeID( "Ply " );
        var desc2 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref1 = new ActionReference();
            var idActn = charIDToTypeID( "Actn" );
            ref1.putName( idActn, actionName );
            var idASet = charIDToTypeID( "ASet" );
            ref1.putName( idASet, actionSet );
        desc2.putReference( idnull, ref1 );
    executeAction( idPly, desc2, DialogModes.NO );    
    }
jimm7329411
Known Participant
January 8, 2020

Hi Chuck,

Thank you very much.  This is a bit more complex than I thought it would be.

And a bit over my head.  Let me give you one example scenario.

 

The Excel value for 5x7 says "3" (a customer wants 3- 5x7's)

So in my photoshop document there is a hidden text layer called "_5x7"

That text in that layer is "3" (brought in from Excel)

I would like the script to play the action that would save 3- 5x7's

There will be an action for 1-5x7, 2-5x7 3-5x7, 4-5x7 and so on.

 

So from the script you sent me, can you tell me where to target the layer name?

I'm guessing where it says "case" I would have the cell value like this?

switch(layerContent){
    case '1':
        playAction('My action set', 'save1-5x7')
        break;
    case '2':
        playAction('My action set', 'save2-5x7')
        break; 
    case '3':
        playAction('My action set', 'save3-5x7')
        break;  
    case '4':
        playAction('My action set', 'save4-5x7')
        break;
    case '5':
        playAction('My action set', 'save5-5x7')
        break; 
    case '6':
        playAction('My action set', 'save6-5x7')
        break;   

 

Hopefully that makes sense. I should mention too that the text layer may not be the active layer and there will be more layers for other sizes like 8x10, wallets, 3.5x5 and so on...

I was going to run this as a batch once all of the photos were finished being processed.

Thank you!!!