Làm việc với tab

Apps Script dành cho Google Tài liệu cho phép bạn truy cập vào nội dung từ bất kỳ trong tài liệu.

Thẻ là gì?

Google Tài liệu có một lớp tổ chức được gọi là thẻ. Tài liệu cho phép người dùng tạo một hoặc nhiều thẻ trong một tài liệu, tương tự như cách hôm nay có thẻ trong Trang tính. Mỗi thẻ có tiêu đề và một mã riêng (được thêm vào) trong URL). Một thẻ cũng có thể có thẻ con, chính là các thẻ được lồng vào nhau bên dưới một thẻ khác.

Chúng tôi hiện đã hỗ trợ API cho thẻ con nhưng sắp ra mắt tính năng hỗ trợ giao diện người dùng. Bạn có thể xử lý các thẻ con trong mã của mình ngay hôm nay để khi tính năng hỗ trợ giao diện người dùng bắt đầu hoạt động bạn sẽ không phải cập nhật mã nữa.

Truy cập vào các thẻ

Bạn có thể truy cập vào thuộc tính thẻ và nội dung bằng Document.getTabs()! Hàm này sẽ trả về danh sách các Tab. Các phần sau sẽ cung cấp tổng quan ngắn gọn về lớp Tab; Tài liệu về lớp thẻ còn cung cấp thông tin chi tiết hơn.

Thuộc tính thẻ

Bạn có thể truy xuất thuộc tính thẻ bằng các phương thức như Tab.getId()Tab.getTitle().

Nội dung thẻ

Bạn có thể truy xuất nội dung tài liệu trong mỗi thẻ bằng cách sử dụng Tab.asDocumentTab(). Thay đổi đối với cấu trúc lớp tài liệu mô tả cách sử dụng hàm này.

Hệ phân cấp thẻ

Các thẻ con hiển thị trong Google Apps Script thông qua Tab.getChildTabs(). Để truy cập nội dung từ tất cả các thẻ yêu cầu phải truyền qua "cây" trong số các thẻ con. Ví dụ: hãy xem xét một tài liệu có chứa hệ phân cấp thẻ như sau:

Giao diện người dùng của danh sách thẻ chứa 3 thẻ cấp cao nhất, một số thẻ trong số đó có các thẻ con

Để truy cập Tab 3.1.2, bạn có thể làm như sau:

// 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());

Hãy xem các khối mã mẫu trong các phần sau. Các khối này cung cấp mã mẫu cho lặp lại trên tất cả các thẻ trong một tài liệu.

Các cách khác để truy xuất thẻ

Có hai cách khác để truy xuất thẻ:

  • Document.getTab(tabId): Trả về thẻ có mã nhận dạng đã chỉ định.
  • Document.getActiveTab(): Trả về Thẻ đang hoạt động của người dùng. Chỉ hoạt động ở các tập lệnh được ràng buộc với một tài liệu. Chiến lược phát hành đĩa đơn các phần sau sẽ mô tả điều này chi tiết hơn.

Thay đổi đối với cấu trúc Lớp tài liệu

Trước đây, tài liệu không có khái niệm về thẻ, do đó, Lớp tài liệu đã hiển thị các phương thức để truy cập trực tiếp và chỉnh sửa nội dung văn bản của tài liệu. Các phương thức sau đây cũng thuộc danh mục này:

Với hệ phân cấp cấu trúc bổ sung gồm các thẻ, các phương thức này không còn biểu thị nội dung văn bản từ tất cả các thẻ trong tài liệu theo đúng ngữ nghĩa. Văn bản nội dung giờ đây sẽ được trình bày trong một lớp khác; tất cả những điều trên có thể truy cập phương thức văn bản thông qua DocumentTab.

Các phương thức hiện có này trên lớp Document sẽ truy cập hoặc sửa đổi nội dung từ tab hoạt động (trong tập lệnh ràng buộc với một tài liệu cụ thể) hoặc thẻ đầu tiên (nếu không có thẻ đang hoạt động).

Truy cập vào nội dung văn bản trong một Thẻ cụ thể

Thay vì sử dụng các phương thức văn bản trong Document, bạn nên sử dụng các phương thức có sẵn trong lớp DocumentTab (tức là có sẵn thông qua Tab.asDocumentTab() ). Ví dụ:

// 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());

Các thay đổi đối với lựa chọn của người dùng

Phương thức chọn văn bản

Lớp Document cung cấp phương thức getter và setter để quản lý vị trí trong văn bản người dùng đang chọn, trong tài liệu đang hoạt động. Các phương thức này hoạt động trong ngữ cảnh của thẻ đang hoạt động của người dùng đang chạy tập lệnh.

  • Document.getCursor(): Trả về vị trí con trỏ của người dùng trong thẻ đang hoạt động.
  • Document.getSelection(): Trả về dải ô lựa chọn của người dùng trong thẻ đang hoạt động.
  • Document.setCursor(position): Đặt vị trí con trỏ của người dùng trong tài liệu đang hoạt động. Nếu Vị trí ở trong không hoạt động, thì thẻ đang hoạt động của người dùng cũng được chuyển sang thẻ được liên kết với Vị trí đó.
  • Document.setSelection(range): Đặt phạm vi lựa chọn của người dùng trong tài liệu đang hoạt động. Nếu Dải ô ở trong một không hoạt động, thì thẻ đang hoạt động của người dùng cũng được chuyển sang thẻ được liên kết bằng Dải ô đó.

Các trường hợp sử dụng và phương pháp chọn thẻ

Với sự ra mắt của thẻ, có thể bạn sẽ thấy hữu ích khi tải và đặt thẻ đang hoạt động cho người dùng chạy tập lệnh. Bạn có thể thực hiện việc này bằng các phương pháp sau:

  • Document.getActiveTab(): Trả về Tab đang hoạt động của người dùng trong tài liệu đang hoạt động.
  • Document.setActiveTab(tabId): Đặt Tab mà người dùng đã chọn trong tài liệu hiện tại thành thẻ có mã nhận dạng được chỉ định.

"Lựa chọn" toàn diện của người dùng được tạo thành từ sự kết hợp giữa thẻ đang hoạt động cùng với vị trí con trỏ hiện tại hoặc dải ô lựa chọn. Hai để làm việc với lựa chọn đang hoạt động là sửa đổi rõ ràng thẻ đang hoạt động của người dùng sang một thẻ cụ thể hoặc sử dụng thẻ đang hoạt động của người dùng.

Bạn có thể thay đổi rõ ràng thẻ đang hoạt động của người dùng bằng cách sử dụng Document.setActiveTab(tabId). Ngoài ra, việc gọi Document.setCursor(position) hoặc Document.setSelection(range) với Position hoặc Range từ một thẻ không hoạt động sẽ làm cho thẻ đó đang hoạt động.

Nếu hành vi dự định của tập lệnh là sử dụng thẻ đang hoạt động của người dùng mà không cần thay đổi, sau đó Document.setActiveTab(tabId) là không cần thiết. Chiến lược phát hành đĩa đơn Document.getCursor()Document.getSelection() sẽ hoạt động trên thẻ đang hoạt động, dựa trên thẻ mà người dùng đang chạy tập lệnh từ.

Xin lưu ý rằng một tài liệu không hỗ trợ việc chọn nhiều thẻ hoặc chọn nhiều thẻ vị trí hoặc dải ô trên các tab khác nhau. Do đó, việc sử dụng Document.setActiveTab(tabId) sẽ xóa vị trí con trỏ hoặc dải lựa chọn trước đó.

Phương pháp vị trí và dải ô cho một Thẻ cụ thể

Thẻ cụ thể xác định ý nghĩa cho các khái niệm lựa chọn văn bản PositionRange. Nói cách khác, vị trí con trỏ hoặc dải ô lựa chọn chỉ có ý nghĩa nếu tập lệnh biết thẻ cụ thể mà vị trí hoặc nằm trong phạm vi.

Điều này đạt được bằng cách sử dụng DocumentTab.newPosition(element, offset)DocumentTab.newRange() mà tạo ra Vị trí hoặc Dải ô nhắm mục tiêu cụ thể DocumentTab nơi phương thức được gọi. Ngược lại, Document.newPosition(element, offset)Document.newRange() sẽ tạo Vị trí hoặc Dải ô nhắm mục tiêu tab hoạt động (hoặc , nếu tập lệnh không bị ràng buộc).

Hãy xem các khối mã mẫu trong các phần sau. Các khối này cung cấp mã mẫu cho làm việc với các lựa chọn.

Dạng sử dụng phổ biến cho thẻ

Các mã mẫu sau đây mô tả nhiều cách tương tác với thẻ.

Đọc nội dung thẻ từ tất cả các thẻ trong tài liệu

Mã hiện có đã thực hiện việc này trước khi có thể di chuyển tính năng thẻ để hỗ trợ các thẻ bằng cách truyền tải cây thẻ và gọi các phương thức getter qua TabDocumentTab thay vì Document. Mã mẫu một phần sau đây cho biết cách để in tất cả nội dung văn bản từ mọi thẻ trong tài liệu. Thẻ này mã truyền tải này có thể được điều chỉnh cho nhiều trường hợp sử dụng khác không quan tâm đến cấu trúc thực tế của các thẻ.

/** 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);
  }
}

Đọc nội dung thẻ từ thẻ đầu tiên trong tài liệu

Thao tác này tương tự như việc đọc tất cả các thẻ.

/** 
 * 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());
}

Cập nhật nội dung thẻ trong thẻ đầu tiên

Mã mẫu một phần sau đây cho biết cách nhắm mục tiêu một thẻ cụ thể khi tạo bản cập nhật.

/** 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();
}

Cập nhật nội dung thẻ trong thẻ đang hoạt động hoặc thẻ đã chọn

Mã mẫu một phần sau đây cho biết cách nhắm mục tiêu thẻ đang hoạt động khi thực hiện bản cập nhật.

/**
 * 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();
}

Đặt vị trí con trỏ hoặc dải ô lựa chọn trong thẻ đang hoạt động

Mã mẫu một phần sau đây cho biết cách cập nhật vị trí con trỏ hoặc trong thẻ hoạt động của người dùng. Điều này chỉ phù hợp trong giới hạn các tập lệnh.

/**
 * 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());
}

Đặt thẻ đang hoạt động hoặc đã chọn

Mã mẫu một phần sau đây cho biết cách thay đổi thẻ đang hoạt động của người dùng. Điều này chỉ áp dụng trong các tập lệnh ràng buộc.

/**
 * 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()); } }