datedatetimegoogle-sheetsgoogle-apps-scriptgoogle-sheets-formula

how to construct and write a formula to google sheets to perform a dynamic date calculation


I will be importing data in spreadsheet form from my database software. I am wanting to be able to take my cell that has a date of birth in MM/DD/YY format and through Google script make a formula that will report date at xxYY/xxMM/xxDD format of age. For example: dob=06/03/2021 Formula in Google in Google sheet would report age as 3Y/6M/19D. Then as the days and weeks went by the age would continually update, because the date difference would be performed in the spreadsheet. (Cat rescue computing age of cat if you are wondering about the application.)

The following formula works well in the spreadsheet, but I would like to have the script read the dob from the cell, convert it to the following formula (with the appropriate date of course) and put that calculation back in the same cell.

=DATEDIF(VALUE("6/3/2021"),NOW(),"Y")&"Y/"&DATEDIF(VALUE("6/3/2021"),NOW(),"ym")&"M/"&DATEDIF(VALUE("6/3/2021"),NOW(),"md")&"D"

I have worked on this for some time and have discovered that in creating the formula where I have to pass a quotation mark that I have to precede that quotation with a backslash. I am still having issues getting this to work. I'm struggling with getting even the formula written. The next step would be to use the dob read and embedded in the the formula.

  function calcAGE (){

    //  This function should get the date contents of a cell.
    //  A string will be assembled to replace the dob with a formula containing that dob.
    //  It will be written back to the same cell.
    //  The formula written to the spreadsheet will make a calculation
    //  of the current age in Years, months and days using the sheet NOW function
    //  This way the calcuation will be dynamic in the sheet and will update with time.


    // example contents of current active cell : 4/20/2024
    // example of formula that will be written to the active cell
    //        =DATEDIF(VALUE("4/20/2022"),NOW(),"Y")&"Y/"&DATEDIF(VALUE("4/20/2022"),NOW(),"ym")&"M/"&DATEDIF(VALUE("4/20/2022"),NOW(),"md")&"D"

    var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    var cell = sheet.getActiveCell();

    var dob= cell.getDisplayValues();

  // var string1="=a1 "
  //var string2="& \" \" & c1 & \" \" & " + dob
  // var string=string1 + string2


    // =DATEDIF(VALUE("4/20/2022"),NOW(),"Y")&"Y/"&DATEDIF(VALUE("4/20/2022"),NOW(),"ym")&"M/"&DATEDIF(VALUE("4/20/2022"),NOW(),"md")&"D"
    var string1="=a1"
  //var string2=\"),NOW(),\"Y")&\"Y/\"&DATEDIF(VALUE(\"
  //var string3=\"),NOW(),\"ym\")&\"M/\"&DATEDIF(VALUE(\"
  //var string4=\"),NOW(),\"md\")&\"D\"

    var string="\"=DATEDIF(VALUE(\"4/20/2022\"),NOW(),\"Y\")&\"Y/\"&DATEDIF(VALUE(\"4/20/2022\"),NOW(),\"ym\")&\"M/\"&DATEDIF(VALUE(\"4/20/2022\"),NOW(),\"md")&\"D\""

    
    cell.setFormula(string)

    
  }

Solution

  • So like TheMaster already commented, you can use template literals as an easy way to build a string dynamically. Template literals use backticks to surround the string, and you can then insert variables into the string with the dollar sign and curly brackets, like this:

    const myVar = 'variable'
    let string = `You can put a ${myVar} in a string.`
    

    You can read more about it here.

    I've incorporated template literals into your function:

    function calcAGE() {
      const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
      const cell = sheet.getActiveCell();
      const dob = cell.getDisplayValue();
      let string =`=DATEDIF(VALUE("${dob}"),NOW(),"Y")&"Y/"&DATEDIF(VALUE("${dob}"),NOW(),"ym")&"M/"&DATEDIF(VALUE("${dob}"),NOW(),"md")&"D"`;
      cell.setFormula(string);
    }
    

    Note: I changed getDisplayValues() into getDisplayValue(). The former still works, but it technically returns a 2D array, which may lead to problems down the line if you modify your function to include a bigger range. The latter just returns the string itself, which makes more sense in this case since you are only dealing with one cell.

    Hope this helps!