Task guide
Create a Google Doc from each Sheet row
Keep a person and a project note in a Sheet, then create one short Doc per unfinished 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 placing in a new Google Doc. Run with one operator and do not edit or reorder the rows during execution.
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 CA later run skips rows with a visible document link. A missing link does not prove no document was created.
2 · Review before running
What the script can access and change
Permissions you approve
- Read and update the active Google Sheet.
- Create and edit Google Docs in your Drive.
Effects of one run
- Creates a Google Doc for each named row whose link was empty in the initial read.
- Requests a link write in column C after each document is saved, rather than waiting until the end of the batch. Writing per row records progress so a retry does not repeat document creation; a Sheets-only update should use one batched write instead. Sheets may buffer writes. A created or partially written Doc can remain without a link after a failure; the two services do not share a transaction.
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 safely
Follow these steps in order
Prepare one test row
Use the first row for headers. Add one row below it with a sample name and a short note; leave column C empty.
Add the script
Open Extensions, choose Apps Script, paste the function, and save it.
Create and inspect the Doc
Run createDocsFromSheetRows. Open the link in column C and inspect its text before adding more rows. Wait for each run to finish; after a failure, reconcile unlinked rows in Drive before rerunning.
5 · Confirm
How to tell it worked
Each unfinished row gets a new document link in column C, and running the function again leaves linked rows alone.
If the result is different
Troubleshooting
- Nothing was created.
- Check that the tab is named Projects and that at least one row has a name with an empty column C.
- The same person needs a second document.
- Clear the link cell for that row only when you intentionally want another document.
- The run failed before a document link appeared.
- Stop before rerunning. Search Drive for the row name and project note title, then inspect the document contents and creation time. Restore its link only if the document is complete; repair an incomplete document by hand. If several files match or the outcome is unclear, resolve that ambiguity first. File names are not unique, and overlapping runs 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
Use one row per person, then let the script send only the rows that have not already been marked as sent.
- Task guide Respond to a Google Form submission
Add a small response function, then install a form-submit trigger so each new answer produces a private email summary.
- 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. Reach it with getSheetByName() or getActiveSheet(), then inspect getLastRow() or read cells with getRange().
- 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 bound script, getActiveDocument().getBody() reaches the active tab; in a standalone script, openById(id).getBody() uses 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 run repeatable actions across rows.
- Google app Google Docs
DocumentApp scripts open a Google Doc, reach its body with getBody(), and turn row values into a finished document you can share.