1
votes

First time posting here, pretty new to coding Google Scripts, so I appreciate whatever help I can get.

I'm trying to design a macro and have gone through some threads but haven't found something that fits. I've tried to design the process as program-friendly as I can imagine, hopefully it'll help. The setup is as follows:

The macro is meant to copy data from Column1 and Column2 on MainSheet, and based on the information provided on the SheetName and Date columns, paste it on the respective cells on the secondary sheets. Repeat this process for each entry on MainSheet.

I here an image example of the process: Example MainSheet Example SheetA Example SheetB

Again, I'd appreciate whatever help I can get. Thank you very much!

Edit: Here is a Link to the example Google Sheets spreadsheet.

--- Valraz

4
Hey Valraz, welcome to Stackoverflow! I would like to know a few things of the date column: how does it behave? Can you have multiple rows with the same date for the same Sheet? Also, I imagine that SheetA, SheetB... 's records should be sorted by this field, too? Finally, and just for the record, please remember next time to attach example Sheets documents rather than images. ;)carlesgg97
Hey Carl, thanks for reaching out! To answer your questions: 1) The Date column in the secondary sheets is a timeline, where with each passing month of the year, a new entry will be added for each month. There will only be one record per month. 2) Yes, secondary sheet records will be sorted by Date as time goes by. 3) Sure, I'll see how to attach an example document right away :DValraz Krants
Why do you not use query, its more simple I thinkuser11982798

4 Answers

1
votes

This function will look for columns in the Sheets A,B... that match columns in the master and append that data for Sheet Names in ColumnA. It doesn't care how the columns in the sheets are laid out. So it runs a little slower than assuming a fix layout. But I was getting bored doing it the same way all of the time.

function copyData() {
  var ss=SpreadsheetApp.getActive();
  var msh=ss.getSheetByName('MainSheet');
  var mrg=msh.getRange(1,1,msh.getLastRow(),msh.getLastColumn());
  var vA=mrg.getValues();
  var hA=vA[0];
  var hObj={};
  hA.forEach(function(e,i){if(e){hObj[e]=i;}});
  vA.forEach(function(row,i){
    if(i>0) {
      var pA=[];
      var sh=ss.getSheetByName(row[hObj['SheetName']]);
      var shA=sh.getRange(1,1,1,sh.getLastColumn()).getValues()[0];
      var shObj={};
      shA.forEach(function(e,i){if(e){shObj[e]=i;}});
      row.forEach(function(c,j){
        if(shObj.hasOwnProperty(hA[j])) {
          pA.push(c);
        }
      });
      sh.appendRow(pA);
    }
  });
}

This is the straight forward way to do it.

function copyData1() {
  var ss=SpreadsheetApp.getActive();
  var msh=ss.getSheetByName('MainSheet');
  var mrg=msh.getDataRange();
  var vA=mrg.getValues();
  vA.forEach(function(r,i){
    if(i>0) {
      var sh=ss.getSheetByName(r[0]);
      sh.appendRow([r[1],r[2],r[3]],r[4]);//Modified for more columns
    }
  });
}
0
votes

Vital question I guess, how your Sheet A and Sheet B are receiving data? Is it someone who insert data or a script who is doing it?

0
votes

In Sheet A put this formula:

=QUERY(MainSheet!A:D,"select * where A='Sheet A'",-1)

In sheet B put this formula:

=QUERY(MainSheet!A:D,"select * where A='Sheet B'",-1)

And you can do this in your macro or google app script too

0
votes

Here as I said before to use Query, and this automatically create your sheet and get the next date:

function CopyDataFromMainSheet() {
  var spreadsheet = SpreadsheetApp.getActive();
  var mysheet;
  mysheet=spreadsheet.getSheetByName('MainSheet');
  //8 is spare columns that may be can used
  var myrange=mysheet.getRange('A1').offset(0, mysheet.getLastColumn()+8);
  myrange.setFormula('=Query(MainSheet!A2:A' + mysheet.getLastRow() + ',"Select A ,count(A) Group By A",0)'); 
  var jojo=mysheet.getRange(1,myrange.getColumn(),mysheet.getLastRow(),1).getValues();
  //Clear Query
  myrange.clear();
  for  (a=1 ;a<jojo.length;a++){
    //Create New Sheet That Not found included with header
    if(spreadsheet.getSheetByName(jojo[a][0])==null) if (jojo[a][0]!='') {
      spreadsheet.insertSheet(jojo[a][0]);
      spreadsheet.getRange('MainSheet!1:1').copyTo(spreadsheet.getSheetByName(jojo[a][0]).getRange("A1"), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
    }

    if(spreadsheet.getSheetByName(jojo[a][0])!=null) if (jojo[a][0]!='') {
      var myDate=new Date('1 jan 1900');

      var DestLastRow = spreadsheet.getSheetByName(jojo[a][0]).getLastRow();
      if (DestLastRow>1) myDate=new Date(spreadsheet.getSheetByName(jojo[a][0]).getRange('B' + DestLastRow).getValue());
      var dateStr = [
                  myDate.getFullYear(),
                  ('0' + (myDate.getMonth() + 1)).slice(-2),
                  ('0' + myDate.getDate()).slice(-2)
               ].join('-');
      myrange.setFormula('=Query(MainSheet!A:E,"Select * where A=\'' + jojo[a][0] + '\' and B>date \'' + dateStr + '\'",0)'); 

      var RsltRange=myrange.getA1Notation() + ":" + 
          mysheet.getRange("A1").offset(mysheet.getLastRow()-1,
          mysheet.getLastColumn()-1).getA1Notation();
      //Copy Value
      spreadsheet.getRange('MainSheet!' + RsltRange).copyTo(spreadsheet.getSheetByName(jojo[a][0]).getRange("A"+DestLastRow), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
      //copy format
      spreadsheet.getRange('MainSheet!' + RsltRange).copyTo(spreadsheet.getSheetByName(jojo[a][0]).getRange("A"+DestLastRow), SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false);

      myrange.clear();
    }
  }
};