AppSpreadsheet (GAS):避免一些系统测试数据的问题

AppSpreadsheet (GAS): avoid some problems with sistematic tested data

在我目前使用 spreadsheet 的工作中,所有插入的数据都会通过测试,检查是否在其他 sheet 的相同索引上找到相同的值。失败,在当前单元格中放入一条警告消息。

//mimimalist algorithm
function safeInsertion(data, row_, col_)
{
  let rrow = row_ - 1; //range row
  let rcol = col_ - 1; // range col
  const active_sheet_name = getActiveSheetName(); // do as the its name suggest
  const all_sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
  
  //test to evaluate the value to be inserted in the sheet    
  for (let sh of all_sheets)
  {
    if (sh.getName() === active_sheet_name)
      continue;  
    //getSheetValues do as its name suggest.
    if( getSheetValues(sh)[rrow][rcol] === data )
      return "prohibited insertion"
  }
  return data;  
} 
// usage (in cell): =safeInsertion("A scarce data", ROW(), COLUMN())

问题是:

如何使用这种方法获得 stablesheet?

PS:原函数对每次数据插入做更多的测试。这些测试包括计算实际 sheet 和所有 sheet 中的频率。

编辑:

事实上,我无法创建一个stable sheet。为了进行测试,a 允许您复制我的代码并进行最少的修改。

function safelyPut(data, max_onesheet, max_allsheet, row, col)
{
  // general initialization
  const data_regex = "\^\s*"+data+"\s*$"
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const activesheet = spreadsheet.getActiveSheet();
  const active_text_finder = activesheet.createTextFinder(data_regex)
                                        .useRegularExpression(true)
                                        .matchEntireCell(true);
  const all_text_finder = spreadsheet.createTextFinder(data_regex)
                                     .useRegularExpression(true)
                                     .matchEntireCell(true);
  const all_occurrences = all_text_finder.findAll();

  //test general data's environment
  const active_freq = active_text_finder.findAll().length;
  if (max_onesheet <= active_freq)
    return "Too much in a sheet";
  const all_freq = all_occurrences.length;
  if (max_allsheet <= all_freq)
    return "Too much in the work";
  
  //test unicity in a position
  const active_sname = activesheet.getName();
  for (occurrence of all_occurrences)
  {
    const sname =  occurrence.getSheet().getName();

    //if (SYSTEM_SHEETS.includes(sname))
      //continue;

    if (sname != active_sname)
    if (occurrence.getRow() == row && occurrence.getColumn() == col)
    if (occurrence.getValue() == data)
    {
      return `${sname} contains same data with the same indexes.`;
    };
  }

  return data;  
}

创建两个或三个单元格并在短范围short range 中随机放置一个值按照用法

=safeInsertion("稀缺数据", 3; 5; ROW(), COLUMN())

去做吧,说不定你会得到一个unstable sheet.

关于cached values confuse me sometimes. The script is changed but not perceived by the sheet until renewing manually the cell's content or refreshing all table. No relevant configuration available to this issue?,当你想刷新safeInsertion的自定义函数时,我认为this thread可能会有用。

关于Sometimes, at loading, a messing result appears. Almost all data are prohibited, for example (originally, all was fine!).What can I do to obtain a stable sheet using this approach?,在这种情况下,例如,如何降低脚本的处理成本?我想通过减少脚本的进程开销,你的情况可能会稳定一些。

当您的脚本通过降低流程成本进行修改时,下面的修改怎么样?

修改后的脚本:

function safeInsertion(data, row_, col_) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const range = ss.createTextFinder(data).matchEntireCell(true).findNext();
  return range && range.getRow() == row_ && range.getColumn() == col_ && range.getSheet().getSheetName() != ss.getActiveSheet().getSheetName() ? "prohibited insertion" : data;
}
  • 这个用法和你现在的脚本一样=safeInsertion("A scarce data", ROW(), COLUMN()).

  • 本次修改使用了TextFinder。因为我认为当从一个Google电子表格中的所有工作表中搜索值时,TextFinder适合降低处理成本。

参考文献: