我如何 return 来自 google 应用程序脚本的超链接

how can I return Hyperlink from google apps script

//Link_generator 

function lk(num01) {
  try{
     var sheets = SpreadsheetApp.getActiveSpreadsheet()
     var out_01 = new Array();
  
               if(num01==1){var sheetnames = ["01.01","01.02","01.03","01.04","01.05","01.06","01.07","01.08","01.09","01.10","01.11","01.12","01.13","01.14","01.15","01.16","01.17","01.18","01.19","01.20","01.21","01.22","01.23","01.24","01.25","01.26","01.27","01.28","01.29","01.30","01.31"];}
               if(num01==2){var sheetnames = ["02.01","02.02","02.03","02.04","02.05","02.06","02.07","02.08","02.09","02.10","02.11","02.12","02.13","02.14","02.15","02.16","02.17","02.18","02.19","02.20","02.21","02.22","02.23","02.24","02.25","02.26","02.27","02.28","02.29"];}
               if(num01==3){var sheetnames = ["03.01","03.02","03.03","03.04","03.05","03.06","03.07","03.08","03.09","03.10","03.11","03.12","03.13","03.14","03.15","03.16","03.17","03.18","03.19","03.20","03.21","03.22","03.23","03.24","03.25","03.26","03.27","03.28","03.29","03.30","03.31"];}
               if(num01==4){var sheetnames = ["04.01","04.02","04.03","04.04","04.05","04.06","04.07","04.08","04.09","04.10","04.11","04.12","04.13","04.14","04.15","04.16","04.17","04.18","04.19","04.20","04.21","04.22","04.23","04.24","04.25","04.26","04.27","04.28","04.29","04.30"];}
               if(num01==5){var sheetnames = ["05.01","05.02","05.03","05.04","05.05","05.06","05.07","05.08","05.09","05.10","05.11","05.12","05.13","05.14","05.15","05.16","05.17","05.18","05.19","05.20","05.21","05.22","05.23","05.24","05.25","05.26","05.27","05.28","05.29","05.30","05.31"];}
               if(num01==6){var sheetnames = ["06.01","06.02","06.03","06.04","06.05","06.06","06.07","06.08","06.09","06.10","06.11","06.12","06.13","06.14","06.15","06.16","06.17","06.18","06.19","06.20","06.21","06.22","06.23","06.24","06.25","06.26","06.27","06.28","06.29","06.30"];}
               if(num01==7){var sheetnames = ["07.01","07.02","07.03","07.04","07.05","07.06","07.07","07.08","07.09","07.10","07.11","07.12","07.13","07.14","07.15","07.16","07.17","07.18","07.19","07.20","07.21","07.22","07.23","07.24","07.25","07.26","07.27","07.28","07.29","07.30","07.31"];}
               if(num01==8){var sheetnames = ["08.01","08.02","08.03","08.04","08.05","08.06","08.07","08.08","08.09","08.10","08.11","08.12","08.13","08.14","08.15","08.16","08.17","08.18","08.19","08.20","08.21","08.22","08.23","08.24","08.25","08.26","08.27","08.28","08.29","08.30","08.31"];}
               if(num01==9){var sheetnames = ["09.01","09.02","09.03","09.04","09.05","09.06","09.07","09.08","09.09","09.10","09.11","09.12","09.13","09.14","09.15","09.16","09.17","09.18","09.19","09.20","09.21","09.22","09.23","09.24","09.25","09.26","09.27","09.28","09.29","09.30"];}
               if(num01==10){var sheetnames = ["10.01","10.02","10.03","10.04","10.05","10.06","10.07","10.08","10.09","10.10","10.11","10.12","10.13","10.14","10.15","10.16","10.17","10.18","10.19","10.20","10.21","10.22","10.23","10.24","10.25","10.26","10.27","10.28","10.29","10.30","10.31"];}
               if(num01==11){var sheetnames = ["11.01","11.02","11.03","11.04","11.05","11.06","11.07","11.08","11.09","11.10","11.11","11.12","11.13","11.14","11.15","11.16","11.17","11.18","11.19","11.20","11.21","11.22","11.23","11.24","11.25","11.26","11.27","11.28","11.29","11.30"];}
               if(num01==12){var sheetnames = ["12.01","12.02","12.03","12.04","12.05","12.06","12.07","12.08","12.09","12.10","12.11","12.12","12.13","12.14","12.15","12.16","12.17","12.18","12.19","12.20","12.21","12.22","12.23","12.24","12.25","12.26","12.27","12.28","12.29","12.30","12.31"];}
    
  for (var i = 0 ; i < sheetnames.length ; i++ ){
     var k=i+1;
    out_01.push('=hyperlink("#gid='+sheets.getSheetByName(sheetnames[i]).getSheetId()+'",'+k+')');     
  }
var division = chunk (out_01 , 7) ;
  
    return  division 

}
  catch (err){
    return "#ERROR!"
    }
}



function chunk(arr, size) {
    var i, j, temparray = [], chunk = size;
    for (i = 0, j = arr.length; i < j; i += chunk) {
        temparray.push(arr.slice(i, i + chunk));
    }
    return temparray
}

我想通过应用程序脚本在 google 电子表格中创建超链接

但是这个单元格自定义函数只显示 'hyperlink formula text'

我想要真正的超链接

如何修复此代码?

这是我的情况

问题:

自定义函数只能 return 值(字符串、数字等),不能是公式。由自定义函数编辑的“公式”return 将被解释为以 =.

开头的字符串

问题跟踪器中的相关请求:

解决方法 1:

修改您的自定义函数,使其仅 return 是 url 部分(即 #gid=...)并在 [=15= 中使用该 returned 值] 公式,由您的 sheet:

通常调用
function lk(num01,sheetIndex) {
  var sheets = SpreadsheetApp.getActiveSpreadsheet();
  var sheetnames;
  switch (num01) {
    case 1:
      sheetnames = ["01.01","01.02","01.03","01.04","01.05","01.06","01.07","01.08","01.09","01.10","01.11","01.12","01.13","01.14","01.15","01.16","01.17","01.18","01.19","01.20","01.21","01.22","01.23","01.24","01.25","01.26","01.27","01.28","01.29","01.30","01.31"];
      break;
    case 2:
      sheetnames = ["02.01","02.02","02.03","02.04","02.05","02.06","02.07","02.08","02.09","02.10","02.11","02.12","02.13","02.14","02.15","02.16","02.17","02.18","02.19","02.20","02.21","02.22","02.23","02.24","02.25","02.26","02.27","02.28","02.29"];
      break;
    // Other cases
  }
  return '#gid=' + sheets.getSheetByName(sheetnames[sheetIndex]).getSheetId();
}

然后,在每个单元格中调用它,例如:=HYPERLINK(lk(1,0),1):

一个相当大的缺点是您必须为每个单元格调用自定义函数,这会减慢过程(参考:Optimization)。因此,我不推荐这种方法。

解决方法 2:

不要为此使用自定义函数,而是通过其他上下文调用您的函数,以便像 setFormulas or setRichTextValues can be used (these methods cannot be used in the context of custom functions - ref: Using Apps Script services).

这样的方法

例如,您可以这样做(不是通过自定义函数,而是通过 custom menu - with a prompt dialog to provide the parameters, or what have you - or, alternatively, via onEdit trigger):

function lk(num01=1,TARGET_SHEET = "Sheet where hyperlinks will be written") {
  var sheets = SpreadsheetApp.getActiveSpreadsheet();
  var out_01 = new Array();
  var sheetnames;
  switch (num01) {
    case 1:
      sheetnames = ["01.01","01.02","01.03","01.04","01.05","01.06","01.07","01.08","01.09","01.10","01.11","01.12","01.13","01.14","01.15","01.16","01.17","01.18","01.19","01.20","01.21","01.22","01.23","01.24","01.25","01.26","01.27","01.28","01.29","01.30","01.31"];
      break;
    case 2:
      sheetnames = ["02.01","02.02","02.03","02.04","02.05","02.06","02.07","02.08","02.09","02.10","02.11","02.12","02.13","02.14","02.15","02.16","02.17","02.18","02.19","02.20","02.21","02.22","02.23","02.24","02.25","02.26","02.27","02.28","02.29"];
      break;
    // Other cases
  }
  //for (var i = 0 ; i < sheetnames.length; i++ ){
  for (var i = 0 ; i < 2; i++ ){
    var k=i+1;
    out_01.push('=hyperlink("#gid='+sheets.getSheetByName(sheetnames[i]).getSheetId()+'",'+k+')');     
  }
  var division = chunk (out_01 , 7) ;
  var targetSheet = sheets.getSheetByName(TARGET_SHEET);
  targetSheet.getRange(1,1,division.length,division[0].length).setFormulas(division);
}

作为其他解决方法,在您的情况下,如何将公式作为字符串值转换为有效公式?在这种情况下,您的脚本不会被修改。添加了以下功能。

用法:

1。示例脚本:

请将此函数添加到您的脚本编辑器(包括您的函数)并保存脚本。这样的话,你的展示脚本可以不用修改就可以使用了。

function installOnEdit(e) {
  const range = e.range;
  const formula = range.getFormula();
  if (!(/^\=lk\(\d+\)$/i).test(formula)) return;
  const sheet = range.getSheet();
  const id = e.source.getId();
  const sheetName = sheet.getSheetName();
  const ranges = sheet.createTextFinder("^\=hyperlink\(.+\)$").useRegularExpression(true).matchEntireCell(true).findAll().map(r => `'${sheetName}'!${r.getA1Notation()}`);
  const data = Sheets.Spreadsheets.Values.batchGet(id, { ranges }).valueRanges.map(({ range, values }) => ({ range, values }));
  Sheets.Spreadsheets.Values.batchUpdate({ data, valueInputOption: "USER_ENTERED" }, id);
}

2。启用表格 API.

此脚本使用表格 API。请在高级 Google 服务中启用表格 API。使用 Sheets API.

将作为字符串值的公式转换为有效公式

3。安装 OnEdit 触发器。

此脚本是 运行 由可安装的 OnEdit 触发器,当 =lk(##) 的自定义函数放入单元格时。 Please install OnEdit trigger to the function of installOnEdit.

4。正在测试。

当使用这个脚本时,比如你把=lk(1)放到一个单元格中,会得到如下结果。

参考文献:

已添加:

我注意到比上述方法更简单的解决方法。所以我想补充一下。

示例脚本:

在这种情况下,不需要使用可安装的 OnEdit 触发器和表格 API。您可以通过将此脚本复制并粘贴到您的脚本编辑器并保存来使用此脚本。

当您使用此脚本时,例如,请将 =lk(1) 放入单元格。这样,onEdit 函数自动成为 运行,并且从 lk() 的函数中检索公式。然后,将公式放入单元格。结果情况和上面的演示一样

function onEdit(e) {
  const range = e.range;
  const formula = range.getFormula();
  if (!(/^\=lk\(\d+\)$/i).test(formula)) return;
  const arg = formula.match(/^\=lk\((\d+)\)$/i)[1];
  const formulas = lk(Number(arg));
  const max = Math.max(...formulas.map(r => r.length));
  const res = formulas.map(r => r.length < max ? [...r, ...Array(max - r.length).fill("")] : r);
  range.offset(0, 0, res.length, res[0].length).setFormulas(res);
}