Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/464.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何比较两个工作表并删除/添加第1行中具有不同值的任何列?谷歌脚本_Javascript_Google Apps Script_Google Sheets - Fatal编程技术网

Javascript 如何比较两个工作表并删除/添加第1行中具有不同值的任何列?谷歌脚本

Javascript 如何比较两个工作表并删除/添加第1行中具有不同值的任何列?谷歌脚本,javascript,google-apps-script,google-sheets,Javascript,Google Apps Script,Google Sheets,我想比较两张图纸(基于第1行中的标题值),并删除具有唯一值(不匹配)的任何列。例如,假设Sheet1第1行数据和Sheet2第1行数据是一致的,如果用户在任何工作表中添加/删除列,我希望始终将两个工作表中的列数与其值匹配 页面标题的屏幕截图 如果两张纸都像这样 并且用户添加一个新列N 或删除第N列 如何通过删除工作表1中的奇数/不同列来确保两个工作表匹配 我尝试过修改下面的代码,但我不能只得到唯一的一个。此代码仅查找具有定义值的标题 function deleteAloneColumns(

我想比较两张图纸(基于第1行中的标题值),并删除具有唯一值(不匹配)的任何列。例如,假设Sheet1第1行数据和Sheet2第1行数据是一致的,如果用户在任何工作表中添加/删除列,我希望始终将两个工作表中的列数与其值匹配

页面标题的屏幕截图

如果两张纸都像这样

并且用户添加一个新列N

或删除第N列

如何通过删除工作表1中的奇数/不同列来确保两个工作表匹配

我尝试过修改下面的代码,但我不能只得到唯一的一个。此代码仅查找具有定义值的标题

function deleteAloneColumns(){
  var sheet = SpreadsheetApp.getActiveSheet();
  var lastColumnPos = sheet.getLastColumn();
  var headers = sheet.getRange( 1 ,1, 1, lastColumnPos ).getValues()[0];
  for( var i = lastColumnPos ; i < 1; i--){
    if( headers[i] === "alone" ) sheet.deleteColumn(i);
  }
 SpreadsheetApp.getUi().alert( 'Job done!' );
}
函数deleteAloneColumns(){
var sheet=SpreadsheetApp.getActiveSheet();
var lastColumnPos=sheet.getLastColumn();
var headers=sheet.getRange(1,1,1,lastColumnPos).getValues()[0];
对于(var i=lastColumnPos;i<1;i--){
如果(标题[i]=“单独”)sheet.deleteColumn(i);
}
SpreadsheetApp.getUi().alert('Job done!');
}

如果您能帮助比较和删除具有唯一值的列,我们将不胜感激。

问题

基于标题行值的平衡表不匹配

解决方案

如果我理解正确,您有一个运行验证的源工作表和两个主要用例:用户在源工作表中添加一个名不同于任何其他列的新列(如果您想检查该列是否与sheet1中的列严格匹配,很容易修改),或者删除一个应该存在的列

const balanceSheets = (sourceShName = 'Sheet1',targetShName = 'Sheet2') => {
  const ss = SpreadsheetApp.getActiveSpreadsheet();

  const s1 = ss.getSheetByName(sourceShName);
  const s2 = ss.getSheetByName(targetShName);

  const s2lcol = s2.getLastColumn();

  //keep all vals from source to reduce I/O
  const s1DataVals = s1.getDataRange().getValues();

  const s2Vals = s2.getRange(1, 1, 1, s2lcol).getValues();

  const h1Vals = s1DataVals[0];
  const h2Vals = s2Vals[0];

  //assume s1 is source (validation) sheet
  //assume s2 is target sheet that a user can edit

  //case 1: target has value not present in source -> delete column in target
  let colIdx = 0;
  h2Vals.forEach(value => {
    const isOK = h1Vals.some(val => val===value);

    isOK ? colIdx++ : s2.deleteColumn(colIdx+1);
  });

  //case 2: target does not have values present in source -> append column from source
  h1Vals.forEach((value,index) => {
    const isOK = h2Vals.some(val => val===value);
    !isOK && s2.insertColumnAfter(index);

    const valuesToInsert = s1DataVals.map(row => [row[index]]);

    const numRowsToInsert = valuesToInsert.length;

    s2.getRange(1,index+1, numRowsToInsert,1).setValues(valuesToInsert);
  });

};
展示

以下是它作为宏的工作原理的小演示:

注释

  • 使用两个
    forEach
    解决您的问题是次优的,但我将I/O的数量保持在较低的水平(例如,将
    deleteColm
    移出循环,同时只跟踪列索引,可以进一步降低I/O的数量)
  • 该脚本使用V8提供的ES6功能,因此请小心(尽管我建议尽快迁移-即使您遇到错误/不一致,它的价值也超过了成本)
  • UPD通过将工作表名称移动到参数列表,使脚本更加灵活
  • UPD2在与
    deleteColumn()
    行为讨论了这个问题之后,答案被更新,以使列指针保持在范围内(对于那些对它好奇的人,
    forEach
    不断增加
    索引
    ,而
    deleteColumn
    减少了任何给定索引的范围)
  • 参考

  • insertColumnAfter()
    方法

  • 嗨@Smith O!你能澄清一下“独特”是什么吗值是指脚本上下文中的值?是否希望标题单元格值可配置,或仅删除表2中标题值与表1不同的列?我指的是不同的值,没有任何匹配项。例如,假设表1第1行数据和表2第1行是统一的,如果用户在任何表中添加/删除列,我希望始终将两张工作表中的列数与其值相匹配请共享工作表的图像根据请求添加的屏幕截图验证工作表是从不同的电子表格复制的,因此可能有更多的列。在这种情况下,我只需更新(插入新列)目标工作表。同样,如果验证工作表没有那么多列,那么目标工作表列应该与之匹配。我还没有测试过它,但这看起来已经很棒了。非常感谢,OlegHope这就是您正在寻找的内容-在示例电子表格上测试过,可能您需要根据您的需要调整它,但它应该很容易配置ble-如果您遇到任何问题,请告诉我。我假设它在您的数据集上运行良好?很高兴听到这样的消息-欢迎您,我们总是在这里提供帮助)我仍在测试中,但需要时我会调整或与您联系。我很高兴你能帮我吗?我一直从这行“const ss=SpreadsheetApp.getActiveSpreadsheet();”中得到“Invalid property Id”错误