-1

I have a spreadsheet: https://docs.google.com/spreadsheets/d/1df2cp4DsJvSeBvhsNjLgIa5x_RO1X7s_APRdFzU6jqQ/edit?usp=sharing

|    | C                               | D              |
|----+---------------------------------+----------------|
| 1> | From IFTTT                      | Extracted Date |
| 2> | 0809 1800 0909 0600 RLK Steiger | 08.09.2020     |
| 3> | 0809 1800 0909 0600 RLK Dvorak  | 08.09.2020     |
| 4> | 0909 0600 0909 1800 UNIS Brando | 09.09.2020     |

Where I get automaticly SMS trought the android program "IFTTT" I have there then formulas to count the hours worked, date etc. that is taken from the SMS body.

|    | C                               | D                                         |
|----+---------------------------------+-------------------------------------------|
| 1> | From IFTTT                      | Extracted Date                            |
| 2> | 0809 1800 0909 0600 RLK Steiger | =MID(C2,1,2)&"."&MID(C2,3,2)&".2020"      |
| 3> | 0809 1800 0909 0600 RLK Dvorak  | =MID(C3,1,2)&"."&MID(C3,3,2)&".2020"      |
| 4> | 0909 0600 0909 1800 UNIS Brando | //<= New row from IFTTT. Set formula here |

I have now the issue that the android program will always put the SMS to the last blank row. So I can't have the formulas pre-set there, because then it goes under the formulas and it's useles unles done by hand.

I've tried with Google Apps Scripts. Is there anyway how to do that by the Google Sheets macros? I've tried the following:

function myFunction() {    
  var spreadsheet = SpreadsheetApp.getActive();       
   spreadsheet.getRange('D1').activate();
   spreadsheet.getCurrentCell().setFormula('=if(isnumber(A1);mid(C1;1;2)&"."&mid(C1;3;2)&".2020";""))

However if it's used, then it won't leave the cell empty, but with the formula in it and also I would have to do this for each cell. My idea was that if(set the formula) else delete it, but I don't know how to write that in Javascript.

Ideally it would be that if column D:D last row contains text, then use the formulas I have there, but I don't know how to do that either.

TheMaster
  • 45,448
  • 6
  • 62
  • 85
  • 3
    I have to apologize for my poor English skill. Unfortunately, from your question and your shared Spreadsheet, I cannot understand about your current issue and your goal. I cannot understand about 3 sheets in your shared Spreadsheet. And also, I cannot understand about `My idea was that if(set the formula) else delete it` and `Ideally it would be that if column D:D last row contains text, then use the formulas I have there`. Can I ask you about the detail of them? – Tanaike Sep 10 '20 at 22:37
  • Hi, sorry for the late answer. Sure. The first sheet there is where I get the automatical SMS from the program itself. On the second there are counts for weekends hours, work trought night, etc. And the last "SMS-tabulka" I've tried to go around the issue that the SMS go to the last blank row, to simply copy the data to new sheet, but unfortunatelly that didn't worked, because it then move all the formulas by 1. – Patrik Gremlica Sep 11 '20 at 07:19
  • Thank you for replying and adding more information. Now I noticed that an answer has already been posted. In this case, I would like to respect the existing answer. I think that it will resolve your issue. – Tanaike Sep 11 '20 at 07:32
  • 1
    @Tanaike Feel free to add any other answer or approaches, if you wish. You're not disrespecting my answer by posting another one. – TheMaster Sep 11 '20 at 07:40
  • 1
    @TheMaster Thank you for the replying. When I found the other solution, I would like to propose it. – Tanaike Sep 11 '20 at 07:50

2 Answers2

2

This is a very common problem when dealing with auto-inserted data through sheets api or Google forms. The easiest solution would be to convert all your formulas into arrayformulas. For eg, Your formula in D2

=MID(C2,1,2)&"."&MID(C2,3,2)&".2020

can be modified as

In D1:

=ARRAYFORMULA({"Extracted Date";MID(C2:INDEX(C:C,COUNTA(C:C)),1,2)&"."&MID(C2:INDEX(C:C,COUNTA(C:C)),3,2)&".2020"})

OR using :

=ARRAYFORMULA({"Extracted Date";REGEXREPLACE(C2:INDEX(C:C,COUNTA(C:C)),"(\d{2})(\d{2}).*","$1.$2.2020")})

The table then becomes:

|    | C                               | D                                                                                                                   |
|----+---------------------------------+---------------------------------------------------------------------------------------------------------------------|
| 1> | From IFTTT                      | =ARRAYFORMULA({"Extracted Date";MID(C2:INDEX(C:C,COUNTA(C:C)),1,2)&"."&MID(C2:INDEX(C:C,COUNTA(C:C)),3,2)&".2020"}) |
| 2> | 0809 1800 0909 0600 RLK Steiger |                                                                                                                     |
| 3> | 0809 1800 0909 0600 RLK Dvorak  |                                                                                                                     |
| 4> | 0909 0600 0909 1800 UNIS Brando |                                                                                                                     |

Here the rest of D:D is auto filled automatically.

  • We use array literals on the header row: {"Extracted Date";Formula for rest of the column}

  • Whenever a new row comes, INDEX/COUNTA() auto calculates the last row and automatically fills the formula upto last row. See here for a deeper explanation on INDEX/COUNTA.

TheMaster
  • 45,448
  • 6
  • 62
  • 85
  • Hello, Thank you so much for the help! I've tried to do that, but I don't know why but there are some differences due to languge I assume. For example I can't use the , but I have to use ; Which is OK, I can check that. However it won't fill the table, since according to sheets there are 3 arguments for the MID function instead of 3. I'm not sure if I'm doing anything wrong there? And if possible - I don't want to bother too much, this was great help already! To get there the data from another sheet "List2" it would be possible with the function counta right? Thank you so much again! – Patrik Gremlica Sep 11 '20 at 07:16
  • @PatrikGremlica About mid, Could you show the current formula you edited in here? Kindly ask new questions for non-related issues – TheMaster Sep 11 '20 at 07:24
  • Hi, Ok sorry, this is my first time using this site myself, I'm really grateful for this and also edit of the original question. I've ussed this, unfortunatelly it'l translate to Czech: =ARRAYFORMULA({"Datum";ČÁST(C2;INDEX(C:C;POČET2(C:C));1;2)&"."&ČÁST(C2;INDEX(C:C;POČET2(C:C));3;2)&".2020"}) – Patrik Gremlica Sep 11 '20 at 07:40
  • 1
    @PatrikGremlica `=ARRAYFORMULA({"Datum";ČÁST(C2:INDEX(C:C;POČET2(C:C));1;2)&"."&ČÁST(C2:INDEX(C:C;POČET2(C:C));3;2)&".2020"})` – TheMaster Sep 11 '20 at 07:42
  • You are really the master! :) Thank you it's working now. The only thing is the last row is kept blank eventough there is text next to it, is there any solution for that, or it can't be changed? If not it's not issues, as I've wrote before, thisi is way more helpful then I've could've asked for. Thank you again! – Patrik Gremlica Sep 11 '20 at 07:54
  • 1
    @PatrikGremlica That shouldn't happen. Do you have a extra blank space in between rows in `C:C`? If so, You should remove it. Alternatively, Just add +1 to the both the counta: `COUNTA(...)+1`. Consider accepting the answer, if It helped by clicking the checkmark on the answers' left. – TheMaster Sep 11 '20 at 09:15
  • @PatrikGremlica Did you fix it? – TheMaster Sep 11 '20 at 09:37
  • I'm really sorry to bother - I've tried to solve this all day now... can you please check what I'm doing wrong in this formula: =ARRAYFORMULA({"den týdne";DENTÝDNE(D5:INDEX(D:D;POČET2(D:D)));D2;2}) - it should put back the day of the week, but it doesn't or when it does, it's not right number. – Patrik Gremlica Sep 11 '20 at 12:06
  • @PatrikGremlica Why don't you ask a new question? You should at least provide 1. The error message.2. The English formula. 3. Sample table/data/csv of 2-4 rows to reproduce the same error. See [mcve]. I don't have enough information to diagnose the problem or provide a solution for this issue, that you claim exists – TheMaster Sep 11 '20 at 12:13
  • Can't ask another question for 2 days. Understood, when it would be possible I will submit new question. Thank you for all the help! :) – Patrik Gremlica Sep 11 '20 at 12:24
  • @PatrikGremlica Link here, when you do ask – TheMaster Sep 11 '20 at 12:26
  • master - I have the link for new question: https://stackoverflow.com/questions/63881838/google-sheets-night-shift-hours-worked-with-arrayformula-weekends-hours-worke – Patrik Gremlica Sep 14 '20 at 11:42
0

Solution:

  • This solution uses . This does not need array formulas, but uses autofill. For the solution to work, you should not use array formula, but plain formula.
  • Get the active range, which will represent the current range inserted onChange or onFormSubmit.
  • offset the range to the right to get the calculated columns and expand the range to all of calculated columns on the right.
  • Use range.autoFillToNeighbor to fill all the calculated regions of the range.

Sample script:

/**
 * @param {GoogleAppsScript.Events.SheetsOnChange|GoogleAppsScript.Events.SheetsOnFormSubmit} e
 */
const onFormSubmitORonChange = e => {
  const rg = SpreadsheetApp.getActiveRange(),
    wd = rg.getWidth(),
    sh = rg.getSheet(),
    lc = sh.getLastColumn(),
    numRows = Math.max(
      rg
        .offset(0, wd, 1, 1)
        .getNextDataCell(SpreadsheetApp.Direction.UP)
        .getRow() - 1,
      1
    ),
    numCols = lc - wd;
  sh.getRange(2, wd + 1, numRows, numCols).autoFillToNeighbor(
    SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES
  );
};

References:

TheMaster
  • 45,448
  • 6
  • 62
  • 85