apps-script-utils (Deutsch) 2.1.1 Help

Die Apps-Script-Laufzeit

Die Bibliothek ist ein Paket, aber ihre Funktionen laufen nicht alle an denselben Orten. Auf welcher Seite der Linie eine Funktion steht, entscheidet, ob sie sich als Unit testen lässt und ob sie einen Dienstaufruf kostet.

Zwei Arten von Funktion

Laufzeitunabhängige Funktionen sind gewöhnliches JavaScript. Sie nehmen Werte, geben Werte zurück und greifen nie nach einer globalen Variablen. Dazu gehört alles in lang, net, json, html, time und exception, und ebenso die Teile von appsscript, die nur Zeichenketten und einfache Objekte umformen — die A1-Zerleger, die Spaltenbuchstaben-Umrechnungen und die GridRange-Vergleiche.

Dienstgebundene Funktionen greifen selbst nach einem globalen Dienst. Sie funktionieren nur in einem Skript mit den nötigen Berechtigungen und in Node gar nicht. Das ist derzeit die ganze Liste:

Funktion

Greift nach

isAdmin

Session.getActiveUser, AdminDirectory.Users

checkMultipleAccount

Session.getEffectiveUser

getSheetById

SpreadsheetApp.getActiveSpreadsheet, wenn keine Tabelle übergeben wird

getSheetByIndex

SpreadsheetApp.getActiveSpreadsheet, wenn keine Tabelle übergeben wird

highlightHtml

SpreadsheetApp.newTextStyle, SpreadsheetApp.newRichTextValue

convertRichTextToHtml

Utilities.formatString

Alles Übrige in appsscript nimmt das Dienstobjekt als Argument: appendRows schreibt in das Sheet, das Sie ihm geben, und requireSheet betrachtet den übergebenen Wert, statt selbst einen zu holen. Solche Funktionen brauchen ein lebendes Dienstobjekt, um nützlich zu sein, suchen aber keines — genau das macht sie im Test ersetzbar.

An der Grenze bündeln

Jeder Dienstaufruf ist ein Hin und Zurück, und Apps Script rechnet ihn gegen das Zeitlimit. Die Schreibhelfer gibt es deshalb: appendRows macht einen Aufruf, gleich wie viele Zeilen Sie übergeben, während eine Schleife mit appendRow einen pro Zeile macht.

// Ein Dienstaufruf. appendRows(sheet, rows); // Ein Dienstaufruf je Zeile; nur für ein einzelnes Anhängen sinnvoll. for (const row of rows) { appendRow(sheet, row); }

Dieselbe Überlegung gilt für die Prüfung. Prüfen Sie die Form der Daten, bevor sie den Dienst erreichen, nicht danach:

import { IllegalArgumentException, appendRows, isConsistent2DArray } from "apps-script-utils"; if (!isConsistent2DArray(rows)) { throw new IllegalArgumentException("every row must have the same number of columns"); } appendRows(sheet, rows);

Range.setValues() lehnt eine ungleichmäßige Matrix ab, doch der Fehlschlag kommt vom Dienst, ohne zu sagen, welche Zeile falsch war. Vorher zu prüfen macht daraus einen Fehler, den Sie steuern.

Kontingente

Apps Script setzt Kontingente je Skript und je Konto durch — Ausführungszeit, Aufrufe jedes Dienstes, Trigger, URL-Abrufe und mehr. Die Bibliothek hebt sie weder an noch zählt sie mit; sie verringert nur die Zahl der Aufrufe. Zwei Folgerungen, mit denen man planen sollte:

  • Eine laufzeitunabhängige Funktion kostet nichts außer Rechenzeit. Verschieben Sie Prüfung und Umformung, wo immer es geht, auf diese Seite der Linie.

  • Eine dienstgebundene Funktion kann aus Gründen scheitern, die nichts mit ihren Argumenten zu tun haben. Wirft isAdmin eine AdminDirectoryException, heißt das, dass der erweiterte Admin-SDK-Dienst im Projekt nicht aktiviert ist — nicht, dass der Nutzer kein Administrator wäre.

Die geltenden Grenzen stehen in Quotas for Google Services.

Testen

Die Testsuite läuft mit Vitest in Node, wo keine der Apps-Script-Globalen existiert. Genau deshalb zählt die Trennung:

  • Laufzeitunabhängige Funktionen werden direkt als Unit getestet. Sie machen den Großteil von test/ aus, importiert über den @/-Alias.

  • Dienstgebundene nicht. Ein Aufruf in Node wirft einen ReferenceError auf SpreadsheetApp oder die jeweilige Globale, sie werden daher von Hand gegen ein echtes Skriptprojekt geprüft. Die Funktionen, die bloß ein Sheet entgegennehmen, liegen dazwischen: sie lassen sich mit einem Stellvertreterobjekt in der Form der Dienstklasse ausführen.

npm test # die Suite einmal laufen lassen npm run dev # Beobachtungsmodus

Wenn Sie eine Funktion hinzufügen, ist dies die erste Entwurfsfrage: kann sie das Dienstobjekt als Parameter nehmen, statt eines zu holen? Wenn ja, wird sie testbar, und der Aufrufer behält die Kontrolle darüber, wie viele Dienstaufrufe geschehen.

Für beide Seiten schreiben

Die Bibliothek zielt auf die V8-Laufzeit. Zwei Gewohnheiten halten Code auf beiden Seiten der Linie lauffähig:

  • Nehmen Sie Dienstobjekte als Argumente. appendRows(sheet, rows) funktioniert, woher das Sheet auch kommt; eine Funktion, die intern SpreadsheetApp.getActiveSpreadsheet() aufruft, funktioniert nur in einem gebundenen Skript.

  • Trennen Sie das Zerlegen vom Holen. parseA1Notation ist reine Zeichenkettenarbeit, läuft in Node und ist deshalb als Unit getestet; getSheetById ist dieselbe Suche, nur gegen die aktive Tabelle ausgedrückt, und ist es nicht. Die Tabelle ausdrücklich zu übergeben — getSheetById(id, spreadsheet) — holt sie zurück über die Linie.

23 September 2026

Diese Dokumentation wurde mit KI (Claude) aus dem Quellcode der Bibliothek erzeugt.