1

This is my first time using javascript, so maybe I am missing something. The task: I have code that, given a table of information, creates new sheets for each unique name in one of the columns. Notice how Josh chan appears in two of these columns:

sample

With a large enough list, it would be tedious to go through 100 sheets. Is there any way to export each google sheet as its own document?

I've looked hard, I haven't found any way to do this. Any help and expertise would be much appreciated. Side note: this might be possible with macros or something like that.

Thanks!

Pᴇʜ
  • 56,719
  • 10
  • 49
  • 73
jeisenman19
  • 45
  • 1
  • 8
  • Let me clear this up, you want to have multiple sheets based on the unique names here? – NightEye Jun 21 '21 at 22:01
  • Yes, so I have created unique sheets for each of the rows in this columns. E.g. I'd have unique sheets for Jordan, Barkerl Jack, Rose; etc. These would all be in the same master file but different google sheets. – jeisenman19 Jun 21 '21 at 22:11
  • 1
    Oh. Wow. The script works! Thanks so much. This has been a huge help. After 20 hours of just grinding my teeth. – jeisenman19 Jun 21 '21 at 23:56
  • 1
    I'm glad it worked and solved your issue @jeisenman19. If we answered your question, please click the accept button on the left (check icon). By doing so, other people in the community, who may have the same concern as you, will know that theirs can be resolved. If the accept button is unavailable to you, feel free to tell me. [how to accept answer](https://stackoverflow.com/help/accepted-answer) – NightEye Jun 22 '21 at 00:01

2 Answers2

1

You need to filter your data with regards to the unique names. You also need to manipulate the data so you can easily loop them all and add them onto a new sheet. There is a lot going on but there are ample comments to state what each step does.

Code:

function createSheetPerUniqueName() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getActiveSheet();
  var range = sheet.getDataRange();
  var values = range.getValues();

  // remove first row as header
  var headers = values.shift();

  // get unique names
  var name = values.map(row => row[1]).filter(function (value, index, self) {
    return self.indexOf(value) === index;
  });

  // traverse unique names
  name.forEach(function (uniqueName) {
    // get all rows with the unique name
    var data = values.filter(row => row[1] == uniqueName);

    // pass the id of destination folder (in between "folders/" and "?resourcekey=")
    var folder = DriveApp.getFolderById("1UvAE1ZbFso35kiooJ7lUq_nDH2QgUYyS");
    // create spreadsheet
    var temporarySheet = SpreadsheetApp.create(uniqueName);
    // move created spreadsheet to folder and get its ID
    var sheetId = DriveApp.getFileById(temporarySheet.getId()).moveTo(folder).getId();

    // access the sheet via ID
    var newSpreadSheet = SpreadsheetApp.openById(sheetId);
    // rename Sheet1 to name
    var newSheet = newSpreadSheet.getSheets()[0];
    newSheet.setName(uniqueName);

    // set header
    newSheet.getRange(1, 1, 1, data[0].length).setValues([headers]);
    // set data
    newSheet.getRange(2, 1, data.length, data[0].length).setValues(data);
  });
}

Sample Data:

sample

Output:

output output2

Note:

  • For every unique name, there will be a corresponding spreadsheet to be generated in the chosen folder. And all those rows with that name will be added to that new spreadsheet where it belongs.

Resource:

NightEye
  • 10,634
  • 2
  • 5
  • 24
  • Oh, semantics. First, thanks for the effort. Once you have the unique sheets, is there any way to export each sheet to a folder as a separate document? E.g. Sheet 1 is called Bob. Sheet two is Sidney. The folder would contain one document for Bob and a completely separate document for Sidney. Does this make sense? – jeisenman19 Jun 21 '21 at 23:13
  • Yes, that would be doable.. Let me modify my answer – NightEye Jun 21 '21 at 23:16
  • Oh, thanks in advance. This problem has really gotten me. – jeisenman19 Jun 21 '21 at 23:38
  • I have modified my answer @jeisenman19, please check. – NightEye Jun 21 '21 at 23:45
1

So if I'm getting this correctly you want the following:

For every unique entry make a new Google Sheets (so a new file, not just a tab)

First things first

You'll have to create a template document which you'll copy every time a new document's made. So for this example, I'll use a sheet called templateSheet as the template, and I'll refer to the main sheet as masterSheet.

Master sheet

Try using this code and filling out the variable templateSheet with the id of your templateSheet

function myFunction() {
  // Template sheet stuff
  // Insert id of template sheet
  const templateSheet = "";
  const templateSheetObj = DriveApp.getFileById(`${templateSheet}`);

  // Main sheet stuff
  const ss = SpreadsheetApp.getActiveSheet();
  const allData = ss.getRange(2, 1, ss.getLastRow() - 1, 6).getValues();
  let usersDone = [];

  for (const entry of allData) {
    const fullName = entry[1];
    if (!usersDone.includes(fullName)) {
      // this makes a copy and sets the title of document to fullname variable
      const copy = templateSheetObj.makeCopy(fullName)
      usersDone.push(fullName);
    }
  }
}

Output

How my Drive folder now looks

Content of new document

Since you have the new sheet object saved in copy you can freely do whatever with the new copy, like adding all the rows of data or anything like that.

PiratePie
  • 214
  • 2
  • 7