Heya
Pretty silly issue. But it appears to be unbreakable for me :/
I'm trying to select layers by part of name. Well I want to loop thought all of them but I hope that wont be a problem... in any case :
Code: Select allif (newName = layerName.artLayers.getByName("*Rainbow*"));
{
alert(newName)
}
Thanks, bye.
Select by part of name
Select by part of name
As far a I know, getByName doesn't support wildcard chars and only returns exact matches. Even then it only returns the top most layer with that exact name.
I think you will have to loop through all the layers and find the match(s) that way.
I think you will have to loop through all the layers and find the match(s) that way.
Select by part of name
Heya
yea thats what I have atm. But it drops me an error...
Code: Select alldoc = app.activeDocument;
for (var a =0;a<doc.layers.length;a++){
doc.activeLayer = doc.layers[a];
layerName = doc.layers[a].name;
if (newName = layerName.artLayers.getByName("*Rainbow*"));
{
alert(newName)
}
}
I'm getting "undefinied is not an object" umh?
yea thats what I have atm. But it drops me an error...
Code: Select alldoc = app.activeDocument;
for (var a =0;a<doc.layers.length;a++){
doc.activeLayer = doc.layers[a];
layerName = doc.layers[a].name;
if (newName = layerName.artLayers.getByName("*Rainbow*"));
{
alert(newName)
}
}
I'm getting "undefinied is not an object" umh?
Select by part of name
As I said you can't use getByName to match part of a layer name. Even if you could you wouldn't do it that way. You are assigning the layer name to a variable called 'layerName'. That variable holds a string( the layer's name). It doesn't have an artLayers collection. That is why you are getting the undefined error.
Do something like this
Code: Select alldoc = app.activeDocument;
for (var a =0;a<doc.layers.length;a++){
var layerName = doc.layers[a].name;
if (layerName.match(/.*Rainbow.*/)){
alert(layerName);
}
}
Do something like this
Code: Select alldoc = app.activeDocument;
for (var a =0;a<doc.layers.length;a++){
var layerName = doc.layers[a].name;
if (layerName.match(/.*Rainbow.*/)){
alert(layerName);
}
}
Select by part of name
Hai !
Right so I hit another wall... and well this is embarasing, I thought I could get it running.
In any case I'm trying now to do the stuff I wanted to do initially.. I sort off got it working one way, but it does not do exactly wahat I wanted. I gues its because the index changes after I run 1st loop and then all goes to hell...
So here is the first line of code:
Code: Select alldoc = app.activeDocument;
testGRP = doc.layerSets.getByName('Shadows');
for (var a =0;a<doc.layers.length;a++){
var LN = doc.layers[a].name;
if (LN.match(/.*IB_Shad*/)){
var desc = new ActionDescriptor();
var sourceRef = new ActionReference();
sourceRef.putName( charIDToTypeID( "Lyr " ), LN );
desc.putReference( charIDToTypeID( "null" ), sourceRef );
var indexRef = new ActionReference();
indexRef.putName( charIDToTypeID("Lyr "), testGRP.name );
var layerIndex = executeActionGet(indexRef).getInteger(stringIDToTypeID('itemIndex'));
var destinationRef = new ActionReference();
destinationRef.putIndex( charIDToTypeID( "Lyr " ), layerIndex-1 );
desc.putReference( charIDToTypeID( "T " ), destinationRef );
desc.putBoolean( charIDToTypeID( "Adjs" ), false );
desc.putInteger( charIDToTypeID( "Vrsn" ), 5);
executeAction( charIDToTypeID( "move" ), desc, DialogModes.NO );
}
}
it works but it messes up the layers...
The second attempt was this :
Code: Select alldoc = app.activeDocument;
testGRP = doc.layerSets.getByName('Lights');
for (var a =0;a<doc.layers.length;a++){
var layerName = doc.layers[a].name;
if (layerName.match(/.*lit*/)){
Name = doc.artLayers.getByName(layerName);
moveIt(doc,Name,testGRP);
function moveIt(doc, srcLayer, toLayerName) {
srcLayer.move(toLayerName.ElementPlacement.INSIDE);
}
}
}
And this one give me some error so ehh hilp meee
If I have string and i want to use it with .move I need it to be layer or layerSet as far as I was informed, then how can I convert that string to that thini ? Is this the good approach ? Name = doc.artLayers.getByName(layerName);
Also on a side note regarding searching by name...
How can I search for multiple flags so it only selects the one that it has them all in any order?
.match(/.*lit_*/,/.*specular*/))
.match(/.*lit_*/+/.*specular*/))
.match(/.*lit_*/|/.*specular*/))
.match(/.*lit_,specular*/))
.match(/.*lit_ | specular*/))
I tried these options, none of them work and from internet I read that I might need to use redex so uhhh...
Thanks, bye..
Right so I hit another wall... and well this is embarasing, I thought I could get it running.
In any case I'm trying now to do the stuff I wanted to do initially.. I sort off got it working one way, but it does not do exactly wahat I wanted. I gues its because the index changes after I run 1st loop and then all goes to hell...
So here is the first line of code:
Code: Select alldoc = app.activeDocument;
testGRP = doc.layerSets.getByName('Shadows');
for (var a =0;a<doc.layers.length;a++){
var LN = doc.layers[a].name;
if (LN.match(/.*IB_Shad*/)){
var desc = new ActionDescriptor();
var sourceRef = new ActionReference();
sourceRef.putName( charIDToTypeID( "Lyr " ), LN );
desc.putReference( charIDToTypeID( "null" ), sourceRef );
var indexRef = new ActionReference();
indexRef.putName( charIDToTypeID("Lyr "), testGRP.name );
var layerIndex = executeActionGet(indexRef).getInteger(stringIDToTypeID('itemIndex'));
var destinationRef = new ActionReference();
destinationRef.putIndex( charIDToTypeID( "Lyr " ), layerIndex-1 );
desc.putReference( charIDToTypeID( "T " ), destinationRef );
desc.putBoolean( charIDToTypeID( "Adjs" ), false );
desc.putInteger( charIDToTypeID( "Vrsn" ), 5);
executeAction( charIDToTypeID( "move" ), desc, DialogModes.NO );
}
}
it works but it messes up the layers...
The second attempt was this :
Code: Select alldoc = app.activeDocument;
testGRP = doc.layerSets.getByName('Lights');
for (var a =0;a<doc.layers.length;a++){
var layerName = doc.layers[a].name;
if (layerName.match(/.*lit*/)){
Name = doc.artLayers.getByName(layerName);
moveIt(doc,Name,testGRP);
function moveIt(doc, srcLayer, toLayerName) {
srcLayer.move(toLayerName.ElementPlacement.INSIDE);
}
}
}
And this one give me some error so ehh hilp meee
If I have string and i want to use it with .move I need it to be layer or layerSet as far as I was informed, then how can I convert that string to that thini ? Is this the good approach ? Name = doc.artLayers.getByName(layerName);
Also on a side note regarding searching by name...
How can I search for multiple flags so it only selects the one that it has them all in any order?
.match(/.*lit_*/,/.*specular*/))
.match(/.*lit_*/+/.*specular*/))
.match(/.*lit_*/|/.*specular*/))
.match(/.*lit_,specular*/))
.match(/.*lit_ | specular*/))
I tried these options, none of them work and from internet I read that I might need to use redex so uhhh...
Thanks, bye..
Select by part of name
I'll answer the RegExp part first. There are lots of ways to create a RegExp to match parts of a string. And guessing rarely works so reading about how to use regular expressions would help. But it you just want to match any layer that has 'lit_' or 'specular' any where in the layer name you can do something like this.
Code: Select allif(app.activeDocument.activeLayer.name.match(/lit_|specular/) != null) alert('Match in layer name');
As for the rest, it might be better if you told us what you want to do instead of posting what you have tried and us trying to understand what you want done( and why it's not working ).
But it looks like you are trying to move layers with matching names into a layerSet. I think the best way to do that is with two loops. The first loop searches the layers and stores the matches. Moving, adding, or deleting layers in that loop just causes problems. A second loop of the matching layers is where you move or delete. Something like this.
Code: Select allvar doc = app.activeDocument;
var testGRP = doc.layerSets.getByName('Lights');// layerSet to move matching layers into
var matchedLayers = [];// array to hold any matching layer objects
// loop to find layers - top level only
for (var a =0;a<doc.layers.length;a++){
var layerName = doc.layers[a].name;
if (layerName.match(/lit_|specular/) != null){
matchedLayers.push(doc.layers[a]);// name matches so store layer object for later
}
}
// loop any found layers to move
for( var a = 0;a<matchedLayers.length;a++){
matchedLayers[a].move(testGRP, ElementPlacement.INSIDE);
}
Code: Select allif(app.activeDocument.activeLayer.name.match(/lit_|specular/) != null) alert('Match in layer name');
As for the rest, it might be better if you told us what you want to do instead of posting what you have tried and us trying to understand what you want done( and why it's not working ).
But it looks like you are trying to move layers with matching names into a layerSet. I think the best way to do that is with two loops. The first loop searches the layers and stores the matches. Moving, adding, or deleting layers in that loop just causes problems. A second loop of the matching layers is where you move or delete. Something like this.
Code: Select allvar doc = app.activeDocument;
var testGRP = doc.layerSets.getByName('Lights');// layerSet to move matching layers into
var matchedLayers = [];// array to hold any matching layer objects
// loop to find layers - top level only
for (var a =0;a<doc.layers.length;a++){
var layerName = doc.layers[a].name;
if (layerName.match(/lit_|specular/) != null){
matchedLayers.push(doc.layers[a]);// name matches so store layer object for later
}
}
// loop any found layers to move
for( var a = 0;a<matchedLayers.length;a++){
matchedLayers[a].move(testGRP, ElementPlacement.INSIDE);
}
Select by part of name
Heya
Yea I guess that would be a lot simpler if I would just explain up front what I was trying to do... uhh sorry.
On a side note what does this do ? != null ? Atm its finding either lit_ or specular or both. I was wondering if I can tweak it down to lit + specular only rather than them being separated option.
Where would you suggest I could read about searching and string? I think it would be a lot better for me to read doc than my spamming the forum
Thanks, bye.
Yea I guess that would be a lot simpler if I would just explain up front what I was trying to do... uhh sorry.
On a side note what does this do ? != null ? Atm its finding either lit_ or specular or both. I was wondering if I can tweak it down to lit + specular only rather than them being separated option.
Where would you suggest I could read about searching and string? I think it would be a lot better for me to read doc than my spamming the forum
Thanks, bye.
Select by part of name
As long as your post is about Adobe scripting it's not spam.
Don't be offended but from the code you posted I would suggest you start with reading the scripting guide to understand the Photoshop Object Model. I think that will be more helpful to you than trying to learn Photoshop scripting and RegExp at the same time.
There are tons of books and web sites about RegExp and I don't really have any recommendations. RegExp is all about pattern matching. It should be possible to have an expression that does what you want but before I can suggest something I would need to see some examples of the layer names you want to search/match to see if there is a pattern. For example you want to match both 'lit' and 'specular'. Does 'lit' always come before 'specular'. What about any chars between those two strings. A simple match expression would look something like this
/lit.*specular/
That will match 'lit' followed by 0 or more chars followed by 'specular'. Note case matters. It will not match 'Specular' unless you add the ignore case modifier.
/lit.*specular/i
The != null is a test to see if the match does not equal null. The match() method returns the matching string if there is a match. If there is not a match it returns null. In other words null means not found. Because the matching string depends on the match argument checking that it is not null lets you know there is a match without needing to know the exact matching string.
Similarly if(myString.search(someRE) != -1 ) lets you know there isn't a match when using the search method. If there was a match it returns the starting matching char position. A -1 means not found in this case.
And again, don't worry about posting on topic questions here. This forum exists to help people at all levels of experience.
Don't be offended but from the code you posted I would suggest you start with reading the scripting guide to understand the Photoshop Object Model. I think that will be more helpful to you than trying to learn Photoshop scripting and RegExp at the same time.
There are tons of books and web sites about RegExp and I don't really have any recommendations. RegExp is all about pattern matching. It should be possible to have an expression that does what you want but before I can suggest something I would need to see some examples of the layer names you want to search/match to see if there is a pattern. For example you want to match both 'lit' and 'specular'. Does 'lit' always come before 'specular'. What about any chars between those two strings. A simple match expression would look something like this
/lit.*specular/
That will match 'lit' followed by 0 or more chars followed by 'specular'. Note case matters. It will not match 'Specular' unless you add the ignore case modifier.
/lit.*specular/i
The != null is a test to see if the match does not equal null. The match() method returns the matching string if there is a match. If there is not a match it returns null. In other words null means not found. Because the matching string depends on the match argument checking that it is not null lets you know there is a match without needing to know the exact matching string.
Similarly if(myString.search(someRE) != -1 ) lets you know there isn't a match when using the search method. If there was a match it returns the starting matching char position. A -1 means not found in this case.
And again, don't worry about posting on topic questions here. This forum exists to help people at all levels of experience.
Select by part of name
Heya
Thanks for help ! Regarding reading the scripting guide. Yes it is on the list. Just with all the stuff that happens around me right now I might just not have as much time as I should give it to...
In any case I went over RegExp and I sort of understand quite a lot more about it now.
I managed to tweak the search parameter so it looks for both of the key worlds and acts only if it find them both....
Is this the correct approach ? it works, but it might be accident
/lit+.*specular./ ?
Also I went over this information + few other regarding regexp but nowhere it says what does this means "/" and "\"... so what does it do ?
http://www.w3schools.com/jsref/jsref_obj_regexp.asp
http://www.w3schools.com/js/js_obj_regexp.asp
Thanks, bye.
Thanks for help ! Regarding reading the scripting guide. Yes it is on the list. Just with all the stuff that happens around me right now I might just not have as much time as I should give it to...
In any case I went over RegExp and I sort of understand quite a lot more about it now.
I managed to tweak the search parameter so it looks for both of the key worlds and acts only if it find them both....
Is this the correct approach ? it works, but it might be accident
/lit+.*specular./ ?
Also I went over this information + few other regarding regexp but nowhere it says what does this means "/" and "\"... so what does it do ?
http://www.w3schools.com/jsref/jsref_obj_regexp.asp
http://www.w3schools.com/js/js_obj_regexp.asp
Thanks, bye.
Select by part of name
"/" and "\" are just two of the many special chars used in regular expressions. The forward slash is used to start and stop the pattern when creating an implicit RegExp like /lit+.*specular./
That same expression could be created explicitly like this new RegExp(lit+.*specular.). Notice the forward slashes are not used in the last example.
The back slash is used to either give a char a special meaning or take away the special meaning of some chars.
/d/ means match a single 'd' char. /\d/ means match a single digit char( 0-9 )
/./ means match any single char. /\./ means match a single dot char.
That same expression could be created explicitly like this new RegExp(lit+.*specular.). Notice the forward slashes are not used in the last example.
The back slash is used to either give a char a special meaning or take away the special meaning of some chars.
/d/ means match a single 'd' char. /\d/ means match a single digit char( 0-9 )
/./ means match any single char. /\./ means match a single dot char.