获取对象 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 Apps 脚本中新创建的文件夹的 ID

    作为 Google Apps 脚本项目的一部分 我尝试将活动电子表格和几个上传的文件移动到在共享目录中创建的新文件夹中 我已经能够使用以下命令创建新文件夹 DriveApp getFolderById parentFolder create
  • Google Apps 脚本中 $.ajax() 的服务器端等效项是什么?

    我想在 Google App 脚本中从服务器端代码执行 HTTP 请求Authorization标头 是否有用于发送 HTTP 请求的 App Script API Google Apps 脚本中的这段代码相当于什么 var api URL
  • Google Apps 脚本触发器 - 每当将新文件添加到文件夹时运行

    我想在任何时候执行谷歌应用程序脚本new文件被添加到特定文件夹 目前 我使用的是每 x 分钟运行一次的时钟触发器 但我只需要在向文件夹添加文件时运行脚本 有没有办法做到这一点 与this https stackoverflow com qu
  • 在 userCodeAppPanel 中看不到我的 javascript 代码

    这是来自 Google 电子表格中包含的脚本的代码 唯一的其他代码是onOpen它创建菜单和showDialog 功能 function showDialog userInterface HtmlService createHtmlOutp
  • 有没有办法将 Google 文档分割成多个 PDF?

    我想在 Google Scripts VBA 代码中复制我为 Word 文档编写的代码 基本上 它通过搜索我插入文档中的标签 将文档 切片 为多个 PDF 文件 目的是允许合唱团使用 forScore 管理乐谱的应用程序 在切片点插入先前注
  • 移动设备:缺少操作

    我正在尝试执行该操作的 POST 但是 当我发出请求时 我收到代码 400 表示操作值丢失 my code function mobileAPIPOST var response UrlFetchApp fetch https www go
  • 测量填写部分的时间 - 谷歌表单

    我正在尝试使用谷歌表单进行研究调查问卷 对于某些部分 我想自动测量用户填写所需的时间 谷歌表单中没有这样的选项 我尝试复制表单源 并用 javascript 填充时间 但它不起作用 跨源问题 未能成功托管复制的表单 如何做到 我如何衡量回答
  • getActiveRange 不返回当前选择

    这应该是一个简单的问题 但我自己无法破解 我想将活动工作表中当前选定的单元格复制到名为 data 的数组中 var sheet SpreadsheetApp getActive getActiveSheet var selection sh
  • 在 Google 网站中嵌入 Google 电子表格时,Google Apps 脚本可帮助解决错误?

    电子表格 A 是欢迎新移民来到我们小镇的团队的主数据源 它里面有大量非常敏感的数据 不能公开 哪怕是一点点 我们谈论的是孩子的姓名和出生日期以及他们上学的地方 保证电子表格 A 的安全是至关重要的任务 因此 电子表格 B 使用 import
  • 使用 Google Apps 脚本从 Firebase 读取数据

    因此 正如标题所示 我目前正在解决一个相当麻烦的问题 这是场景 我有一个 Google 电子表格 其中包含一个包含姓名 电子邮件和到期日期的模板 但是 它不包含实际数据 数据本身位于 Firebase 中并且不断变化 那么 我的目标是让sc
  • 如何使用脚本获取 Google 文档中的修订历史记录?

    如何使用脚本获取 Google 文档中的修订历史记录 我该怎么做 一些想法 您可能需要启用 Drive SDK 您可以在 资源 gt 高级 Google 服务 菜单中执行此操作 然后执行类似以下操作 var revisions Drive
  • 使用 Google App Script 从一个电子表格跳转到另一个电子表格

    我有一个脚本 仅当我位于运行代码的当前工作表中时才有效 在 A1 中 我有一个复选框 其作用是刷新 api 请求 因此 我下面的代码单击复选框并获取新数据 所以我的代码的目的基本上是单击 A1 中的复选框 但是 运行此代码只会激活复选框 但
  • 如何在表单提交时运行 Appscript?

    我正在尝试创建当用户完成表单提交时重定向到网络应用程序的 Google 表单 我查过谷歌开发者文档 https developers google com apps script guides triggers 但我看不到一种简单的方法来做
  • Google Apps 脚本自动生成的库文档

    我目前正在开发一个 Google Apps 脚本库 它基本上将电子表格视为数据库对象 目前 该库有两个相同的功能 例如 Opens and creates a query object for a spreadsheet with the
  • 通过脚本删除工作表

    我正在执行此代码 function deleteSheets var ss SpreadsheetApp getActiveSpreadsheet var sheets ss getSheets var transp ss getSheet
  • 类型错误:ss.getSheetByName 不是函数

    我的代码旨在从用户输入表单中获取数据并将新行插入到电子表格中 function addNewRow rowData const currentDate new Date const ss SpreadsheetApp getActiveSh
  • 正则表达式 - 使用正则表达式提取电子邮件文档的子字符串

    我正在尝试使用正则表达式提取电子邮件文档的子字符串 我正在在线测试正则表达式 它运行得很好 在线正则表达式测试器 https regex101 com r BbWBPk 1 我有一个功能可以检查 Google Apps 脚本上的正则表达式
  • 电子表格的 Google 脚本(If 语句)

    我希望有人能帮助我解决这个问题 我是编码新手 我有一个谷歌电子表格 其中有一个可以推送电子邮件的脚本 我试图让脚本忽略脚本已发送电子邮件的行 function onOpen var ui SpreadsheetApp getUi Or Do
  • 在应用程序脚本中将 .XLS 转换为 Google 表格的最有效方法是什么?

    我每周都会自动将 XLS 文件下载到 Google 云端硬盘 我想每周自动将最新下载的 XLS 文件转换为 Google 表格格式 因此转到特定的 Google 驱动器文件夹 查找最新或未转换的 XLS 文件 转换为 Google 表格格式
  • 与 google 脚本一起使用时,币安搜索 API 返回 403

    我正在使用 binance API 来获取 USDT 的价格 该 API 适用于邮递员 但不适用于 google 脚本 function fetchCryptoPricesFromApi const data page 1 rows 10

随机推荐