GOOGLE SHEETS:使用宏将单元格范围存档到第二张表有时会丢失范围值并导致参考错误

问题描述 投票:0回答:1

全新用户平安到来。刚刚加入,希望能获得一些有关我设置的宏的帮助。如果我使用任何不正确的术语或语言,请道歉。

奇怪的是,在某些情况下,它工作得很好,而在其他情况下,它用“引用错误”替换了公式的“范围”部分。

例如,我有一系列包含合并单元格的模板,这些模板从单元格中提取产品名称,搜索 img 链接并显示它。就像这样...

Template Image

合并单元格中的公式为:

=iferror(IMAGE(vlookup(C5,ImageList!A3:E,5,0))," ")

  • C5 是产品名称,
  • ImageList 是另一张包含所有图像链接的工作表。

我设置的宏是一个简单的选择、复制和粘贴到“存档”工作表的操作,因此我可以快速生成多个订单请求,将每个请求移至工作表,然后清除并替换干净模板存档中的模板在另一张纸上。

其宏是:

function ArchiveAndReset() {
  var spreadsheet = SpreadsheetApp.getActive();
  spreadsheet.getRange('B4:r30').activate();
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Existing Product Order Archive'), true);
  spreadsheet.getRange('3:33').activate();
  spreadsheet.getActiveSheet().insertRowsBefore(spreadsheet.getActiveRange().getRow(), 30);
  spreadsheet.getActiveRange().offset(0, 0, 30, spreadsheet.getActiveRange().getNumColumns()).activate();
  spreadsheet.getRange('B4').activate();
  spreadsheet.getRange('Existing Product Template!B4:r30').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Existing Product Order Archive'), true);
  spreadsheet.getRange('c4').activate();
  spreadsheet.getRange('Existing Product Template!c4').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Clean Template Archive'), true);
  spreadsheet.getRange('B4:r30').activate();
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Existing Product Template'), true);
  spreadsheet.getRange('B4').activate();
  spreadsheet.getRange('\'Clean Template Archive\'!B4:r30').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
}

合并图像单元格的位置位于“B4:r30”范围内。特别是“K4:M14”。

这个特定的宏工作正常,当复制到存档时,图像公式将按原样保留:

=iferror(IMAGE(vlookup(C5,ImageList!A3:E,5,0))," ")

我遇到的问题是这样的。我以相同的方式设置了第二个模板,但是当复制到存档完成后,公式显示如下:

=iferror(IMAGE(vlookup(C5,#REF,5,0))," ")
丢失公式的范围部分。

当我检查宏时,我找不到任何会导致此问题的差异。 该宏如下:

function KIDArchiveReset() {
  var spreadsheet = SpreadsheetApp.getActive();
  spreadsheet.getRange('42:73').activate();
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Existing Product Order Archive'), true);
  spreadsheet.getRange('4:34').activate();
  spreadsheet.getActiveSheet().insertRowsBefore(spreadsheet.getActiveRange().getRow(), 34);
  spreadsheet.getActiveRange().offset(0, 0, 31, spreadsheet.getActiveRange().getNumColumns()).activate();
  spreadsheet.getRange('5:5').activate();
  spreadsheet.getRange('\'Existing Product Template\'!42:73').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Clean Template Archive'), true);
  spreadsheet.getRange('73:104').activate();
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Existing Product Template'), true);
  spreadsheet.getRange('42:42').activate();
  spreadsheet.getRange('\'Clean Template Archive\'!73:104').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false);
  spreadsheet.getRange('42:42').activate();
  spreadsheet.getRange('\'Clean Template Archive\'!73:104').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_FORMULA, false);
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Existing Product Order Archive'), true);
}

在我看来,它的运作方式完全相同。合并的单元格再次出现在第一个选择范围“('42:73')”内。具体来说是“K42:M52”。它使用相同的“PASTE_NORMAL”函数。

我尝试了各种方法试图让他们以同样的方式行事,包括......

•中断合并、复制单个单元格、重新合并...仍然会导致引用错误

•仅粘贴公式,同样的错误。

•仅粘贴值,同样的错误。

一位同事建议问题可能与在宏中使用绝对值与相对值有关,但我不确定如何测试/修复该问题,并且如上所述,第一个模板工作正常。我相信我在设置每个模板时使用了绝对参考值,并且它们按预期运行。

非常感谢您的时间和考虑。

google-apps-script google-sheets macros referenceerror
1个回答
0
投票

我做了一个简单的测试用例来展示如何将包含图像

Test
的一张纸的内容复制到另一张
Archive

正如 Cooper 提到的,您应该学习使用 SpreadsheetApp 对象模型来编写脚本,而不是使用记录宏。录制宏会跟踪您的鼠标和键盘输入,并生成一堆不需要且通常是多余的激活指令。

名为“测试”的工作表

名为 ImageList 的工作表

复制后名为存档的表

代码.gs

function test() {
  try {
    let spread = SpreadsheetApp.getActiveSpreadsheet();
    let sheet = spread.getSheetByName("Test");
    let original = sheet.getRange("A1:D14");
    sheet = spread.getSheetByName("Archive");
    let copy = sheet.getRange("A1:D14")
    original.copyTo(copy);
  }
  catch(err) {
    console.log("Error in test: "+err)
  }
}

参考文献

© www.soinside.com 2019 - 2024. All rights reserved.