Apps Script w Dokumentach Google umożliwia dostęp do treści z dowolnej karty w dokumencie.
Czym są karty?
Dokumenty Google mają warstwę organizacyjną zwaną kartami. Dokumenty umożliwiają tworzenie w jednym dokumencie co najmniej 1 karty, podobnie jak w Arkuszach. Każda karta ma własny tytuł i identyfikator (dołączony do adresu URL). Karta może też mieć karty podrzędne, czyli karty zagnieżdżone pod inną kartą.
Karty dostępu
Właściwości i treści kart są dostępne za pomocą metody
Document.getTabs()
, która zwraca listę obiektów Tab
. W dalszych sekcjach znajdziesz krótkie omówienie klasy Tab
. Więcej szczegółowych informacji znajdziesz w dokumentacji klasy Tab.
Właściwości karty
Właściwości kart można pobierać za pomocą metod takich jak Tab.getId()
i Tab.getTitle()
.
Zawartość karty
Treść dokumentu na każdej karcie można pobrać za pomocą funkcji Tab.asDocumentTab()
.
W sekcji Zmiany w strukturze klasy dokumentu opisujemy, jak można z niej korzystać.
Hierarchia kart
Karty podrzędne są udostępniane w Google Apps Script za pomocą Tab.getChildTabs()
.
Aby uzyskać dostęp do treści ze wszystkich kart, musisz przejść przez „drzewo” kart podrzędnych.
Załóżmy na przykład, że dokument zawiera hierarchię kart w tej postaci:
Aby uzyskać dostęp do karty 3.1.2, możesz wykonać te czynności:
// Print the ID of Tab 3.1.2. const doc = DocumentApp.getActiveDocument(); const tab = doc.getTabs()[2].getChildTabs()[0].getChildTabs()[1]; console.log(tab.getId());
W dalszej części znajdziesz przykładowe bloki kodu, które pokazują, jak iterować po wszystkich kartach w dokumencie.
Inne sposoby przywracania kart
Karty możesz przywrócić na 2 inne sposoby:
Document.getTab(tabId)
: Zwraca kartę o określonym identyfikatorze.Document.getActiveTab()
: zwraca aktywną kartę użytkownika. Działa tylko w przypadku skryptów powiązanych z dokumentem. Więcej informacji na ten temat znajdziesz w dalszej części tego artykułu.
Zmiany w strukturze klasy dokumentu
W przeszłości dokumenty nie miały koncepcji kart, więc klasa Document udostępniała metody bezpośredniego dostępu do treści tekstowych dokumentu i ich modyfikowania. Do tej kategorii należą te metody:
Document.addBookmark(position)
Document.addFooter()
Document.addHeader()
Document.addNamedRange(name, range)
Document.getBody()
Document.getBookmark(id)
Document.getBookmarks()
Document.getFooter()
Document.getFootnotes()
Document.getHeader()
Document.getNamedRangeById(id)
Document.getNamedRanges()
Document.getNamedRanges(name)
Document.newPosition(element, offset)
Document.newRange()
Ze względu na dodatkową hierarchię strukturalną kart te metody nie reprezentują już semantycznie treści tekstowych ze wszystkich kart w dokumencie. Treść tekstowa będzie teraz reprezentowana w innej warstwie. Wszystkie wymienione wyżej metody tekstowe są dostępne po kliknięciu DocumentTab
.
Te istniejące metody w klasie Document
będą uzyskiwać dostęp do treści lub je modyfikować na aktywnej karcie (w skryptach powiązanych z określonym dokumentem) lub na pierwszej karcie (jeśli aktywna karta nie jest dostępna).
Dostęp do treści tekstowych na określonej karcie
Zamiast korzystać z metod tekstowych z klasy Document
, zalecamy używanie metod dostępnych w klasie DocumentTab
(która jest dostępna za pomocą metody Tab.asDocumentTab()
). Na przykład:
// Print the text from the body of the active tab. const doc = DocumentApp.getActiveDocument(); const documentTab = doc.getActiveTab().asDocumentTab(); const body = documentTab.getBody(); console.log(body.getText());
Zmiany w wyborze użytkowników
Metody zaznaczania tekstu
Klasa Document
udostępnia metody pobierania i ustawiania, które umożliwiają zarządzanie miejscem w tekście, w którym użytkownik dokonuje wyboru w aktywnym dokumencie. Te metody działają w kontekście aktywnej karty użytkownika, który uruchamia skrypt.
Document.getCursor()
: zwraca pozycję kursora użytkownika na aktywnej karcie.Document.getSelection()
: zwraca zakres zaznaczenia użytkownika na aktywnej karcie.Document.setCursor(position)
: ustawia pozycję kursora użytkownika w aktywnym dokumencie. Jeśli pozycja znajduje się na nieaktywnej karcie, aktywna karta użytkownika również zostanie przełączona na kartę powiązaną z tą pozycją.Document.setSelection(range)
: ustawia zakres zaznaczenia użytkownika w aktywnym dokumencie. Jeśli zakres znajduje się na nieaktywnej karcie, aktywna karta użytkownika również zostanie przełączona na kartę powiązaną z tym zakresem.
Metody wyboru kart i przypadki użycia
Wraz z wprowadzeniem kart może być przydatne pobieranie i ustawianie aktywnej karty użytkownika uruchamiającego skrypt. Możesz to zrobić na kilka sposobów:
Document.getActiveTab()
: Zwraca aktywneTab
użytkownika w aktywnym dokumencie.Document.setActiveTab(tabId)
: ustawia wybraną przez użytkownikaTab
w bieżącym dokumencie na kartę o określonym identyfikatorze.
Całościowy „wybór” użytkownika składa się z aktywnej karty oraz bieżącej pozycji kursora lub zakresu zaznaczenia. Istnieją 2 wzorce pracy z aktywnym wyborem: możesz jawnie zmienić aktywną kartę użytkownika na konkretną kartę lub użyć aktywnej karty użytkownika.
Aby wyraźnie zmienić aktywną kartę użytkownika, użyj Document.setActiveTab(tabId)
.
Wywołanie funkcji
Document.setCursor(position)
lub Document.setSelection(range)
z wartością Position
lub Range
na nieaktywnej karcie spowoduje, że ta karta stanie się aktywna.
Jeśli skrypt ma używać aktywnej karty użytkownika bez jej zmiany, nie musisz używać Document.setActiveTab(tabId)
. Metody Document.getCursor()
i Document.getSelection()
będą już działać na aktywnej karcie, na podstawie karty, z której użytkownik uruchamia skrypt.
Pamiętaj, że dokument nie obsługuje wyboru wielu kart ani wielu pozycji lub zakresów na różnych kartach. Dlatego użycie
Document.setActiveTab(tabId)
spowoduje wyczyszczenie poprzedniej pozycji kursora lub zakresu zaznaczenia.
Metody pozycji i zakresu dla konkretnej karty
To właśnie konkretna karta nadaje znaczenie koncepcjom wyboru tekstu Position
i Range
. Innymi słowy, pozycja kursora lub zakres zaznaczenia mają znaczenie tylko wtedy, gdy skrypt zna konkretną kartę, na której znajduje się pozycja lub zakres.
Można to osiągnąć za pomocą metod DocumentTab.newPosition(element, offset)
i DocumentTab.newRange()
, które tworzą obiekt Position lub Range, który jest kierowany na konkretny element DocumentTab
, z którego wywoływana jest metoda. Natomiast
Document.newPosition(element, offset)
i Document.newRange()
utworzą obiekt Position lub Range, który będzie kierowany na aktywną kartę (lub pierwszą kartę, jeśli skrypt nie jest powiązany).
W dalszej części znajdziesz przykładowe bloki kodu, które pokazują, jak pracować z wybranymi elementami.
Typowe sposoby korzystania z kart
Poniższe przykłady kodu opisują różne sposoby interakcji z kartami.
odczytywać zawartość kart ze wszystkich kart w dokumencie,
Istniejący kod, który robił to przed wprowadzeniem funkcji kart, można przenieść, aby obsługiwał karty, przechodząc przez drzewo kart i wywołując metody pobierające z Tab
i DocumentTab
zamiast z Document
. Poniższy przykładowy kod pokazuje, jak wydrukować całą zawartość tekstową ze wszystkich kart w dokumencie. Ten kod przechodzenia między kartami można dostosować do wielu innych zastosowań, w których nie jest istotna rzeczywista struktura kart.
/** Logs all text contents from all tabs in the active document. */ function logAllText() { // Generate a list of all the tabs in the document, including any // nested child tabs. DocumentApp.openById('abc123456') can also // be used instead of DocumentApp.getActiveDocument(). const doc = DocumentApp.getActiveDocument(); const allTabs = getAllTabs(doc); // Log the content from each tab in the document. for (const tab of allTabs) { // Get the DocumentTab from the generic Tab object. const documentTab = tab.asDocumentTab(); // Get the body from the given DocumentTab. const body = documentTab.getBody(); // Get the body text and log it to the console. console.log(body.getText()); } } /** * Returns a flat list of all tabs in the document, in the order * they would appear in the UI (i.e. top-down ordering). Includes * all child tabs. */ function getAllTabs(doc) { const allTabs = []; // Iterate over all tabs and recursively add any child tabs to // generate a flat list of Tabs. for (const tab of doc.getTabs()) { addCurrentAndChildTabs(tab, allTabs); } return allTabs; } /** * Adds the provided tab to the list of all tabs, and recurses * through and adds all child tabs. */ function addCurrentAndChildTabs(tab, allTabs) { allTabs.push(tab); for (const childTab of tab.getChildTabs()) { addCurrentAndChildTabs(childTab, allTabs); } }
Odczytywanie zawartości karty od pierwszej karty w dokumencie
Działa to podobnie do odczytywania wszystkich kart.
/** * Logs all text contents from the first tab in the active * document. */ function logAllText() { // Generate a list of all the tabs in the document, including any // nested child tabs. const doc = DocumentApp.getActiveDocument(); const allTabs = getAllTabs(doc); // Log the content from the first tab in the document. const firstTab = allTabs[0]; // Get the DocumentTab from the generic Tab object. const documentTab = firstTab.asDocumentTab(); // Get the body from the DocumentTab. const body = documentTab.getBody(); // Get the body text and log it to the console. console.log(body.getText()); }
Aktualizowanie zawartości karty na pierwszej karcie
Poniższy fragment kodu pokazuje, jak podczas wprowadzania zmian kierować reklamy na konkretną kartę.
/** Inserts text into the first tab of the active document. */ function insertTextInFirstTab() { // Get the first tab's body. const doc = DocumentApp.getActiveDocument(); const firstTab = doc.getTabs()[0]; const firstDocumentTab = firstTab.asDocumentTab(); const firstTabBody = firstDocumentTab.getBody(); // Append a paragraph and a page break to the first tab's body // section. firstTabBody.appendParagraph("A paragraph."); firstTabBody.appendPageBreak(); }
Aktualizowanie zawartości karty na aktywnej lub wybranej karcie
Poniższy fragment kodu pokazuje, jak podczas wprowadzania zmian kierować reklamy na aktywną kartę.
/** * Inserts text into the active/selected tab of the active * document. */ function insertTextInActiveTab() { // Get the active/selected tab's body. const doc = DocumentApp.getActiveDocument(); const activeTab = doc.getActiveTab(); const activeDocumentTab = activeTab.asDocumentTab(); const activeTabBody = activeDocumentTab.getBody(); // Append a paragraph and a page break to the active tab's body // section. activeTabBody.appendParagraph("A paragraph."); activeTabBody.appendPageBreak(); }
Ustawianie pozycji kursora lub zakresu zaznaczenia na aktywnej karcie
Poniższy fragment kodu pokazuje, jak zaktualizować pozycję kursora lub zakres zaznaczenia na aktywnej karcie użytkownika. Dotyczy to tylko skryptów powiązanych.
/** * Changes the user's selection to select all tables within the tab * with the provided ID. */ function selectAllTables(tabId) { const doc = DocumentApp.getActiveDocument(); const tab = doc.getTab(tabId); const documentTab = tab.asDocumentTab(); // Build a range that encompasses all tables within the specified // tab. const rangeBuilder = documentTab.newRange(); const tables = documentTab.getBody().getTables(); for (let i = 0; i < tables.length; i++) { rangeBuilder.addElement(tables[i]); } // Set the document's selection to the tables within the specified // tab. Note that this actually switches the user's active tab as // well. doc.setSelection(rangeBuilder.build()); }
Ustawianie aktywnej lub wybranej karty
Poniższy fragment kodu pokazuje, jak zmienić aktywną kartę użytkownika. Dotyczy to tylko skryptów powiązanych.
/** * Changes the user's selected tab to the tab immediately following * the currently selected one. Handles child tabs. * *Only changes the selection if there is a tab following the
* currently selected one. */ function selectNextTab() { const doc = DocumentApp.getActiveDocument(); const allTabs = getAllTabs(doc); const activeTab = doc.getActiveTab(); // Find the index of the currently active tab. let activeTabIndex = -1; for (let i = 0; i < allTabs.length; i++) { if (allTabs[i].getId() === activeTab.getId()) { activeTabIndex = i; } } // Update the user's selected tab if there is a valid next tab. const nextTabIndex = activeTabIndex + 1; if (nextTabIndex < allTabs.length) { doc.setActiveTab(allTabs[nextTabIndex].getId()); } }