Javascript 同步独立的电子表格行,由IMPORTRANGE()填写

Javascript 同步独立的电子表格行,由IMPORTRANGE()填写,javascript,google-apps-script,google-sheets,Javascript,Google Apps Script,Google Sheets,我需要同步两个相互引用的电子表格的内容,如果其中一个表格中添加了新行,则保持它们的行同步 我在Google Sheets中有两个电子表格(尽管如果有跨电子表格的解决方案,Excel和GS都很好): 电子表格1在A:F中有数据,party1(一组用户)在其中写入数据 电子表格2从电子表格1中输入A:F范围,然后用G:M写入更多详细信息,数据由party2写入 其工作方式是party1将数据写入A1-F10行,然后party2根据party1写入的内容将附加数据写入电子表格2中 例如,如果电子表

我需要同步两个相互引用的电子表格的内容,如果其中一个表格中添加了新行,则保持它们的行同步

我在Google Sheets中有两个电子表格(尽管如果有跨电子表格的解决方案,Excel和GS都很好):

  • 电子表格1在A:F中有数据,party1(一组用户)在其中写入数据
  • 电子表格2从电子表格1中输入A:F范围,然后用G:M写入更多详细信息,数据由party2写入
其工作方式是party1将数据写入A1-F10行,然后party2根据party1写入的内容将附加数据写入电子表格2中

例如,如果电子表格A1:F10是项目的名称、价格、est交货时间、数量等,则电子表格G1:M10可能是订单日期、交货日期(是/否)等的一组数据


我目前遇到的问题是,当设置电子表格时,它们的读数很精细,即电子表格1中的1-10与电子表格2中的1-10对齐,但过了一段时间,一些新行被添加到电子表格1中的旧行2-5之间。这将抛出电子表格2中的订单(现在电子表格1中的第4行与电子表格2中的第4行不对齐,并且数据变得不一致)。是否存在这样的情况,即使有人在现有行的中间添加额外的行,电子表格也会更新?

< P>这是数据库设计中的经典问题;如何关联两个表中的信息。通常的解决方案是使用关键数据;两个表中都存在的一个或多个列,它们提供唯一标识符或键来关联行

我们可以根据您的情况调整该想法,使用一个脚本调整电子表格2中行的位置以与电子表格1同步。要做到这一点,我们需要确定一个键,比如名称列,它必须存在于两个电子表格中

这需要在电子表格2中进行一个小的更改,其中一个名称列现在将出现在G列中,紧随a-F列中导入的范围

A B C D E F G H I J
|名称|价格| est交货时间|数量|等|商品|名称|订单日期|交货|诸如此类|
<------导入--->*键*<----第2页--->
演示 下面是它在实际中的表现!本例仅为方便起见,在同一电子表格中使用了两张工作表。在演示中,一个新的“item”行被添加到表1的中间,由于代码< > =输入()/<代码>函数,在表2中自动出现了“item”行。同步功能在一个1分钟定时触发器上运行,您将看到它在大约20秒内移动东西

您可以获取电子表格+嵌入式脚本的副本

代码
/**
*使用键列的名称调用syncTables()。
*/
函数doSyncTables(){
同步表(“名称”);
}
/*
*将“订单”电子表格与“项目”电子表格中导入的行同步。
*
*发件人:http://stackoverflow.com/a/33172975/1677912
*
*显示用作键列的@param{String}keyName列标题
*在“订单”数据的开头,如下所示
*“项目”数据。
*/
函数同步表(键名){
var sheet2=SpreadsheetApp.openById(sheetId2.getSheetByName('Orders');
//获取数据
var lastCol=sheet2.getLastColumn();
var lastRow=sheet2.getLastRow();//包括所有行,甚至是空的,因为=importRange()
var headers=sheet2.getRange(1,1,1,lastCol).getValues()[0];
var-keyCol=headers.lastIndexOf(keyName)+1;
var itemKeys=sheet2.getSheetValues(1,1,lastRow,1).map(函数(行){返回行[0]});
var itemData=sheet2.getSheetValues(1,1,lastRow,keyCol-1);
var orderData=sheet2.getSheetValues(1,keyCol,lastRow,lastCol keyCol+1);
var ordersByKey=[];//按键跟踪订单
//扫描orderData中的键

对于(var row=1;row而言,mogsdad目前的答案一如既往地好。我只想指出一个不太复杂的替代方案:

如果您可以接受阻止电子表格1允许插入或删除行,则可以避免此问题。例如,您可以使用列标记“已删除”,而不是删除行(并使用筛选器从视图中删除)

要防止在电子表格1中插入和删除行,只需选择右侧整个未使用的列,并创建一个受保护的范围,以便所有编辑器都没有权限。这将防止在行级别修改到最后一个现有行(但仍可以在该范围下插入新行)


它也不会阻止用户交换两行数据。但是知道这个更简单的替代方案还是很好的。

@ZigMandel感谢您的澄清,我已经完全更新了答案。这已经足够好了,我可能很快会在博客上发布它!您知道有没有办法让脚本“在更改时”运行而不是每一分钟?为什么要使用2个单独的电子表格?是否有一个敏感数据,另一方不能查看或是否是编辑权限的问题?@ BrYNP-好问题,这是因为在SeabeSeT2中有敏感数据,我不希望PARTY1能够考虑GETT。如果您不想与重新构建工作表的用户打交道,请删除所涉及的外部表单/自定义ui