Copy Notes Between Google Sheets
Published: 2019-01-15 7:53 PM
Category: Code | Tags: copy, custom, google apps script, notes, script
If you work in big systems, sometimes you come across a situation where you want to share a single tab of a Google Sheet with someone else rather than the master copy. An easy way is to just make a snapshot copy of that tab and share a new sheet with them. A more advanced method is to use a parent/child relationship and some Sheets cell formulas to share an always-up-to-date copy of the master data. The problem with that (there's always a problem, isn't there?) is that it only copies the data, none of the notes or any other information that might be on the master sheet.
In this post, I'm going to give an example of a Google Apps Script that can be used to copy notes from a master parent sheet to a child spreadsheet. If you want to make a copy of a folder with working examples, ask and thou shalt receive.
The Basic Setup
For this example, we have a master Google Sheet with several rows of data organized by location, like this:

The sample master spreadsheet
We want to share child sheets tied to schools A, B, and C with only their relevant data. This first part is done with query and importrange in the following formula in cell A1 of the child spreadsheet.
=query(importrange("masterSheetURL","Sheet1:A:E"),"SELECT * WHERE Col1 CONTAINS 'A'",1)
Query selects an entire row where Column 1 contains the string 'A'. If this were a real situation, the building name would be the imported data, which looks like this:

Imported data into a child spreadsheet using QUERY.
I prefer query because I don't have to select a specific range - it will look at the entire sheet for that data. If you don't want to import notes, this works really well. If you do want to import notes, make sure data is grouped together because you need to determine some offsets when writing to the child sheets. Create a second spreadsheet in masterthat has the following structure:

Helper sheet in master with links to the child sheets
where column A is the building (or location or other selector) and the URL to the child sheet you want to update. Column C will become very important as it holds the offset data for writing notes to the child sheet.
The Script
Copying notes can only be done with the .getNotes() Google Apps Script method. This script looks at the sheet and uses a couple of loops to build arrays to post to the child sheets. The first challenge is to set the offsets. Notice location B in the master sheet is rows six through eight, while on the child sheet it is rows two through four. Without setting an offset, our notes would be written into the wrong rows, and that's no fun.
After running that script, your child sheet will update the offset of each building in Column 3 of the helper sheet in the master copy. I also added an onChange trigger to this function so it runs when rows are inserted anywhere in the sheet.
Now, you're ready to copy notes from one sheet to another.
This script will loop the master spreadsheet and look for a building name it recognizes. If there's a match, it will open the child sheet and set the notes for each row using the offset provided in the previous step. To be honest, this isn't the most elegant solution, but hey, it works.
Just in case of catastrophe, here's another little utility script you can use to clear all notes from the child sheets. This was particularly helpful when I had my offset calculations off by a row.
This is a manual process - there is no edit or change event you can hook into when a note is added or deleted. So, I wrapped all of this into an onOpen simple trigger to add a custom menu.
There are definitely improvements that can be made. Here are all the files as a gist so you can clone, copy/paste, and hack away at your own sheets.
Do you ever give personal help?
I can try to help here and there. If you have something specific about this method, you can leave it here as a comment so others benefit from a (possible) answer.
I’m trying to do something similar to this but I get the error: You do not have permission to call SpreadsheetApp.openByUrl
I’m reading that this can not be used in a custom function, so not understanding what I am doing differently than what you have done here.
Thanks for any help.
There are a couple possibilities. It won’t work if you’re trying to run it using an
event or if you don’t have edit permissions on the child spreadsheet. The other possibility is that the sheet might not have reauthorized you when you updated the script. To do that, sometimes I’ll write a little function that forces the OAuth window to open again and it’ll pick up the new permissions:Does this work for comments as well? I am having hard time setting up another sheet (we have two and the “master” sheet will have information that does not need to be shown on the 2nd sheet). The 2nd sheet is for clients. I have the IMPORTRANGE function working and only pulling the information I want but the comments are not coming through.
Unfortunately, no. Comments aren’t actually a “part” of the document in the sense that you can get them with IMPORTRANGE. To copy comments, you would need to use some scripting to pull them from one sheet to another.
I hope you still look at this article. I have always been a heavy user of comments in cells. When I used Excel or Open Office this was not a problem. I could copy/paste large portions of text into the comment in one cell, however, with Google sheets this does not seem to work. I can copy text out of the cell comment Ok, but when I try to paste text into the cell comment it does not work. Unfortunately I got used to Comments as a way to streamline my spreadsheets, and by now I have hundreds of spreadsheets created with Excel or Open Office that are full of comments.. Appreciate any ideas you may have.
Many thanks in advance. Rafael.