43 posts tagged with “google-apps-script”

Get the Active Row as an Object

Menu actions and sidebar handoffs usually care about the row you're on, not the whole grid. getActiveRowAsObject reads the header row plus…

Copy a Template Sheet Tab

Copying last month's client tab inherits junk formulas, stale sample rows, and mystery filters. Keep a clean template tab, then…

Email Yourself an Error Alert

Nightly jobs that "mostly work" fail quietly until a teammate notices bad data. emailErrorAlert sends you a plain Gmail with the error…

Confirm a Dangerous Action (Yes/No)

Custom menus that Clear, Re-import, or Archive should not fire on a misclick. This thin wrapper around SpreadsheetApp.getUi().alert returns…

Build a Header → Column Index Map

Hard-coding column letters (C, D) breaks the moment a client inserts a column. Build a { headerName: columnIndex } map once from row 1, then…

Move a Row to Another Sheet

"Delete" is usually the wrong word. Archive the row to another tab (or workbook tab), then remove it from the working sheet — so audits…

Ensure Header Row Exists

Importers and upserts assume row 1 is headers. Empty tabs and "someone deleted column C" both break that. This helper creates the header row…

withScriptLock Helper

Standalone projects and library code don't get a Document Lock. When the critical section is the script project itself — watermark updates…

Send an HTML Email with GmailApp

GmailApp.sendEmail can send HTML — you just need htmlBody (and a plain-text fallback for picky clients). This helper wraps the options bag…

Upsert a Row by Key Column

Find a row by a key column (email, order ID, SKU) and update it — or append if it's new. Header-aware, so you pass a plain object instead of…

Get the Last Data Row in a Column

getLastRow() happily counts formatting, old formulas, and phantom blanks. When you need the real last cell with data in a column — for…

withUserLock Helper

Document locks serialize everyone on a spreadsheet. User locks only serialize the same user's overlapping runs — handy for personal quotas…

Convert Sheet Values to CSV Text

Need a CSV string for email attachments, Drive dumps, or API uploads? Escape commas/quotes/newlines correctly, then join rows. These two…

HtmlService Template Include Helper

Splitting HTML dialogs into Dialog.html + Styles.html + Client.js.html keeps IFRAME UIs maintainable. The classic pattern is a server-side…

Show a Sheet Toast for Progress

Long-running menu actions feel broken without feedback. SpreadsheetApp.toast pops a small notice in the lower-right — perfect for "started…

Delete Triggers by Handler Name

Re-running an install function without cleanup creates duplicate triggers — and suddenly your sync fires five times. This deletes every…

Create a Daily Time-Driven Trigger

Time-driven triggers are how most overnight syncs stay hands-off. This helper creates a once-per-day trigger for a named function around the…

Cache JSON with a TTL

Hitting the same API or expensive sheet scan every trigger run burns quota. CacheService gives you a short-lived store (max ~6 hours…

Append an Object as a Sheet Row

When your data is already a plain object (API payload, form values), aligning it to row-1 headers beats hand-building arrays. Missing keys…

Clear a Sheet but Keep Header Row

Wiping a sheet before a fresh import is common — but you usually want the header row to survive. This clears content below the header(s…

Get or Create a Sheet by Name

Need a tab that might not exist yet? This helper returns the sheet if it's there, or inserts it and returns the new one — no null checks…

rowsToObjects and objectsToRows

Sheet data is easiest as a 2D array. Business logic is easier as objects keyed by header. These two helpers convert back and forth without…

withDocumentLock Helper

When a time-driven trigger and a manual run can overlap — or two editors kick the same sync — you need a lock. This helper wraps LockService…

Batch writes without timeouts

When a script dies halfway through writing thousands of rows, you don't need a fancier API — you need a boring pattern: lock, chunk…

For Loop Using Dynamic Set

What Does This Code Snippet Do? Unlike the incremental For Loop where you specify the number of iterations you want the loop to execute…

For Loop Using Increments

What Does This Code Snippet Do? This code snippet is a basic For Loop that takes in a set iteration length and also lets you specify where…