Apps Script w Dokumentach Google umożliwia dostęp do treści z dowolnej karty w dokumencie.
Co to 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 opisaliśmy, 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.
Załóżmy na przykład, że dokument 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 klas dokumentu
W przeszłości w dokumentach nie było obsługi kart, dlatego klasa dokumentu udostępniała metody bezpośredniego dostępu do tekstu dokumentu i modyfikowania jego zawartości. 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()
Dzięki dodatkowej hierarchii struktury kart te metody nie odzwierciedlają już semantycznej treści tekstowej ze wszystkich kart w dokumencie. Treść tekstowa będzie teraz reprezentowana 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 używanych w metodzie Document
zalecamy używanie metod, które są dostępne w klasie DocumentTab
(dostępne w ramach 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 miejscem w tekście, w którym użytkownik dokonuje wyboru w aktywnym dokumencie. Metody te 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 zaznaczonych komórek użytkownika na karcie aktywnej.Document.setCursor(position)
: ustawia pozycję kursora użytkownika w aktywnym dokumencie. Jeśli Pozycja znajduje się na nieaktywnej karcie, aktywna karta użytkownika jest również przenoszona 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
Dzięki wprowadzeniu kart można pobrać i ustawić aktywną kartę użytkownika, który uruchamia 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” użytkownika to kombinacja aktywnej karty oraz bieżącej pozycji kursora lub zakresu zaznaczenia. 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 zamierzone działanie skryptu ma na celu korzystanie z aktywnej karty użytkownika bez jej zmiany, użycie Document.setActiveTab(tabId)
nie jest konieczne. Metody Document.getCursor()
i Document.getSelection()
będą już działać na aktywnej karcie w zależności od karty, na której użytkownik uruchamia skrypt.
Pamiętaj, że dokument nie obsługuje wielokrotnego wyboru kart ani wielu pozycji lub zakresów na różnych kartach. Dlatego użycie opcji Document.setActiveTab(tabId)
spowoduje wyczyszczenie poprzedniej pozycji kursora lub zakresu zaznaczenia.
Metody pozycji i zakresu na konkretnej karcie
To właśnie ona nadaje znaczenie koncepcjom zaznaczania tekstu na stronach Position
i Range
. Inaczej mówiąc, pozycja kursora lub zakres wyboru mają znaczenie tylko wtedy, gdy skrypt zna konkretną kartę, na której się znajdują.
Jest to możliwe dzięki metodom DocumentTab.newPosition(element, offset)
i DocumentTab.newRange()
, które tworzą pozycję lub zakres ukierunkowany na konkretną wartość DocumentTab
, z której jest wywoływana 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żej znajduje się przykładowy kod opisujący różne sposoby korzystania z kart.
Odczytywanie zawartości wszystkich kart 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. Kod przemierzania kart można dostosować do wielu innych zastosowań, które nie uwzględniają rzeczywistej struktury 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 częściowy kod pokazuje, jak podczas wprowadzania aktualizacji ustawić kierowanie 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 skryptów skompilowanych.
/** * 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()); } }