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ą użytkownikom tworzenie co najmniej 1 karty w pojedynczym dokumencie, podobnie jak w przypadku kart w Arkuszach. Każda karta ma swój tytuł i identyfikator (dołączony do adresu URL). Karta może też mieć karty podrzędne, czyli karty umieszczone w innej karcie.
Dostęp do kart
Właściwości i zawartość karty są dostępne za pomocą funkcji Document.getTabs()
, która zwraca listę Tab
. W kolejnych sekcjach znajdziesz krótkie omówienie klasy Tab
. Więcej szczegółowych informacji znajdziesz też w dokumentacji klasy Tab.
Właściwości karty
Właściwości karty można pobierać za pomocą takich metod jak Tab.getId()
i Tab.getTitle()
.
Zawartość karty
Treści dokumentu na każdej karcie można pobrać za pomocą Tab.asDocumentTab()
.
W sekcji Zmiany w strukturze klasy dokumentu opisano, jak można z niej korzystać.
Hierarchia kart
Karty podrzędne są dostępne w Google Apps Script za pomocą Tab.getChildTabs()
.
Dostęp do treści ze wszystkich kart wymaga przejścia przez „drzewo” kart podrzędnych.
Weź pod uwagę na przykład dokument, który zawiera hierarchię kart w ten sposób:
Aby uzyskać dostęp do karty 3.1.2, wykonaj 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 kolejnych sekcjach znajdziesz przykładowe bloki kodu, które zawierają przykładowy kod do iterowania po wszystkich kartach w dokumencie.
Inne sposoby pobierania kart
Istnieją 2 inne sposoby odzyskiwania kart:
Document.getTab(tabId)
: zwraca kartę o określonym identyfikatorze.Document.getActiveTab()
: zwraca aktywną kartę użytkownika. Działa tylko w przypadku skryptów, które są powiązane z dokumentem. W następnych sekcjach znajdziesz więcej informacji na ten temat.
Zmiany w strukturze klasy dokumentu
W przeszłości dokumenty nie miały pojęcia kart, więc klasa Document udostępniała metody umożliwiające bezpośredni dostęp do treści tekstowych dokumentu i ich modyfikowanie. 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 odzwierciedlają już semantycznie treści tekstowej ze wszystkich kart w dokumencie. Treści tekstowe będą teraz reprezentowane w innej warstwie. Wszystkie wymienione powyżej metody tekstowe są dostępne w sekcji DocumentTab
.
Te istniejące metody klasy Document
będą uzyskiwać dostęp do treści lub je modyfikować na aktywnej karcie (w skryptach powiązanych z konkretnym dokumentem) lub na pierwszej karcie (jeśli aktywna karta jest niedostępna).
Dostęp do treści tekstowych na konkretnej karcie
Zamiast metod tekstowych z klasy Document
zalecamy stosowanie metod dostępnych w klasie DocumentTab
(dostępnej 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 wybieraniu użytkowników
Metody zaznaczania tekstu
Klasa Document
udostępnia metody getter i setter, które umożliwiają zarządzanie tym, gdzie w tekście użytkownik dokonuje wyboru w aktywnym dokumencie. Te metody działają w kontekście aktywnej karty użytkownika uruchamiającego skrypt.
Document.getCursor()
: zwraca pozycję kursora użytkownika na aktywnej karcie.Document.getSelection()
: zwraca zakres zaznaczonych przez użytkownika komórek na karcie aktywnej.Document.setCursor(position)
: ustawia pozycję kursora użytkownika w aktywnym dokumencie. Jeśli pozycja znajduje się na karcie nieaktywnej, aktywna karta użytkownika jest również przełączana na kartę powiązaną z tą pozycją.Document.setSelection(range)
: ustawia zakres zaznaczania użytkownika w aktywnym dokumencie. Jeśli zakres znajduje się na karcie nieaktywnej, aktywna karta użytkownika zostanie również przełączona do karty powiązanej z tym zakresem.
Metody i przypadki użycia wyboru kart
Wprowadzenie kart może być przydatne do pobierania i ustawiania aktywnej karty użytkownika uruchamiającego skrypt. Można to zrobić na kilka sposobów:
Document.getActiveTab()
: zwraca aktywnyTab
użytkownika w aktywnym dokumencie.Document.setActiveTab(tabId)
: ustawia wybrany przez użytkownika elementTab
w bieżącym dokumencie na kartę o określonym identyfikatorze.
„Zakres wyboru” użytkownika to kombinacja aktywnej karty oraz bieżącej pozycji kursora lub zakresu wyboru. Istnieją 2 schematy pracy z aktywnym wyborem: można jawnie zmienić aktywną kartę użytkownika na konkretną kartę lub użyć aktywnej karty użytkownika.
Aby jawnie zmienić aktywną kartę użytkownika, użyj polecenia Document.setActiveTab(tabId)
.
Jeśli wywołasz Document.setCursor(position)
lub Document.setSelection(range)
z Position
lub Range
z nieaktywnej karty, ta karta stanie się aktywna.
Jeśli skrypt ma używać aktywnej karty użytkownika bez jej zmiany, Document.setActiveTab(tabId)
nie jest potrzebny. Metody Document.getCursor()
i Document.getSelection()
będą już działać na aktywnej karcie na podstawie karty, na której użytkownik uruchamia skrypt.
Pamiętaj, że dokument nie obsługuje wielu kart, pozycji ani zakresów na różnych kartach. Dlatego użycie Document.setActiveTab(tabId)
spowoduje usunięcie poprzedniej pozycji kursora lub zakresu zaznaczenia.
Metody pozycji i zakresu na konkretnej karcie
To, co określa znaczenie koncepcji wyboru tekstu Position
i Range
, zależy od konkretnej karty. Inaczej mówiąc, pozycja kursora lub zakres wyboru mają znaczenie tylko wtedy, gdy skrypt zna konkretną kartę, na której się znajdują.
Aby to osiągnąć, użyj metod DocumentTab.newPosition(element, offset)
i DocumentTab.newRange()
, które tworzą pozycję lub zakres kierowany na konkretny element DocumentTab
, z którego wywoływana jest metoda. Natomiast Document.newPosition(element, offset)
i Document.newRange()
zbudują pozycję lub zakres, który będzie kierować na aktywną kartę (lub pierwszą kartę, jeśli skrypt nie jest powiązany).
W kolejnych sekcjach znajdziesz przykładowe bloki kodu, które zawierają przykładowy kod do pracy z zaznaczeniami.
Typowe wzorce korzystania z kart
Poniższe przykłady kodu opisują różne sposoby interakcji z kartami.
odczytywać zawartość kart we wszystkich kartach w dokumencie;
Istniejący kod, który wykonywał tę czynność przed wprowadzeniem funkcji kart, można przenieść na karty, przechodząc przez drzewo kart i wywołując metody gettera z elementów Tab
i DocumentTab
zamiast z elementu Document
. Ten przykładowy kod pokazuje, jak wydrukować cały tekst z każdej karty w dokumencie. Ten kod przeszukiwania kart można dostosować do wielu innych zastosowań, w których nie ma znaczenia 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); } }
Czytaj zawartość karty z pierwszej karty w dokumencie
Jest to podobne do odczytania 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 przykładowy kod pokazuje, jak kierować aktualizacje 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
Ten częściowy przykład kodu pokazuje, jak kierować reklamy na aktywną kartę podczas wprowadzania zmian.
/** * 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
Ten częściowy przykład kodu pokazuje, jak zaktualizować pozycję kursora lub zakres zaznaczenia na aktywnej karcie użytkownika. Jest to istotne tylko w przypadku skompilowanych skryptów.
/** * 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
Ten przykładowy fragment kodu pokazuje, jak zmienić aktywną kartę użytkownika. Jest to istotne tylko w przypadku 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()); } }