2

I'm working with a Google Sheets form which also accepts answers via text message. I'm trying to work out a method using Google Apps Scripts to split the body of the text message using a comma as a delimiter.

screenshot

The problem I'm running into is overwriting information submitted by the form and not by text message.

screenshot 2

My current script is:

function splitCells() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
  var colC = sheet.getRange("C2:C").getValues();
  var colD = sheet.getRange("D2:D").getFormulas();
  //Logger.log(colC);
  for(var i in colC){
    if(typeof(colC[i][0]) =='string'){
      colD = '=if(istext(C2:C),split(C2:C,",",true))';
    } else {
      colD = 'D2:D';
    }
  }
  sheet.getRange("D2:D").setFormula(colD);
}

The function is working correctly, splitting the contents of column C (the SMS body) into D, E, and F as expected. But, it's overwriting data in column D because the else condition isn't being met (colC is blank in those places).

How do I get the script to move over blank cells without replacing the contents of the cell?

It's sort of confusing to explain, so here's a sample document you can check out. A custom menu should install when you open it and you can run the script from there (or from the editor).

Thanks for the help.

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Brian
  • 4,274
  • 2
  • 27
  • 55

1 Answers1

3

There are a few simple mistakes to start.

  • A spreadsheet cell can contain a value or a formula, not both.

  • If you use setFormula/s(), any value in a cell will be replaced by the result of the formula, even if the formula is blank.

    Since you want to have a mix of values and formulas, you should set formulas only in the specific cells that match the criteria:

    // If we received a SMS response, set a formula to parse it
    sheet.getRange(2+i,4).setValue('=if(istext(C2:C),split(C2:C,",",true),"")')
    
  • The criteria test isn't sufficient. A blank cell is still of type string, but it's a blank string. So this evaluates true for both form entries and SMS entries:

    if(typeof(colC[i][0]) =='string'){ ...
    

    A more effective test checks for a non-blank response:

    if(colC[i][0] != ''){ ...
    

    An even better one would ensure that the value in column C meets the required format requirements.

  • You are looping over an array using the for .. in loop, which is meant for going over object properties. This works, but the loop value i will be a string, which can cause problems when doing math. Better to get in the habit of looping over the numeric index. (See.)

  • The full-column range expression C2:C is elegant, however you end up with an array that contains all rows in the spreadsheet, more than a thousand in your example. Since we're going to loop over all rows, it's best to limit that range:

    var colC = sheet.getRange(2, 3, sheet.getLastRow()).getValues();  // C2:C, only non-blank rows
    

Adjusting for those problems, we have:

function splitCells2() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
  var colC = sheet.getRange(2, 3, sheet.getLastRow()).getValues();  // C2:C, only non-blank rows
  //Logger.log(colC);
  for(var i=0; i< colC.length; i++){
    if(colC[i][0] != ''){
      // If we received a SMS response, set a formula to parse it
      sheet.getRange(2+i,4).setValue('=if(istext(C2:C),split(C2:C,",",true),"")')
    }
  }
}
Community
  • 1
  • 1
Mogsdad
  • 44,709
  • 21
  • 151
  • 275
  • Thanks for such a detailed answer. I'm teaching myself as I go, and a lot of the mistakes you point out are things I do in other projects, so it's nice to be able to improve other things I'm working on. I really appreciate it. – Brian Apr 30 '15 at 10:41
  • I figured as much, and I'm glad to have helped. (2 'favorites' on the question already, so it's resonated with folks.) I'd love to learn more about the SMS portion, do you have a blog post or link that would educate? – Mogsdad Apr 30 '15 at 14:52
  • Yeah, I've got a draft. I'm working today on analyzing the data and then I'll link a post back here with the method I'm using. Definitely hacky, but it works. – Brian Apr 30 '15 at 15:18
  • Here's a writeup of [getting text messages into Google Sheets](http://blog.ohheybrian.com/text-messages-google-form-responses/). There's no API for Google Voice right now, so it's a little messy, but it works well. Second part to this post coming later today (hopefully). – Brian May 01 '15 at 17:47