是否可以在基于activeRange的公式内更改单元格引用?

时间:2019-03-28 18:59:10

标签: javascript google-apps-script google-sheets

我想根据位置更改公式中的单元格编号。

使用我的脚本的工作表用户可以单击菜单项以添加包含预设公式的布局。但是,当我运行脚本时,公式所在的单元格不会根据用户添加布局的位置更改单元格引用。

我也在寻找一种将其预设为具有计算公式的5行,10行,15行的布局的方法。

因此,当用户激活单元格A1并进入菜单时,他/她可以选择是否要添加5、10、15行。

这将是工作表内的脚本,用于计算食品成本,不仅计算制作食谱的成本,而且还需要定价以免浪费金钱。

我没有找到任何在线答案或通过Youtube指出正确方向的答案。在https://developers.google.com/apps-script/reference/script/上寻找答案,但仍然不明白如何按照我的意愿去做。

\\\ function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Kalkyle')
      .addItem('Sett inn layout', 'layout')
      .addSeparator()
      .addItem('Ny Kalkyle', 'nyKalkyle')
      .addToUi();
}    

function nyKalkyle() {

 var sheet = SpreadsheetApp.getActiveRange();
 var numFormat = sheet.setNumberFormat("0.00 KR");
 var range = "Navn:";
 var range1 = "Salgspris:";
 var range2 = "Varenummer";
 var range3 = "Varenavn";
 var range4 = "Pris pr kg";
 var range5 = "Pris pr gr";
 var range6 = "Svinn %";
 var range7 = "Vår mengde"; 
 var range8 = "Råvarekostnad";
 var range9 = "Varekost";
 var range10 = "";

 // OppskriftNavn
 sheet.setValue(range); 

 // SalgsPris
 sheet.offset(0, 3).setValue(range1); 

  // Råvarekostnad
  sheet.offset(1, 3).setValue(range8); 

  // Formel Råvarekostand
  sheet.offset(1, 4).setFormula('=sum(G9:G15)').setNumberFormat("#,## kr"); 

范围(G9:G15)需要根据布局的传入位置进行更改。当用户单击“ Ny烷基”时,它将在活动单元格中传入。

  // Varekost
  sheet.offset(0, 5).setValue(range9);

  // Formel Varekost
  sheet.offset(0, 6).setFormula('=E4/E3'); 

  // Varenummer
  sheet.offset(4, 0).setValue(range2).setBackground("lightgray"); 

  // Formel Finn varenummer
  sheet.offset(6, 0).setFormula('=ArrayFormula(IFERROR(UNIQUE(Query(IMPORTRANGE("https://docs.google.com/spreadsheets/d/1PagM-gaCoKXV012t-AzaTsk5o3GUd0YGXeXOSECSWVo/edit#gid=0";"A2:C");"Select Col1 where Col2=\'"&B9&"\'"))))');

范围(“ B9”)需要根据布局的传入位置进行更改。当用户单击“ Nykalkée”时,它将在活动单元格中被传入。

  // Varenavn
  sheet.offset(4, 1).setValue(range3).setBackground("lightgray"); 

  // Pris pr kg
 sheet.offset(4, 2).setValue(range4).setBackground("lightgray");

范围(“ B9”)需要根据布局的传入位置进行更改。当用户单击“ Nykalkée”时,它将在活动单元格中被传入。

  // Formel Finn KG pris  
  sheet.offset(6, 2).setFormula('=ArrayFormula(IFERROR(UNIQUE(Query(IMPORTRANGE("https://docs.google.com/spreadsheets/d/1PagM-gaCoKXV012t-AzaTsk5o3GUd0YGXeXOSECSWVo/edit#gid=0";"A2:E");"Select Col3 where Col2=\'"&B9&"\'"))))').setNumberFormat("#,## kr");

  // Pris pr gr
  sheet.offset(4, 3).setValue(range5).setBackground("lightgray"); 

  // Formel Pris pr gr
  sheet.offset(6, 3).setFormula('=C9/1000'); 

 // Svinn %
 sheet.offset(4, 4).setValue(range6).setBackground("lightgray");  

 // Formel svinn
 sheet.offset(6, 4).setNumberFormat("#,###%");

 // Vår mengde
 sheet.offset(4, 5).setValue(range7).setBackground("lightgray");  

 // Råvarekostnad
 sheet.offset(4, 6).setValue(range8).setBackground("lightgray"); 

setFormula内部的范围需要根据布局的传入位置进行更改。当用户单击“ Nykalkée”时,它将在活动单元格中被传入

  // Formel Råvarekostnad
 sheet.offset(6, 6).setFormula('=ArrayFormula(IF(C9;D9*F9+(E9/1*D9*F9);""))').numFormat;

}

我希望每个用户引用都在用户离开时更改布局。

如果他/她激活了单元格A1,则单元格引用需要引用公式中的正确单元格。

如果他/她已激活单元格A25,则相同。

但是根据我的脚本,它不会更改,因此无法正确计算,然后用户必须更改传入布局的每一个单元格的引用,这使得我的脚本是毫无意义。

编辑

在您在这个社区中的帮助以及在Google上的大量搜索之后,我最终得到的结果与我自己看到的结果相同。现在仍然需要找到一种方法来添加具有范围的下拉列表,就像数据验证一样

这是我以https://pastebin.com/TBw86PtK结尾的脚本

1 个答案:

答案 0 :(得分:0)

您可以使用getActiveRange获取活动单元格并使用字符串替换更新所有公式,但这是一个较差的解决方案,将很难管理。

var sheet = SpreadsheetApp.getActiveRange();
var active_row = sheet.getRow();
var active_column = sheet.getColumn();
/* 
  various math here to calculate correct row/column values,
  and convert them into A1 notation inside strings

  NOT RECOMMENDED!
*/

最好使用R1C1表示法的相对形式,该形式使用方括号。 EG:R [1] C [1]。当在R1C1中的数字周围使用方括号时,它表示当前单元格的行数或列数 relative 。如果在单元格A1中指定R [1] C [1],则引用的是单元格B2(行+ 1,列+ 1),或者是活动单元格的下方一行,右侧一行。同样,您可以在方括号中使用0或负数。 0表示当前行或列,负数表示行和列的上移和左移。

    单元格A1中的R1 [0] C [2]将产生单元格C1中的值。 (行+ 0,列+2) 单元格B3中的R1 [-2] C [-1]将产生单元格A1中的值。 (第-2行,第-1列)

因此,通过使用相对R1C1表示法,可以确保所有公式都将引用相对于工作表中插入单元格的单元格。

将公式更新为R1C1表示法后,您将需要使用SetFormulaR1C1函数而不是SetFormula

因此,假设您在现有代码中编写的公式是相对于A1的,则看起来像这样:

sheet.offset(1, 4).setFormulaR1C1('=sum(R[8]C[3]:R[14]C[3])').setNumberFormat("#,## kr");