google-apps-script - 调用 saveAndClose 后如何重新打开事件文档?

标签 google-apps-script google-docs

我想知道如何在调用 saveAndClose 后重新打开事件文档。

我有一个 Google 文档插件 ( Magic Rainbow Unicorns ),它可以将每个选定字符的字体颜色更改为不同的彩虹颜色。如果文档真的很长(例如 100 页),那么我会看到以下错误:

ScriptError: Too many changes applied before saving document. Please save changes in smaller batches using Document.saveAndClose(), then reopen the document with Document.openById().

正如另一个建议 SO answer ,我有一个计数器,并在 50000 次更改后进行刷新。

      // save & flush changes
      if (rainbowIndex%50000 == 0) {
        DocumentApp.getActiveDocument().saveAndClose();
        // reopen the doc and refresh the selection
        selection = DocumentApp.getActiveDocument().getSelection();
        elements = selection.getRangeElements();
      }

但是此代码不起作用,因为每当我尝试修改元素时,我都会看到错误文档已关闭,其内容无法更新。

我无法按照错误消息的建议使用 DocumentApp.openById,因为我的加载项仅具有当前文档 (@OnlyCurrentDoc) 的权限。

所以我想知道的是:是否可以在关闭事件文档后重新打开它,因为我不想更改附加组件的权限?如果可以的话我应该调用哪个方法?

最佳答案

感谢 filipeglfw 指出了一个对他有用的代码片段,我在代码中发现了一个错误。我刷新了事件文档、选区和选区中的元素,但没有刷新我当前正在使用的元素。

下面显示了一个工作代码片段:

/**
 * @OnlyCurrentDoc
 *
 * The above comment directs Apps Script to limit the scope of file
 * access for this add-on. It specifies that this add-on will only
 * attempt to read or modify the files in which the add-on is used,
 * and not all of the user's files. The authorization request message
 * presented to users will reflect this limited scope.
 */

function test() {
  var document = DocumentApp.getActiveDocument();
  var selection = document.getSelection();
  if (selection) {
    var elements = selection.getRangeElements();
    // go through each selected item and change the font colour
    var rainbowIndex = 0;
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i].getElement();
      var elementText, startIndex, endIndex;
      if (elements[i].isPartial()) {
        // they selected only part of a paragraph
        elementText = element.asText();
        startIndex = elements[i].getStartOffset();
        endIndex = elements[i].getEndOffsetInclusive() + 1;
      } else {
        // they selected whole paragraph(s)
        elementText = element.editAsText();
        startIndex = 0;
        endIndex = selectedText.length;
      }
      for (var j=startIndex; j<endIndex; j++) {
        elementText.setForegroundColor(j, j, "#CCCCCC");
        rainbowIndex++;
        // save & flush changes
        if (rainbowIndex%5 == 0) {
          document.saveAndClose();
          // reopen the doc and refresh the selection
          var document = DocumentApp.getActiveDocument();
          selection = document.getSelection();
          elements = selection.getRangeElements();
          element = elements[i].getElement();
          elementText = element.asText();
        }
      }
    }
  } else {
    // there was no selection
    throw 'Please select some text.';
  }
}

请注意,我使用较低的数字 (5) 作为刷新计数器,但我相信它应该约为 50000。

关于google-apps-script - 调用 saveAndClose 后如何重新打开事件文档?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50875601/

相关文章:

javascript - 自动回复电子邮件 Google 联系表单

google-sheets - 如何基于 Google 电子表格生成可打印的报告

google-docs - 是否自动检测到 Google 数据服务器上的数据损坏?

google-apps-script - 在谷歌应用脚​​本中注入(inject)外部 javascript 文件(谷歌文档)

javascript - 尝试使用需要身份验证的 API 使用 Google 脚本从 TDAmeritrade 提取股票报价信息

javascript - Google Apps 脚本 : Calendar . getEvents 导入错误时区的事件

google-docs - Google Docs API - 模拟用户文件下载

javascript - 删除 Google 文档中的空行

google-apps-script - 使用google app script ui service时修改html Meta

javascript - 循环行,检查两个单元格的值是否相等,然后更改单元格值