Task guide
Create a Google Doc from each Sheet row
Create one short Google Doc for each row on a Projects tab that has no document link yet. The script writes the link to the new Doc back into the row.
1 · Prepare
Put these pieces in place
- Create a Sheet tab named Projects.
- Put a person or project name in column A, a note in column B, and leave column C for the document link.
- Use short notes that you are comfortable putting in a new Google Doc. Only one person should run the script at a time. Wait for each run to finish, and do not edit or sort the rows while it runs.
Change these values
- Sheet tab name
ProjectsThis must match the tab holding the source rows.
- Document title ending
project noteThis wording is added after the name from column A.
- Link column
Column CThe script writes the link to the new Doc here, and a later run skips rows that show a link. If a run fails, a Doc can exist even though column C is empty.
2 · Review before running
What the script can access and change
Permissions you approve
- See, edit, create, and delete all your Google Sheets spreadsheets. The code only reads the Projects tab and writes links into column C of this spreadsheet.
- See, edit, create, and delete all your Google Docs documents. The code only creates new Docs and writes the note into them.
Effects of one run
- Creates a Google Doc in your Drive for each row that has a name in column A and an empty column C when the run starts.
- Writes the link to column C right after each Doc is saved, so a later run skips that row. The script writes one row at a time, instead of all rows at the end, because each Doc already exists in Drive as soon as it is created. If the run stops between creating a Doc and writing its link, or before Sheets saves the write, the Doc exists, possibly with only part of its text, but column C stays empty.
- Does not change the Projects tab except for column C, and never edits or deletes an existing Doc.
3 · Copy
Paste this into the Apps Script editor
Create or open a script file, replace the example values marked above, then save the project.
function createDocsFromSheetRows() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Projects');
if (!sheet) throw new Error('Add a Sheet tab named Projects before running this function.');
const firstDataRow = 2;
const lastRow = sheet.getLastRow();
if (lastRow < firstDataRow) return;
const rows = sheet.getRange(firstDataRow, 1, lastRow - firstDataRow + 1, 3).getValues();
rows.forEach((row, index) => {
const [name, note, documentUrl] = row;
if (!name || documentUrl) return;
const document = DocumentApp.create(String(name) + ' project note');
document.getBody().appendParagraph('Project note for ' + name);
document.getBody().appendParagraph(String(note || 'No note was entered.'));
document.saveAndClose();
sheet.getRange(firstDataRow + index, 3).setValue(document.getUrl());
});
} 4 · Run
Follow these steps in order
Prepare one test row
On the Projects tab, put headers in row 1. In row 2, add a sample name in column A and a short note in column B. Leave column C empty.
Add the script
Choose Extensions, then Apps Script. Paste the function over the starter code and save.
Run it and open the new Doc
Choose createDocsFromSheetRows in the function dropdown above the code, then click Run. Approve access when Google asks. A link appears in C2. Open it and read the text before you add more rows.
Add the remaining rows
When the test Doc looks right, fill in the other rows and run the function again. Rows that already show a link in column C are left alone. If a run fails, search Drive for the Docs it made and paste each link into its row before you run again.
5 · Confirm
How to tell it worked
Each row that had an empty column C now shows a link, and the Doc behind it is titled with the name from column A followed by project note. Running the function again changes nothing.
If the result is different
Troubleshooting
- The run finishes but no link appears.
- Check that the tab is named Projects, that the name is in column A, and that at least one row has a name and an empty column C.
- The run stops with "Add a Sheet tab named Projects before running this function."
- Rename your tab to Projects, or change the tab name in the code to the name of your tab.
- The same person needs a second Doc.
- Clear the link in column C for that row, then run the function again. The first Doc stays in Drive.
- The run failed and a row has no link.
- Do not run the script again yet. Search Drive for the name from the row followed by project note. Open each match and check its text and creation time. Paste the link into column C only if the Doc is complete. Finish an incomplete Doc by hand. If several files match, or you cannot tell whether the run finished a Doc, decide what to keep before you run again. Two files can have the same name, and two runs at the same time can create duplicates.
Technical details
Names used in this script
Open these details when you want to adapt the example or look up an exact service or method name.
Show Apps Script symbols and service pages
Apps Script symbols
Service pages
Keep going
Related tasks, basics, and apps
- Task guide Send an email for each row in a Google Sheet
Send one email to each person listed on a Customers tab. The script marks each row Sent as it goes, so a later run sends only to rows that are not marked yet.
- Task guide Respond to a Google Form submission
Get an email every time someone submits your Google Form, listing each question and its answer. The email goes only to you, the owner of the script.
- Object reference Spreadsheet
A Spreadsheet is the whole Google Sheets file. Use SpreadsheetApp.getActiveSpreadsheet() or openById() to get it, then call getSheetByName() or getActiveSheet().
- Object reference Sheet
A Sheet is one tab inside a Google spreadsheet. Get it with getSheetByName() or getActiveSheet(). Use getLastRow() to find the last row with content, or getRange() to select cells to read.
- Object reference Range
A Range represents one cell such as A2 or a rectangular block of rows and columns in a Sheet. Use getValue() for one cell and getValues() or setValues() for a 2D array of rows.
- Object reference Document
A DocumentApp.Document is the Google Doc file itself. In a script opened from a Doc, getActiveDocument().getBody() returns the active tab. In a standalone script, openById(id).getBody() returns the first tab.
- Google app Google Sheets
SpreadsheetApp lets a Google Sheets script read a Sheet or Range, add a custom menu or formula, and act on each row, such as sending one email per row.
- Google app Google Docs
DocumentApp scripts open a Google Doc, reach its body with getBody(), and fill a document with values from Sheet rows.