获取对象 SpreadsheetApp.Range 上的方法或属性 setRichTextValues 时出现意外错误

2024-03-14

如何处理 RichTextValues() 中的空值

  • 我已经研究这段代码几天了。我开始只是在活动工作表上构建每月日历,这不可避免地导致我希望将我的事件放置在它们上,这最终导致我想要添加富文本以更好地处理较小字体大小的附加文本的格式。

但是,最近我开始收到此错误:

Unexpected error while getting the method or property setRichTextValues on object SpreadsheetApp.Range

  • 这是整个代码:

代码.gs:

function monthlyCalendarWithEvents(obj) {
  var m = obj.m || new Date().getMonth();
  var wsd = obj.wsd || 1;//defaults to Monday
  const calids = obj.calids || CalendarApp.getAllOwnedCalendars().map(c => c.getId());
  const cals = calids.map(id => CalendarApp.getCalendarById(id));
  const td = new Date();
  const [cy, cm, cd] = [td.getFullYear(), td.getMonth(), td.getDate()];
  const dA = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
  const oA = [...Array.from(Array(7).keys(), idx => dA[(idx + wsd) % 7])]
  let dObj = {};
  let midx = {};
  let rObj = { cA: null, roff: null, coff: null };
  oA.forEach(function (e, i) { dObj[e] = i; });
  const mA = [...Array.from(new Array(12).keys(), x => Utilities.formatDate(new Date(2021, x, 15), Session.getScriptTimeZone(), "MMM"))];
  mA.forEach((e, i) => { midx[i] = i; })
  let cA = [];
  let bA = [];
  let wA = [null, null, null, null, null, null, null];
  const ss = SpreadsheetApp.getActive();
  const sh = ss.getActiveSheet();
  sh.clear();
  const year = new Date().getFullYear();
  let i = midx[m % 12];
  let month = new Date(year, i, 1).getMonth();
  let dates = new Date(year, i + 1, 0).getDate();
  var events = { pA: [] };
  cals.forEach(c => {
    let evs = c.getEvents(new Date(year, month, 1), new Date(year, month, dates));
    evs.forEach(ev => {
      let st = ev.getStartTime();
      let dd = st.getDate();
      let hh = st.getHours();
      let mm = st.getMinutes();
      let sts = `${hh}:${mm}`;
      if (!events.hasOwnProperty(dd)) {
        events[dd] = [];
        events[dd].push(`${ev.getTitle()} - ${sts}`);
        events.pA.push(dd);
      } else {
        events[dd].push(`${ev.getTitle()} - ${sts}`);
      }
    });
  });
  cA.push([mA[month], dates, '', '', '', '', '']);
  bA.push(['#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff']);
  cA.push(oA)
  //bA.push(['#ffff00', '#ffff00', '#ffff00', '#ffff00', '#ffff00', '#ffff00', '#ffff00']);
  let d = [];
  let ddd = [];
  for (let j = 0; j < dates; j++) {
    let day = new Date(year, i, j + 1).getDay();
    let date = new Date(year, i, j + 1).getDate();
    if (day < wA.length) {
      wA[dObj[dA[day]]] = date;
      if (events.hasOwnProperty(date)) {
        wA[dObj[dA[day]]] += '\n' + events[date].join('\n')
      }
    }
    if (cy == year && cm == month && cd == date) {
      rObj.roff = cA.length;
      rObj.coff = dObj[dA[day]];
    }
    if (dA[day] == oA[wA.length - 1] || date == dates) {
      cA.push(wA);
      //bA.push(['#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff']);
      wA = ['', '', '', '', '', '', ''];
    }
  }
  const dtnotcur = SpreadsheetApp.newTextStyle().setBold(true).setForegroundColor('black').build();//used with richtext
  const dtcur = SpreadsheetApp.newTextStyle().setBold(true).setForegroundColor('red').build();
  const evsty = SpreadsheetApp.newTextStyle().setFontSize(6).setForegroundColor('black').build();
  rObj.cA = cA;
  rObj.crtA = cA.map((r, i) => {
    let row = [];
    r.map((c, j) => {
      if (c == '' || c == null) {
        row.push(null);
        return;
        //c = ' ';//heres the current solution
      }
      if(typeof c != 'string') {
        c = c.toString();
      }
      let idx = c.indexOf('\n');
      let rtv = SpreadsheetApp.newRichTextValue().setText(c);
      if (rObj.roff == i && rObj.coff == j) {
        if (~idx) {
          rtv.setTextStyle(0, idx, dtcur)
          rtv.setTextStyle(idx + 1, c.length, evsty);
          row.push(rtv.build());
        } else {
          rtv.setTextStyle(0, c.length, dtcur);
          row.push(rtv.build());
        }
      } else {
        if (~idx) {
          rtv.setTextStyle(0, idx, dtnotcur)
          rtv.setTextStyle(idx + 1, c.length, evsty);
          row.push(rtv.build());
        } else {
          if (c.length > 0) {
            rtv.setTextStyle(0, c.length, dtnotcur);
            row.push(rtv.build());
          } else {
            row.push(rtv.build());
          }
        }
      }
    });
    return row;
  });
  return rObj;
}

但这是有问题的部分;我将二维值数组转换为富文本值。

const dtnotcur = SpreadsheetApp.newTextStyle().setBold(true).setForegroundColor('black').build();
  const dtcur = SpreadsheetApp.newTextStyle().setBold(true).setForegroundColor('red').build();
  const evsty = SpreadsheetApp.newTextStyle().setFontSize(6).setForegroundColor('black').build();
  rObj.cA = cA;
  rObj.crtA = cA.map((r, i) => {
    let row = [];
    r.map((c, j) => {
      if (c == '' || c == null) {//I started by pushing a null into the row array and skipping to  the next loop but that's when I started get the error
        row.push(null);
        return;
        //c = ' ';//heres the current solution
      }
      if(typeof c != 'string') {
        c = c.toString();
      }
      let idx = c.indexOf('\n');//the inital error was cannot find function indexOf() of null
      let rtv = SpreadsheetApp.newRichTextValue().setText(c);
      if (rObj.roff == i && rObj.coff == j) {
        if (~idx) {
          rtv.setTextStyle(0, idx, dtcur)
          rtv.setTextStyle(idx + 1, c.length, evsty);
          row.push(rtv.build());
        } else {
          rtv.setTextStyle(0, c.length, dtcur);
          row.push(rtv.build());
        }
      } else {
        if (~idx) {
          rtv.setTextStyle(0, idx, dtnotcur)
          rtv.setTextStyle(idx + 1, c.length, evsty);
          row.push(rtv.build());
        } else {
          if (c.length > 0) {
            rtv.setTextStyle(0, c.length, dtnotcur);
            row.push(rtv.build());
          } else {
            row.push(rtv.build());
          }
        }
      }
    });
    return row;
  });
  return rObj;
}

只是好奇那些一直使用富文本的人是否有更好的方法来处理空单元格的问题。该解决方案只是在空单元格中放置一个空格并继续前进。

这是当前日历的样子。我无法将整个季度都穿上。

它可能会更干净,但我同意。说到外表,我没那么挑剔。

我应该采取卡洛斯·M 所采取的更简单的道路。希望接下来我会考虑这个问题,但我是这样做的:

当前工作解决方案:

function monthlyCalendarWithEvents(obj) {
  var m = obj.m || new Date().getMonth();
  var wsd = obj.wsd || 1;//defaults to Monday
  const calids = obj.calids || CalendarApp.getAllOwnedCalendars().map(c => c.getId());
  const cals = calids.map(id => CalendarApp.getCalendarById(id));
  const td = new Date();
  const [cy, cm, cd] = [td.getFullYear(), td.getMonth(), td.getDate()];
  const dA = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
  const oA = [...Array.from(Array(7).keys(), idx => dA[(idx + wsd) % 7])]
  let dObj = {};
  let midx = {};
  let rObj = { cA: null, roff: null, coff: null };
  oA.forEach(function (e, i) { dObj[e] = i; });
  const mA = [...Array.from(new Array(12).keys(), x => Utilities.formatDate(new Date(2021, x, 15), Session.getScriptTimeZone(), "MMM"))];
  mA.forEach((e, i) => { midx[i] = i; })
  let cA = [];
  let bA = [];
  let wA = [null, null, null, null, null, null, null];
  const ss = SpreadsheetApp.getActive();
  const sh = ss.getActiveSheet();
  sh.clear();//after clearing the sheet I get the rtvnull which I then push into the final output whenever I hit an empty cell.
  const rtvnull = sh.getRange("A1").getRichTextValue();
  const year = new Date(new Date().getFullYear(),m,1).getFullYear();
  let i = midx[m % 12];
  let month = new Date(year, i, 1).getMonth();
  let ldom = new Date(year, i + 1, 0).getDate();
  var events = { pA: [] };
  cals.forEach(c => {
    let evs = c.getEvents(new Date(year, month, 1), new Date(year, month, ldom));
    evs.forEach(ev => {
      let st = ev.getStartTime();
      let dd = st.getDate();
      let hh = st.getHours();
      let mm = st.getMinutes();
      let sts = `${hh}:${mm}`;
      if (!events.hasOwnProperty(dd)) {
        events[dd] = [];
        events[dd].push(`${ev.getTitle()} - ${sts}`);
        events.pA.push(dd);
      } else {
        events[dd].push(`${ev.getTitle()} - ${sts}`);
      }
    });
  });
  cA.push([mA[month], ldom, '', '', '', '', '']);
  bA.push(['#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff']);
  cA.push(oA)
  //bA.push(['#ffff00', '#ffff00', '#ffff00', '#ffff00', '#ffff00', '#ffff00', '#ffff00']);
  let d = [];
  let ddd = [];
  for (let j = 0; j < ldom; j++) {
    let day = new Date(year, i, j + 1).getDay();
    let date = new Date(year, i, j + 1).getDate();
    if (day < wA.length) {
      wA[dObj[dA[day]]] = date;
      if (events.hasOwnProperty(date)) {
        wA[dObj[dA[day]]] += '\n' + events[date].join('\n')
      }
    }
    if (cy == year && cm == month && cd == date) {
      rObj.roff = cA.length;
      rObj.coff = dObj[dA[day]];
    }
    if (dA[day] == oA[wA.length - 1] || date == ldom) {
      cA.push(wA);
      //bA.push(['#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff']);
      wA = ['', '', '', '', '', '', ''];
    }
  }
  const dtnotcur = SpreadsheetApp.newTextStyle().setBold(true).setForegroundColor('black').build();
  const dtcur = SpreadsheetApp.newTextStyle().setBold(true).setForegroundColor('red').build();
  const evsty = SpreadsheetApp.newTextStyle().setFontSize(6).setForegroundColor('black').build();
  rObj.cA = cA;
  rObj.crtA = cA.map((r, i) => {
    let row = [];
    r.map((c, j) => {
      if (c == '' || c == null) {
        row.push(rtvnull);//this is where I push the rtvnull into thus no longer needing to put a space in and have to run through the rest of the loop.
        return;
        //c = ' ';//here is the old space solution in case the other one fails in the near future for some other yet unforeseen problem
      }
      if(typeof c != 'string') {
        c = c.toString();
      }
      let idx = c.indexOf('\n');
      let rtv = SpreadsheetApp.newRichTextValue().setText(c);
      if (rObj.roff == i && rObj.coff == j) {
        if (~idx) {
          rtv.setTextStyle(0, idx, dtcur)
          rtv.setTextStyle(idx + 1, c.length, evsty);
          row.push(rtv.build());
        } else {
          rtv.setTextStyle(0, c.length, dtcur);
          row.push(rtv.build());
        }
      } else {
        if (~idx) {
          rtv.setTextStyle(0, idx, dtnotcur)
          rtv.setTextStyle(idx + 1, c.length, evsty);
          row.push(rtv.build());
        } else {
          if (c.length > 0) {
            rtv.setTextStyle(0, c.length, dtnotcur);
            row.push(rtv.build());
          } else {
            row.push(rtv.build());
          }
        }
      }
    });
    return row;
  });
  return rObj;
}

 

解释:

当你使用getRichTextValues()在空范围(或单元格)上,您将不会得到null,相反它仍然输出一个RichTextValue目的。所以设置实际上是非法的null到一个范围使用setRichTextValues():

此示例脚本在空电子表格上运行:

function myFunction() {
  var ss = SpreadsheetApp.getActiveSheet();
  var range = ss.getRange("A1:A2");
  var arr = range.getRichTextValues();
  Logger.log(arr);
  var bold = SpreadsheetApp.newTextStyle()
    .setBold(true)
    .build();
  var richTextA1 = SpreadsheetApp.newRichTextValue()
    .setText("This cell is bold")
    .setTextStyle(bold)
    .build();
  range.setRichTextValues([[richTextA1],null]);
}

代替null,你可以推动RichTextValue由空单元格返回的对象作为占位符。

参考:

类别范围 |获取 RichTextValues() https://developers.google.com/apps-script/reference/spreadsheet/range#getrichtextvalues

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取对象 SpreadsheetApp.Range 上的方法或属性 setRichTextValues 时出现意外错误 的相关文章

  • Google Sheets API v4:batchGet 不起作用

    无法使用 batchGet 让 Google Sheets API v4 返回多个范围值 它给出以下错误 尽管文档说它需要 valueRanges 但所有范围和电子表格 ID 都是正确的 额外的参数块必须是 javascript 对象文字
  • 将电子邮件签名添加到电子邮件通知脚本

    我正在 Google Apps 脚本上编写一段代码 以便每次在我的网站上发布新公告时发送电子邮件 这是供参考的代码 var url of announcements page https sites google com announcem
  • 寻找使用库版本的方法?

    我正在通过库在多个电子表格上部署脚本 但正如您所知 脚本 目前 还无法知道它是否正在运行最新版本 我试图通过为我的代码创建自己的版本控制来找到解决此问题的方法 我有一个 Web 服务返回我的库代码的最新版本号 以便我可以对其进行比较 但 o
  • Google Apps 脚本无法从托管的 GAS 转换为特定的云项目

    我有一个 GAS 管理的项目 我想将其转换为特定的谷歌标准云项目 我有身份证 我将其输入到资源 云托管项目中 然后得到 项目不存在 或者您需要对其进行编辑访问 它确实存在 并且我拥有权限 因为我是所有者 该错误有些误导性 我花了一段时间才弄
  • 使用文件名将文件一个文件夹复制到 Google 云端硬盘中的另一个文件夹

    我的谷歌云端硬盘帐户中有两个文件夹 文件夹 1 和 文件夹 2 文件夹1 内有多个文件 假设有一个文件名Test txt我想复制Test txt使用 Driveapp 将文件保存到 文件夹 2 我找到了代码 但它仅适用于 文件唯一 ID 我
  • “在 Chrome 网上应用店中注册”未显示在 Google 脚本编辑器中

    我正在尝试将脚本 在脚本库中称为 Paypal 商店 作为 Chrome 网上应用店中的网络应用程序发布 但 Google 脚本的 发布 菜单中未显示 在 Chrome 网上应用店中注册 项目编辑器 此菜单中唯一的项目是 发布到库 和 部署
  • 如何在链接到表单的工作表中执行 Google 工作表脚本之前等待 Google 表单脚本完成执行

    我有两个脚本 一个链接到 Google 表单 另一个链接到 Google 表格 我需要确保 Google 表单脚本在执行链接到 Google 表单的工作表的 Google 工作表脚本主体之前完成执行 如何才能做到这一点 需要等待 Googl
  • Google Apps 脚本:从云端硬盘下载文件(同一用户)

    我正在尝试编写一个 Google Apps 脚本来下载特定云端硬盘文件夹中的所有文件 可能是 csv 文件 我找到了 getDownloadUrl 方法 但我不知道该做什么do用它 我目前正在尝试以下代码 其中files是文件夹中的文件列表
  • 如何检查 Gmail 标签是否有嵌套子标签?

    使用Google Apps脚本 是否有一个功能可以检查Gmail标签是否有嵌套子标签 如果标签有一个或多个子标签 我想将它们从代码序列中排除 没有直接的方法可以从 父 标签获取标签 但是使用简单的方法来获取标签非常简单getUserLabe
  • 从 Gmail 获取 pdf 附件作为文本

    我在网络和 Stack Overflow 上搜索但没有找到解决方案 我尝试做的事情如下 我通过邮件收到某些附件 我希望将其作为 纯 文本进行进一步处理 我的脚本如下所示 function MyFunction var threads Gma
  • 图像未显示在从 HTML 创建的 PDF 上

    我想动态创建 PDF 这意味着我将从 Google Drive 获取文件 然后将它们放入 HTML 代码中 并尝试从中创建 PDF 一切工作正常 除了图像没有显示 我现在正在做的是 从 HTML 字符串创建 HtmlOutput 获取该 H
  • 如何使用 OnChange() 触发器

    我有一个电子表格以及该电子表格的主副本 每次用户将数据输入单元格时 它都会获取新数据并放入主副本中 然而最近 我注意到一个用户创建了一个新列 该列未被 OnEdit 捕获 于是我查了一下 看到了去年实现的OnChange 但是 我不知道如何
  • 谷歌表格根据今天的日期隐藏行

    在 Google Sheets 中 当 A 列中的日期等于或早于今天的日期时 我需要一个脚本来自动隐藏工作表 1 中的行 因此 如果今天是 2018 年 8 月 29 日 单元格 A3 中的日期是 2018 年 8 月 28 日 则第 3
  • Google电子表格脚本创建特定范围内的数据验证

    我正在尝试这个脚本来创建数据验证 但它总是不起作用 function test validation var Spread SpreadsheetApp getActiveSpreadsheet var Sheet Spread getSh
  • 从 Google 电子表格接收实时更新

    我正在尝试设置与 Google 电子表格的双向同步 我可以使用其数据集将更改推送到 Google 电子表格Google 表格 API V4 https developers google com sheets 现在 我希望每当有人实时或近实
  • 当 Google 任务标记为“已完成”时如何触发 Google 脚本

    Google Apps 脚本允许由各种事件触发脚本 看here https developers google com apps script guides triggers 当用户将任务标记为已完成 在 Google 任务中 时 我想更新
  • 用于设置形状颜色的 Google Apps 脚本

    我正在查看 Google Apps 脚本参考here https developers google com apps script reference slides fill setSolidFill Color 并注意到有一种方法set
  • 使用 google apps 脚本添加大量响应

    我想制作一个脚本 添加大量 大约 1500 简历和候选人信息作为对表单的回复 我有谷歌电子表格的信息 我将其链接到表单 但我只能管理回复 即使我更改电子表格 或添加 表单中也不会发生更新 我正在添加行 但没有添加响应 那可能吗 我看到了 2
  • Google App Script postMessage 与收件人窗口的来源不匹配

    我有一个 Google App 脚本部署为Web应用程序 https developers google com apps script guides web 它工作正常 直到今天晚上我发现它无法在 Firefox 或 Chrome 中加载
  • Google Sheets - 如何从 iOS 应用程序运行脚本?

    我在电子表格中使用脚本在活动行下方添加行并从活动行复制内容 在 PC 上 我可以通过图像 绘图触发脚本 效果很好 但我不知道如何让它在 iOS 应用程序中工作 其中图像触发不起作用 并且将内容从一个应用程序复制到另一个应用程序是一场噩梦 我

随机推荐