Task guide
Email yourself a weekly sheet summary
Run the setup function once. Each Friday the script reads the Orders tab, counts the nonblank rows, totals column C, counts the rows that are not Done, and emails the account that installed it.
1 · Prepare
Put these pieces in place
- Open the script from the spreadsheet with Extensions, then Apps Script.
- Create a tab named Orders with headers in row 1 and the first data row in row 2.
- Put a number in column C for the amount and a status word in column D, such as Done.
- Use an account that can send email through Gmail.
Change these values
- Sheet name
OrdersThe tab the summary reads. It must already exist.
- Send day
ScriptApp.WeekDay.FRIDAYThe weekday the trigger runs. Other values look like ScriptApp.WeekDay.MONDAY.
- Send hour
16The hour the trigger runs, in the project time zone. 16 means some time between 4 PM and 5 PM.
- Finished status
DoneRows whose column D does not match this word exactly are counted as still open.
2 · Review before running
What the script can access and change
Permissions you approve
- Read the Orders tab in the active spreadsheet.
- Send email from your Google account to the account that installed the trigger.
- Create and view triggers in this Apps Script project.
Effects of one run
- Sends one short plain text email each week to the account that installed the trigger.
- Reads the sheet only. No cell is written, moved, or deleted.
- Completely blank rows in columns A through D are ignored, while rows with a zero amount are still counted.
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.
const SHEET_NAME = 'Orders'; // The tab the summary reads. It must already exist.
const SEND_DAY = ScriptApp.WeekDay.FRIDAY; // The weekday the trigger runs. Other values look like ScriptApp.WeekDay.MONDAY.
const SEND_HOUR = 16; // The hour the trigger runs, in the project time zone. 16 means some time between 4 PM and 5 PM.
const FINISHED_STATUS = 'Done'; // Rows whose column D does not match this word exactly are counted as still open.
function createWeeklySummaryTrigger() {
const alreadyInstalled = ScriptApp.getProjectTriggers().some((trigger) => {
return trigger.getHandlerFunction() === 'sendWeeklyOrderSummary';
});
if (alreadyInstalled) return;
ScriptApp.newTrigger('sendWeeklyOrderSummary')
.timeBased()
.onWeekDay(SEND_DAY)
.atHour(SEND_HOUR)
.create();
}
function sendWeeklyOrderSummary() {
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet = spreadsheet.getSheetByName(SHEET_NAME);
if (!sheet) throw new Error('Add a Sheet tab named ' + SHEET_NAME + ' before running this function.');
let rowCount = 0;
let total = 0;
let notDone = 0;
const lastRow = sheet.getLastRow();
if (lastRow >= 2) {
const rows = sheet.getRange(2, 1, lastRow - 1, 4).getValues();
const dataRows = rows.filter((row) => row.some((cell) => cell !== ''));
rowCount = dataRows.length;
dataRows.forEach((row) => {
const amount = Number(row[2]);
if (!isNaN(amount)) total = total + amount;
if (String(row[3]).trim() !== FINISHED_STATUS) notDone = notDone + 1;
});
}
const reportDate = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'yyyy-MM-dd');
const lines = [
'Orders summary for ' + reportDate,
'Rows with data: ' + rowCount,
'Total amount: ' + total,
'Not marked ' + FINISHED_STATUS + ': ' + notDone,
spreadsheet.getUrl()
];
GmailApp.sendEmail(Session.getEffectiveUser().getEmail(), 'Weekly orders summary', lines.join('\n'));
} 4 · Run safely
Follow these steps in order
Set up the Orders tab
Row 1 holds the headers and the data starts in row 2. Column C holds the amount as a number, and column D holds the status word.
Run the summary by hand first
Paste both functions and save. Choose sendWeeklyOrderSummary and press Run. Approve the access when Google asks, then compare the numbers in the email with the sheet.
Install the weekly trigger
When the numbers look right, choose createWeeklySummaryTrigger and run it once. It skips the work when a trigger for sendWeeklyOrderSummary already exists, so running it twice does not add a second trigger.
Check the trigger list
Open Triggers in the left sidebar. sendWeeklyOrderSummary should be listed as a week timer for Friday. The trigger runs as the account that created it, and that is the account the summary is sent to.
5 · Confirm
How to tell it worked
An email with the subject Weekly orders summary lists the report date, how many data rows the tab has, the total of column C, how many rows are not Done, and a link to the spreadsheet.
If the result is different
Troubleshooting
- The script says Add a Sheet tab named Orders before running this function.
- Rename the tab to Orders, or change the name in the code and in the editable values. The name has to match exactly, including capital letters.
- The total is 0 even though column C has values.
- The amounts have to be numbers. A cell holding text such as 1,200 USD is skipped. Remove the extra text and let the sheet format the number instead.
- Every row is counted as not Done.
- The check compares column D with the word Done. Spaces around the word are ignored, but done and Done are different, so use the same spelling in every row.
- No email arrives on Friday.
- Open Executions in the left sidebar to see whether the trigger ran and what it reported. The hour follows the project time zone, which you can check under Project Settings.
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 Run an Apps Script function every day
Run the setup function once, then Apps Script calls the reminder function each day around your chosen hour.
- Task guide Back up a spreadsheet to Drive every week
Run the setup function once. Every Monday morning the script copies the spreadsheet into a Drive folder and puts the date in the copy name. The original is never touched.
- 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.
- Object reference Trigger builder
ScriptApp.newTrigger(functionName) returns a TriggerBuilder that configures a timeBased(), forSpreadsheet(), or forForm() trigger before create() saves it.
- 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().
- Basics Google Apps Script triggers explained
A Google Apps Script trigger runs a function when an event happens, without pressing Run. Simple triggers like onEdit and onOpen need no setup, while installable triggers run on a schedule or form submit using the OAuth scopes approved by their owner.
- 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 Gmail
GmailApp scripts can send messages, search threads, apply labels, and read attachments after you approve Gmail access for the project.
- Google app Triggers
A trigger is a saved schedule or event rule in ScriptApp that runs your function on time, on edit, or on form submit.