Highlighted

CSV to Swatch Library script problems

Community Beginner ,
Feb 10, 2020

Copy link to clipboard

Copied

Hi All,

I have a spreadsheet of color names and their RGB values saved as a .csv that I need to import to a CC Swatch Library. I used the script below to perform this task back in 2015:

function main() {
     if (isOSX()) {
          var csvFile = File.openDialog('Select a CSV File', function (f) { return (f instanceof Folder) || f.name.match(/\.csv$/i);} );
     } else {
          var csvFile = File.openDialog('Select a CSV File','comma-separated-values(*.csv):*.csv;');
     }
     if (csvFile != null) {
          fileArray = readInCSV(csvFile);
          var columns = fileArray[0].length;
          //alert('CSV file has ' + columns + ' columns…');
          var rows = fileArray.length;
          //alert('CSV file has ' + rows + ' rows…');
          if (columns == 4 && rows > 0) {
               exchangeSwatches(csvFile);
          } else {
               var mess = 'Incorrect CSV File?';
               isOSX ? saySomething(mess) : alert(mess);
          }
     } else {
          var mess = 'Ooops!!!';
          isOSX ? saySomething(mess) : alert(mess);
     }
}

main();

function exchangeSwatches(csvFile) {
//    var docRef = app.documents.add();
     var docRef = app.activeDocument;
     var swatchgroup = docRef.swatchGroups.add();
     swatchgroup.name = csvFile.name;
     with (docRef) {  
        /*  for (var i = swatches.length-1; i >= 0; i--) {
               swatches.remove();
          } */
          for (var a = 0; a < fileArray.length; a++) {
               var n = fileArray[0]; // First Column is name            
               if (n == 'Cyan' || n == 'Magenta' || n == 'Yellow' || n == 'Black') {         
                    n = n + '-???'; // Reserved swatch name;
               }          
               r = parseFloat(fileArray[1]); // Second Column is Red
               g = parseFloat(fileArray[2]); // Third Column is Green
               b = parseFloat(fileArray[3]); // Forth Column is Bloo
               if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) {
                 var color = new RGBColor;
                 color.red = r;
                 color.green = g;
                 color.blue = b;
                 var swatch = swatches.add();
                 swatch.name = n;
                 swatch.color = color;
                 swatchgroup.addSwatch(swatch);
               } else {
                    var mess = 'Color values are out of range?';
                    isOSX ? saySomething(mess) : alert(mess);
               }
          }
     }
}

function readInCSV(fileObj) {
     var fileArray = new Array();
     fileObj.open('r');
     fileObj.seek(0, 0);
     while(!fileObj.eof) {
          var thisLine = fileObj.readln();
          var csvArray = thisLine.split(',');
          fileArray.push(csvArray);
     }
     fileObj.close();
     return fileArray;
}

function saySomething(stringObj) {
     var speakThis = 'I say, "' + stringObj + '"';
     alert(speakThis);
}

function isOSX() {
  return $.os.match(/Macintosh/i);
}

If I try it using Photoshop, I get the following error:

Error 21:undefined is not an object.

Line: 30

->  var swatchgroup = docRef.swatchGroups.add();

 

And when attempting the same thing in Illustrator, I get an endless loop of Script Alerts "I say, "Color values are out of range?"

 

Any help would be greatly appreciated!  ~ lori

Adobe Community Professional
Correct answer by DilliamWowling | Adobe Community Professional
function createSwatchGroupFromCSV()
{
    var valid = true; //running flag validation. if this is ever false, exit
    var docRef = app.activeDocument;
    var swatches = docRef.swatches;
    var swatchGroups = docRef.swatchGroups;
    var destSwatchGroup; //this is the swatch group that will be created
    var csvFileRegex = /.csv$/i;
    var csvRows; //array of all rows in csv file


    //function definitions

    //send message to user
    function saySomething(msg)
    {
        //no need to check the operating system here
        //alerts work the same on windows and mac
        alert("Script message:\n" + msg);
    }

    function getCSV()
    {
        var userSelection;

        userSelection = File.openDialog("Select a CSV File",function(f)
        {
            return f instanceof Folder || csvFileRegex.test(f);
        })

        if(!userSelection)
        {
            saySomething("No CSV file selected. Aborting.");
            valid = false;
        }
        return userSelection;
    }

    function readCSV()
    {
        //open the csv file to read it's contents
        //if the contents is an empty string, alert and exit
        //else, split by \n and set the resulting array to csvRows
        csvFile.open("r");
        var csvContents = csvFile.read();
        csvFile.close();

        if(csvContents === "")
        {
            saySomething("CSV file is blank.");
            valid = false;
            return;
        }

        csvRows = csvContents.split("\n");
    }

    function processCSV()
    {
        destSwatchGroup = swatchGroups.add();
        destSwatchGroup.name = csvFile.name;

        //loop the csvRows array
        var curRow;
        for(var r=0,len=csvRows.length;r<len && valid;r++)
        {
            curRow = csvRows[r];
            processRow(curRow);
        }

    }

    function processRow(row)
    {
        if(row === "" || row === "Name,r,g,b")
        {
            //nothing to see here.. just move on
            return;
        }

        var columns = row.split(",");

        var props = 
        {
            name: columns[0],
            r:columns[1],
            g:columns[2],
            b:columns[3]
        }
        

        createSwatch(props);
    }

    function createSwatch(props)
    {
        var rgbColor = new RGBColor();
        rgbColor.red = props.r;
        rgbColor.green = props.g;
        rgbColor.blue = props.b;

        var newSwatch = swatches.add();
        newSwatch.name = props.name;
        newSwatch.color = rgbColor;

        // destSwatchGroup.addSwatch(newSwatch);
    }


    



    //process

    if(valid)
    {
        var csvFile = getCSV();
    }

    if(valid)
    {
        readCSV();
    }

    if(valid)
    {
        processCSV();
    }


    if(valid)
    {
        saySomething("Success!");
    }


    



}
createSwatchGroupFromCSV();
TOPICS
Scripting

Views

247

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

CSV to Swatch Library script problems

Community Beginner ,
Feb 10, 2020

Copy link to clipboard

Copied

Hi All,

I have a spreadsheet of color names and their RGB values saved as a .csv that I need to import to a CC Swatch Library. I used the script below to perform this task back in 2015:

function main() {
     if (isOSX()) {
          var csvFile = File.openDialog('Select a CSV File', function (f) { return (f instanceof Folder) || f.name.match(/\.csv$/i);} );
     } else {
          var csvFile = File.openDialog('Select a CSV File','comma-separated-values(*.csv):*.csv;');
     }
     if (csvFile != null) {
          fileArray = readInCSV(csvFile);
          var columns = fileArray[0].length;
          //alert('CSV file has ' + columns + ' columns…');
          var rows = fileArray.length;
          //alert('CSV file has ' + rows + ' rows…');
          if (columns == 4 && rows > 0) {
               exchangeSwatches(csvFile);
          } else {
               var mess = 'Incorrect CSV File?';
               isOSX ? saySomething(mess) : alert(mess);
          }
     } else {
          var mess = 'Ooops!!!';
          isOSX ? saySomething(mess) : alert(mess);
     }
}

main();

function exchangeSwatches(csvFile) {
//    var docRef = app.documents.add();
     var docRef = app.activeDocument;
     var swatchgroup = docRef.swatchGroups.add();
     swatchgroup.name = csvFile.name;
     with (docRef) {  
        /*  for (var i = swatches.length-1; i >= 0; i--) {
               swatches.remove();
          } */
          for (var a = 0; a < fileArray.length; a++) {
               var n = fileArray[0]; // First Column is name            
               if (n == 'Cyan' || n == 'Magenta' || n == 'Yellow' || n == 'Black') {         
                    n = n + '-???'; // Reserved swatch name;
               }          
               r = parseFloat(fileArray[1]); // Second Column is Red
               g = parseFloat(fileArray[2]); // Third Column is Green
               b = parseFloat(fileArray[3]); // Forth Column is Bloo
               if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) {
                 var color = new RGBColor;
                 color.red = r;
                 color.green = g;
                 color.blue = b;
                 var swatch = swatches.add();
                 swatch.name = n;
                 swatch.color = color;
                 swatchgroup.addSwatch(swatch);
               } else {
                    var mess = 'Color values are out of range?';
                    isOSX ? saySomething(mess) : alert(mess);
               }
          }
     }
}

function readInCSV(fileObj) {
     var fileArray = new Array();
     fileObj.open('r');
     fileObj.seek(0, 0);
     while(!fileObj.eof) {
          var thisLine = fileObj.readln();
          var csvArray = thisLine.split(',');
          fileArray.push(csvArray);
     }
     fileObj.close();
     return fileArray;
}

function saySomething(stringObj) {
     var speakThis = 'I say, "' + stringObj + '"';
     alert(speakThis);
}

function isOSX() {
  return $.os.match(/Macintosh/i);
}

If I try it using Photoshop, I get the following error:

Error 21:undefined is not an object.

Line: 30

->  var swatchgroup = docRef.swatchGroups.add();

 

And when attempting the same thing in Illustrator, I get an endless loop of Script Alerts "I say, "Color values are out of range?"

 

Any help would be greatly appreciated!  ~ lori

Adobe Community Professional
Correct answer by DilliamWowling | Adobe Community Professional
function createSwatchGroupFromCSV()
{
    var valid = true; //running flag validation. if this is ever false, exit
    var docRef = app.activeDocument;
    var swatches = docRef.swatches;
    var swatchGroups = docRef.swatchGroups;
    var destSwatchGroup; //this is the swatch group that will be created
    var csvFileRegex = /.csv$/i;
    var csvRows; //array of all rows in csv file


    //function definitions

    //send message to user
    function saySomething(msg)
    {
        //no need to check the operating system here
        //alerts work the same on windows and mac
        alert("Script message:\n" + msg);
    }

    function getCSV()
    {
        var userSelection;

        userSelection = File.openDialog("Select a CSV File",function(f)
        {
            return f instanceof Folder || csvFileRegex.test(f);
        })

        if(!userSelection)
        {
            saySomething("No CSV file selected. Aborting.");
            valid = false;
        }
        return userSelection;
    }

    function readCSV()
    {
        //open the csv file to read it's contents
        //if the contents is an empty string, alert and exit
        //else, split by \n and set the resulting array to csvRows
        csvFile.open("r");
        var csvContents = csvFile.read();
        csvFile.close();

        if(csvContents === "")
        {
            saySomething("CSV file is blank.");
            valid = false;
            return;
        }

        csvRows = csvContents.split("\n");
    }

    function processCSV()
    {
        destSwatchGroup = swatchGroups.add();
        destSwatchGroup.name = csvFile.name;

        //loop the csvRows array
        var curRow;
        for(var r=0,len=csvRows.length;r<len && valid;r++)
        {
            curRow = csvRows[r];
            processRow(curRow);
        }

    }

    function processRow(row)
    {
        if(row === "" || row === "Name,r,g,b")
        {
            //nothing to see here.. just move on
            return;
        }

        var columns = row.split(",");

        var props = 
        {
            name: columns[0],
            r:columns[1],
            g:columns[2],
            b:columns[3]
        }
        

        createSwatch(props);
    }

    function createSwatch(props)
    {
        var rgbColor = new RGBColor();
        rgbColor.red = props.r;
        rgbColor.green = props.g;
        rgbColor.blue = props.b;

        var newSwatch = swatches.add();
        newSwatch.name = props.name;
        newSwatch.color = rgbColor;

        // destSwatchGroup.addSwatch(newSwatch);
    }


    



    //process

    if(valid)
    {
        var csvFile = getCSV();
    }

    if(valid)
    {
        readCSV();
    }

    if(valid)
    {
        processCSV();
    }


    if(valid)
    {
        saySomething("Success!");
    }


    



}
createSwatchGroupFromCSV();
TOPICS
Scripting

Views

248

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Feb 10, 2020 0
Adobe Community Professional ,
Feb 10, 2020

Copy link to clipboard

Copied

can you share the CSV?

 

As for your photoshop issue, the Adobe APIs from app to app are not the same. (it seems like adobe put together a team of developers to build the API for each app, but none of the teams were able to talk to each other during development.. so they all came up with something different... 

 

I don't code for photoshop, but I would guess that Document.swatchGroups is not a valid property as it is in Illustrator, hence the "undefined is not an object" error. 

 

And as for illustrator, it sounds like you have some values in your CSV that are invalid (i.e, less than 0 or greater than 255). Your script checks to make sure the values are within the appropriate range, but that condition is returning false, and sending your custom alert message instead.

 

add this console log right before your condition.. 

$.writeln("the csv has the following values:\nred= " + r + "\ngreen= " + g + "\nblue= " + b);
if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) {
//etc

 

or, you could separate that condition into multiple conditions so that you could see which one is failing

if (r <= 0 && r >= 255)
{
	saySomething("the values for red are out of range");
	//handle this error somehow
}
if (g <= 0 && g >= 255)
{
	saySomething("the values for green are out of range");
	//handle this error somehow
}
if (b <= 0 && b >= 255)
{
	saySomething("the values for blue are out of range");
	//handle this error somehow
}

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Feb 10, 2020 0
Community Beginner ,
Feb 11, 2020

Copy link to clipboard

Copied

Thanks so much for the response! Here's a link to the csv https://drive.google.com/file/d/1_yL7yDVuoSq1iORILuCvv5vgoRV_GUue/view?usp=sharing - I searched through the RGB values and didn't see anything out of range. Thoughts?

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Feb 11, 2020 1
Adobe Community Professional ,
Feb 12, 2020

Copy link to clipboard

Copied

ah. ok. i've loaded up your script and the csv file. It appears that your parsing of the CSV is not correct. At the point when you're setting your r, g, and b variables, you're trying to parseFloat() on an entire row, rather than a specific column. I'm not quite sure how to explain it, but when I put in a breakpoint and checked the values, here's what i found:

r = parseFloat(fileArray[1]); // at this point, fileArray[1] = ["P450-2 TAHITIAN BREEZE","184","233","228"];
g = parseFloat(fileArray[2]); // fileArray[2] = ["P450-3 RAINWATER","135","217","210"];
b = parseFloat(fileArray[3]); // etc,

So the issue isn't that your  values are out of range, but the result of each of these parseFloat() calls is NaN, because you're passing an array instead of a numerical value. 

 

Try to use more descriptive variable names so that you know at a glance what you're looking at.. "fileArray" is pretty vague and could mean literally anything. but if you use something like "csvRows" and "csvColumns" then it should be easier to debug because you can directly see whether the value of a given element (for example, csvRows[1]) looks correct.. 

 

Give me a few minutes and I'll try and rework this into something that works and looks a little cleaner.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Feb 12, 2020 0
Adobe Community Professional ,
Feb 12, 2020

Copy link to clipboard

Copied

function createSwatchGroupFromCSV()
{
    var valid = true; //running flag validation. if this is ever false, exit
    var docRef = app.activeDocument;
    var swatches = docRef.swatches;
    var swatchGroups = docRef.swatchGroups;
    var destSwatchGroup; //this is the swatch group that will be created
    var csvFileRegex = /.csv$/i;
    var csvRows; //array of all rows in csv file


    //function definitions

    //send message to user
    function saySomething(msg)
    {
        //no need to check the operating system here
        //alerts work the same on windows and mac
        alert("Script message:\n" + msg);
    }

    function getCSV()
    {
        var userSelection;

        userSelection = File.openDialog("Select a CSV File",function(f)
        {
            return f instanceof Folder || csvFileRegex.test(f);
        })

        if(!userSelection)
        {
            saySomething("No CSV file selected. Aborting.");
            valid = false;
        }
        return userSelection;
    }

    function readCSV()
    {
        //open the csv file to read it's contents
        //if the contents is an empty string, alert and exit
        //else, split by \n and set the resulting array to csvRows
        csvFile.open("r");
        var csvContents = csvFile.read();
        csvFile.close();

        if(csvContents === "")
        {
            saySomething("CSV file is blank.");
            valid = false;
            return;
        }

        csvRows = csvContents.split("\n");
    }

    function processCSV()
    {
        destSwatchGroup = swatchGroups.add();
        destSwatchGroup.name = csvFile.name;

        //loop the csvRows array
        var curRow;
        for(var r=0,len=csvRows.length;r<len && valid;r++)
        {
            curRow = csvRows[r];
            processRow(curRow);
        }

    }

    function processRow(row)
    {
        if(row === "" || row === "Name,r,g,b")
        {
            //nothing to see here.. just move on
            return;
        }

        var columns = row.split(",");

        var props = 
        {
            name: columns[0],
            r:columns[1],
            g:columns[2],
            b:columns[3]
        }
        

        createSwatch(props);
    }

    function createSwatch(props)
    {
        var rgbColor = new RGBColor();
        rgbColor.red = props.r;
        rgbColor.green = props.g;
        rgbColor.blue = props.b;

        var newSwatch = swatches.add();
        newSwatch.name = props.name;
        newSwatch.color = rgbColor;

        // destSwatchGroup.addSwatch(newSwatch);
    }


    



    //process

    if(valid)
    {
        var csvFile = getCSV();
    }

    if(valid)
    {
        readCSV();
    }

    if(valid)
    {
        processCSV();
    }


    if(valid)
    {
        saySomething("Success!");
    }


    



}
createSwatchGroupFromCSV();

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Feb 12, 2020 1
New Here ,
Sep 10, 2020

Copy link to clipboard

Copied

Hi, I also have this problem and after trying your script I still get an error.

 

->  var swatchgroup = docRef.swatchGroups.add();

 

Any help would be appretiated.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 10, 2020 0