I have a sheet that has has a bunch of data in it, all tied to a site URL. It's not sorted data, and each site can have no log entries or many.

There are many items in this file, so I'm looking for a way to split the Sheet into multiple Sheets (not tabs) that have only content from one site. For example, one file would only have rows containing Team1 URLs, and the second would only contain Team2 URLs.

There are similar questions on here, but I'll have a large number of these files with a large number of different sites in each one. Doing an importrange on every URL as suggested here would be too time-consuming. This answer wouldn't work for the same reason.

I have a similar script that splits a sheet into a new tabs at a set line mark - eg, 25 items, but I'm not sure how to make this general enough to make and track on new Sheets.

  • What if : you split a first time in two tabs the original sheet(one tab for each team) ; then importrange tab#1 in Sheet #1 and importrange tab#2 in Sheet#2 ?
    – pjmg
    Commented Oct 29, 2019 at 15:09

1 Answer 1


I wrote some code to fix this as there wasn't any other solution, I'm not sure how elegant it is but it seems to work. I added some code that blacklists certain error types we don't want to see that wasn't part of the original question.

// press the run button when the sheet you want to split is selected.
function splitMeIntoPieces() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Transaction Log");
  var data = sheet.getDataRange().getValues();
  const sourceTypeBlacklist = ["SPRoleAssignment","SPRoleAssignmentSet", "SPDocumentVersion"]; // filter these out, we don't need them
  const headers = data.splice(0, 1); //seperate out the headers and store them

  const distinctSites = data.reduce((acc, row) => { //iterates over each object in the array https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
    const groupKey = row[1]; //selecting the second (B) colum as the key - what we want to group by
    if (!acc[groupKey]) { //if the accumulator (the output object) does not have the key, set an empty one. we'll fill it in in the next step
      acc[groupKey] = [];
    if (sourceTypeBlacklist.indexOf(row[9])==-1 ) { //ignore permissions errors
      acc[groupKey].push(row); // add the row to the array that matches the group key
    return acc; //the accumulator object now has the previous data and is passed again to work on the next row
  }, {});

  for (var x in distinctSites) { 
    const rowsForSite = distinctSites[x];
    // "For each individual site in this list"
    var newss = SpreadsheetApp.create(("Logs for the Teams site: "+x));
    //console.log("new sheet is:" + newss.getId());
    const rowsToWrite = headers.concat(rowsForSite);

    var range = newss.getRange("A1:Q"+ (rowsToWrite.length)); //remeber we're writing the headers along with the data

    //console.log("length: "+rowsForSite.length);
    //console.log("Working on site: ",x);

    for (var q in rowsForSite) {
      // this is each log item for each site in the list
      const row = rowsForSite[q];


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.