Copy link to clipboard
Copied
Im trying to write a script that i can point to a project folder. The script then populates a list with subfolders for me to select from. If the subfolder is selected it searches through the subfolder to open the latest .psb file with 'BG' in the filename. It does this for each of the subfolder selected in the list.
I managed to get it to work selecting a single subfolder but as soon as i try to make it work with multiple subfolders it fails. It currently fails even with single subfolder selected
The error i get is "Error: Selected subfolder is undefined." but no mater what i add to debug in visual code i get the same error.
Any idea how to fix it?
// Save this script as OpenLatestBGFileWithUI.jsx
// Function to find the latest BG PSB file in a folder
function findLatestBGFile(folder) {
try {
var files = folder.getFiles("*.psb");
var latestFile = null;
var latestDate = new Date(0);
if (files) { // Check if files is defined
for (var i = 0; i < files.length; i++) {
var file = files[i];
// Check if the file name contains "BG"
if (file.name.indexOf("BG") !== -1) {
var fileDate = file.modified;
// Compare file modification date to find the latest one
if (fileDate > latestDate) {
latestDate = fileDate;
latestFile = file;
}
}
}
}
return latestFile;
} catch (e) {
// Log any error during file search
$.writeln("Error finding latest BG file: " + e);
return null;
}
}
// Prompt user to select a project folder
var projectFolder = Folder.selectDialog("Select the project folder");
if (!projectFolder) {
alert("No project folder selected. The script will now exit.");
} else {
// Get a list of subfolders
var subfolders = projectFolder.getFiles(function (file) {
return file instanceof Folder;
});
// Create UI
var ui = new Window("dialog", "Select Subfolders");
var list = ui.add("listbox", [0, 0, 200, 200], undefined, { multiselect: true });
for (var i = 0; i < subfolders.length; i++) {
list.add("item", subfolders[i].name);
}
var button = ui.add("button", [0, 210, 200, 240], "Open Latest BG");
// Event handler for button click
button.onClick = function () {
try {
var selectedSubfolderIndices = list.selection;
if (!selectedSubfolderIndices || selectedSubfolderIndices.length === 0) {
alert("No subfolders selected. Please select one or more subfolders.");
return;
}
for (var i = 0; i < selectedSubfolderIndices.length; i++) {
var selectedSubfolderIndex = selectedSubfolderIndices[i];
$.writeln("Selected Subfolder Index: " + selectedSubfolderIndex);
try {
// Get selected subfolder using array indexing
var selectedSubfolder = subfolders[selectedSubfolderIndex];
if (!selectedSubfolder) {
alert("Error: Selected subfolder is undefined.");
continue; // Skip to the next iteration
}
$.writeln("Selected Subfolder: " + selectedSubfolder.name);
// Find all PSB files in the selected subfolder
var psbFiles = selectedSubfolder.getFiles("*.psb");
$.writeln("Found PSB files in '" + selectedSubfolder.name + "': " + psbFiles.length);
// Find the latest BG PSB file in the selected subfolder
var latestBGFile = findLatestBGFile(selectedSubfolder);
if (latestBGFile) {
// Log the file path to check if it's correct
$.writeln("Opening file: " + latestBGFile.fsName);
// Open the latest BG PSB file in Photoshop
app.open(latestBGFile);
} else {
alert("No BG PSB files found in the selected subfolder.");
}
} catch (subfolderError) {
// Log any error during subfolder processing
$.writeln("Error processing subfolder: " + subfolderError);
}
}
ui.close();
} catch (e) {
// Log any error during button click
$.writeln("Error during button click: " + e);
alert("An error occurred. Check the ExtendScript Toolkit console for details.");
}
};
// Show UI
ui.show();
}
Replace
var selectedSubfolderIndex = selectedSubfolderIndices[i];
with
var selectedSubfolderIndex = selectedSubfolderIndices[i].index;
Copy link to clipboard
Copied
Replace
var selectedSubfolderIndex = selectedSubfolderIndices[i];
with
var selectedSubfolderIndex = selectedSubfolderIndices[i].index;
Copy link to clipboard
Copied
Thanks, that fixed it!
Copy link to clipboard
Copied
Please mark @r-bin ’s post as »Correct Answer« if it resolved the original issue.
Copy link to clipboard
Copied
I decided to try to make the script more universally useful so added a search box to choose which files are opened within the subfolders.
Im struggling with the logic though.
I want the script to search the subfolders and open files that match the search term, if the checkbox is also checked it only opens the latest file of the match search term. This currently works.
What doesn't work is if i put multiple search terms in which are comma seperated.
For example, a subfolder has x6 files in it, x3 with FG in the filename and x3 with BG in the filename.
If i add 'FG,BG' to the search terms and check the 'open latest only' checkbox then 2 files should open from this subfolder. The latest 2 files with FG and BG in the filename.
// Save this script as OpenLatestFilesWithSearch.jsx
// Function to find the latest PSB files in a folder based on search terms
function findLatestFiles(folder, searchTerms, openLatestOnly) {
try {
var files = folder.getFiles("*.psb");
var latestFiles = [];
if (files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var matchCount = 0;
for (var j = 0; j < searchTerms.length; j++) {
var searchTerm = searchTerms[j];
// Check if the file name contains the current search term
if (file.name.indexOf(searchTerm) !== -1) {
matchCount++;
if (openLatestOnly) {
// Break if only the latest file is needed for this search term
break;
}
}
}
if (matchCount === searchTerms.length) {
latestFiles.push(file);
}
}
// Sort the files by modification date in descending order
latestFiles.sort(function (a, b) {
return b.modified - a.modified;
});
if (openLatestOnly && latestFiles.length > 1) {
// If "Open Latest Only" is checked, keep only the latest file for each search term
var uniqueLatestFiles = [];
for (var k = 0; k < latestFiles.length; k++) {
var currentFile = latestFiles[k];
// Extract the part of the file name before the first underscore
var fileNamePrefix = currentFile.name.split('_')[0];
// Check if the file name prefix is not already in the unique list
var found = false;
for (var l = 0; l < uniqueLatestFiles.length; l++) {
if (uniqueLatestFiles[l].name.indexOf(fileNamePrefix) !== -1) {
found = true;
break;
}
}
if (!found) {
uniqueLatestFiles.push(currentFile);
}
}
latestFiles = uniqueLatestFiles;
}
}
return latestFiles;
} catch (e) {
// Log any error during file search
$.writeln("Error finding latest files: " + e);
return [];
}
}
// Prompt user to select a project folder
var projectFolder = Folder.selectDialog("Select the project folder");
if (!projectFolder) {
alert("No project folder selected. The script will now exit.");
} else {
// Get a list of subfolders
var subfolders = projectFolder.getFiles(function (file) {
return file instanceof Folder;
});
// Create UI
var ui = new Window("dialog", "Select Subfolders");
var list = ui.add("listbox", [0, 0, 200, 200], undefined, { multiselect: true });
var searchField = ui.add("edittext", [0, 210, 150, 230], "", { multiline: false });
var openLatestOnlyCheckbox = ui.add("checkbox", [160, 210, 300, 230], "Open Latest Only");
openLatestOnlyCheckbox.value = true; // Set the checkbox value manually
var button = ui.add("button", [160, 240, 200, 270], "Open Files");
for (var i = 0; i < subfolders.length; i++) {
list.add("item", subfolders[i].name);
}
// Event handler for button click
button.onClick = function () {
try {
var selectedSubfolderIndices = list.selection;
if (!selectedSubfolderIndices || selectedSubfolderIndices.length === 0) {
alert("No subfolders selected. Please select one or more subfolders.");
return;
}
var searchTerms = searchField.text ? searchField.text.split(',') : [];
var openLatestOnly = openLatestOnlyCheckbox.value;
for (var i = 0; i < selectedSubfolderIndices.length; i++) {
var selectedSubfolderIndex = selectedSubfolderIndices[i].index;
$.writeln("Selected Subfolder Index: " + selectedSubfolderIndex);
try {
// Get selected subfolder using array indexing
var selectedSubfolder = subfolders[selectedSubfolderIndex];
if (!selectedSubfolder) {
alert("Error: Selected subfolder is undefined.");
continue; // Skip to the next iteration
}
$.writeln("Selected Subfolder: " + selectedSubfolder.name);
// Find the latest PSB files in the selected subfolder based on search terms
var latestFiles = findLatestFiles(selectedSubfolder, searchTerms, openLatestOnly);
if (latestFiles.length > 0) {
// Open the latest PSB files in Photoshop
for (var j = 0; j < latestFiles.length; j++) {
var file = latestFiles[j];
$.writeln("Opening file: " + file.fsName);
app.open(file);
}
} else {
alert("No PSB files found in the selected subfolder with the specified search terms.");
}
} catch (subfolderError) {
// Log any error during subfolder processing
$.writeln("Error processing subfolder: " + subfolderError);
}
}
ui.close();
} catch (e) {
// Log any error during button click
$.writeln("Error during button click: " + e);
alert("An error occurred. Check the ExtendScript Toolkit console for details.");
}
};
// Show UI
ui.show();
}
Copy link to clipboard
Copied
You can get folders in a selected folder with this code as well, it may work better. Then you have an array of just Folder objects.
try{
var f = []; //empty array to hold Folder objects
var a = Folder.selectDialog(); //get top folder
var s = a.getFiles(); //get children
for(var t = 0; t < s.length; t++){ //loop through children
if(s[t] instanceof Folder){ test for Folder
f.push(s[t]); //load folder objects to new array
}
}
//Window.alert(f.toString()); //show folder objects
}
catch(e){
Window.alert(e + ' ' + e.line);
}