Copy link to clipboard
Copied
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.
Thanks for any help!!!!!
And if there is a better way to use CSV data please let me know.
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
...
Copy link to clipboard
Copied
OK thanks, so are you able to tell me what is wrong with the code at this point?
I'm not getting any errors, but when I run the script, nothing happens.
Thanks!
Copy link to clipboard
Copied
Did you implement what I suggested?
Copy link to clipboard
Copied
Hi Kukurykus,
I added the parenthesis like this. But I get this error.
#target photoshop
var doc = activeDocument;
var textLayer = doc.activeLayer = doc.layers.getByName('Group')
var layerContent = textLayer.textItem.contents
switch(layerContent){
case 'g001':
(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/g001.psd")
var PSD2 = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!VV/g001.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
case 'g002':
(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/g002.psd")
var PSD2 = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!VV/g002.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
}//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 );
}
Copy link to clipboard
Copied
You did not use correctly ending of function closure, like that was in my example: })()
Copy link to clipboard
Copied
Ah ok I adjusted it, and it started to work but gave this error...
The code looks like this now... is this what you meant?
#target photoshop
var doc = activeDocument;
var textLayer = doc.activeLayer = doc.layers.getByName('Group')
var layerContent = textLayer.textItem.contents
switch(layerContent){
case 'g001':
(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/g001.psd")
var PSD2 = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!VV/g001.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
case 'g002':
(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/g002.psd")
var PSD2 = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!VV/g002.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
}//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 );
}
Copy link to clipboard
Copied
Say where from you took this script as in posted code there's no selectAllLayers() function 😉
Copy link to clipboard
Copied
Hi Kukurykus,
I don't remember where I got it, but I found a version with that function there. Selecting all the layers is important. So this code here works for the first case, but not for the second. Is there an easy way to adjust this to get multiple cases to work? (I'll be adding many more cases once it starts working)
Thanks!
#target photoshop
var doc = activeDocument;
var textLayer = doc.activeLayer = doc.layers.getByName('Group')
var layerContent = textLayer.textItem.contents
switch(layerContent){
case 'g001':
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/g001.psd")
var PSD2 = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!VV/g001.psd");
if(!PSD.exists) return;
open(PSD);
selectAllLayers();
activeDocument.activeLayer.duplicate(documents[0]);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES)
if(!PSD2.exists) return;
open(PSD2);
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 'g002':
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/g002.psd")
var PSD2 = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!VV/g002.psd");
if(!PSD.exists) return;
open(PSD);
selectAllLayers();
activeDocument.activeLayer.duplicate(documents[0]);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES)
if(!PSD2.exists) return;
open(PSD2);
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
Copy link to clipboard
Copied
Put defined selectAllLayers function between first two lines of code I commented and try again.
Copy link to clipboard
Copied
OK, do you mean like this? I surrounded each one with the parenthsis you mentioned.
When I test g002, nothing happens. When I test g001, I get this error.
#target photoshop
var doc = activeDocument;
var textLayer = doc.activeLayer = doc.layers.getByName('Group')
var layerContent = textLayer.textItem.contents
switch(layerContent){
case 'g001':
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/g001.psd")
var PSD2 = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!VV/g001.psd");
if(!PSD.exists) return;
open(PSD);
selectAllLayers();
activeDocument.activeLayer.duplicate(documents[0]);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES)
if(!PSD2.exists) return;
open(PSD2);
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 'g002':
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/g002.psd")
var PSD2 = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!VV/g002.psd");
if(!PSD.exists) return;
open(PSD);
selectAllLayers();
activeDocument.activeLayer.duplicate(documents[0]);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES)
if(!PSD2.exists) return;
open(PSD2);
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
Copy link to clipboard
Copied
Don't you think 'two first lines of code' are #target photoshop & var doc = activeDocument;
Copy link to clipboard
Copied
Hi Kukurykus,
No, I'm sorry I didn't understand it that way. Is this what you meant? It still doesn't open the documents, but there are no errors.
#target photoshop
(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 );
})()
var doc = activeDocument;
var textLayer = doc.activeLayer = doc.layers.getByName('Group')
var layerContent = textLayer.textItem.contents
switch(layerContent){
case 'g001':
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/g001.psd")
var PSD2 = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!VV/g001.psd");
if(!PSD.exists) return;
open(PSD);
selectAllLayers();
activeDocument.activeLayer.duplicate(documents[0]);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES)
if(!PSD2.exists) return;
open(PSD2);
selectAllLayers();
activeDocument.activeLayer.duplicate(documents[0]);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
main();
break;
case 'g002':
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/g002.psd")
var PSD2 = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!VV/g002.psd");
if(!PSD.exists) return;
open(PSD);
selectAllLayers();
activeDocument.activeLayer.duplicate(documents[0]);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES)
if(!PSD2.exists) return;
open(PSD2);
selectAllLayers();
activeDocument.activeLayer.duplicate(documents[0]);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
main();
break;
}//end switch
Copy link to clipboard
Copied
The defined function you put on top should be without opening ( and closing )() characters.
Copy link to clipboard
Copied
Why write code so stupidly?
There is no definition for the selectAllLayers function (you can use app.runMenuItem instead).
Why define the playAction function (which can be replaced with app.doAction) if you don't call it?
It is better to place the opening and closing curly braces on the same level (with the same space), then you will never be mistaken in matching the opening and closing braces.
And in general, if you use scripts, you need to at least read about elementary rules and syntax for javascript code.
upd. was edited
Copy link to clipboard
Copied
He earlier admitted to no scripting skills and it's not his script, so your bold sentence has sense.
Copy link to clipboard
Copied
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?
Copy link to clipboard
Copied
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!
Copy link to clipboard
Copied
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."
Copy link to clipboard
Copied
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? No, I will describe the process below.
Second. The script ends like? You only have the modified current open document, right?
I mostly use actions because they are easy to create. So this script is just part of an action. There are many things that happen before this script will run, and also things will happen after the script runs. So the action will finish the whole process. I know it's not ideal, but until I learn scripting better, this is how I can do it.
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.
I was thinking the same thing that there is probably a way to write the code without all the cases. But as you know, I'm not a programmer so I can't picture how that would be done.
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."
Haha! Sorry, I didn't know how detailed you wanted me to be. I'll try to describe it further...
1- There will already be a document open. That document will have a text layer called "Group". The script will read that text.
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- If the text is g001, the script will "Place" a .psd document called "g001.psd" into the already active document. If the text reads g002, then it will place "g002.psd" and so on... Placing a .psd means that the .psd is opened, all the layers are selected and copied to the document you are working on, then the .psd document is closed. It has to be done this way because normally if you place a .psd all the layers get flattened.
4- The .psd files will be in one of two folders. So the script needs to try one folder, and then if it is not there, try the other folder. This is why there are these two file paths in the script...
var PSD = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!HV/g001.psd")
var PSD2 = new File("/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!VV/g001.psd");
Once it "Places" the .psd this scripts job is done.
I hope that is detailed enough for you.
If the code I have just needs to be completely redone, and you are able to do it, please let me know if payment is needed. I'm not sure how far this Adobe Support Community goes in helping with code. But if this is outside the scope of normal support, then I'm willing to pay for the help. I just need this project finished.
Thank you!
Copy link to clipboard
Copied
Well. Try this script
app.displayDialogs = DialogModes.NO;
main();
function main()
{
try {
var folder_path1 = "/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!HV";
var folder_path2 = "/Macintosh HD/Users/macbookpro2018/Desktop/Current Project/!MemoryMate/!VV";
var doc = app.activeDocument;
// since you did not specify where to copy the layers, we deselect all layers so that the new layers are copied to the very top.
try {
var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("menuItemClass"), stringIDToTypeID("menuItemType"), stringIDToTypeID("selectNoLayers"));
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("select"), d, DialogModes.NO);
}
catch(e) {}
// try to get text of "Group" text layer
var name = doc.artLayers.getByName("Group").textItem.contents;
// try to open psd file with the appropriate name from folder1 or folder2
var file = new File(folder_path1 + "/" + name + ".psd");
if (file.exists)
{
app.open(file);
}
else
{
file = new File(folder_path2 + "/" + name + ".psd");
if (file.exists)
app.open(file);
else
{
alert("PSD file not found: " + name + ".psd");
return;
}
}
var doc2 = app.activeDocument;
// try to convert background layer to normal layer
try { doc2.backgroundLayer.name = "Background"; } catch(e) {}
// select all layers and copy them from doc2 to doc
app.runMenuItem(stringIDToTypeID("selectAllLayers"));
var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
var r1 = new ActionReference();
r1.putIdentifier(stringIDToTypeID("document"), doc.id);
d.putReference(stringIDToTypeID("to"), r1);
executeAction(stringIDToTypeID("duplicate"), d, DialogModes.NO);
doc2.close(SaveOptions.DONOTSAVECHANGES);
app.activeDocument = doc;
// select only the top layer in target doc
app.runMenuItem(stringIDToTypeID("selectNoLayers"));
var r = new ActionReference();
r.putIdentifier(stringIDToTypeID("layer"), doc.layers[0].id); // will cause an error in CS6
var d = new ActionDescriptor();
d.putReference(stringIDToTypeID("null"), r);
d.putBoolean(stringIDToTypeID("makeVisible"), false);
executeAction(stringIDToTypeID("select"), d, DialogModes.NO);
}
catch (e) { alert(e.message + "\n\nline: " + e.line + "\n\n" + e.source.split("\n")[e.line-1].replace(/^\s+/g, "")); }
}
Copy link to clipboard
Copied
Hello r-bin,
That works perfectly, well done! Thank you!
And just to be clear, are "Adobe Community Professionals" employed by Adobe to help customers with code like this? If so, how would I know if the help I'm asking for is beyond the scope of that service? And are any of the "Adobe Community Professionals" available to write code for payment if the project is beyond that scope?
Thanks I really appreciate it!
- Jim
Copy link to clipboard
Copied
I am at a loss to answer you. I think it's not appropriate to talk about payment here.
About ACP Why don't I get a reply from an Adobe professional?
I didn't find it anymore (official links from Adobe are somehow unavailable)
Copy link to clipboard
Copied
ACPs or Adobe Cimmunity Professionals, are bot Adobe employees. We volunteer our time to answer questions on the forums. We are compensated by free software.
Copy link to clipboard
Copied
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..