首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Google脚本-根据列名而不是硬编码范围比较两个工作表

Google脚本-根据列名而不是硬编码范围比较两个工作表
EN

Stack Overflow用户
提问于 2021-06-15 23:21:57
回答 1查看 427关注 0票数 0

我有两张纸,“进口”和“箱子”。

在“导入”表中,我从外部源导入数据,这些外部源有时有更多的列,或者每次都以不同的方式排列现有列。

在“案例”表中,我存储上周所有导入数据的每周快照,并添加包含更多信息的附加列,如注释、下一步步骤等。

我正在寻找一种方法来比较这两张纸,而不硬编码任何列范围。我认为最有效的方法是在两个工作表中查找列标题名称,然后检查对"Case Number“行的更改。如果你能想出更好的办法,请告诉我。

我已经成功地编写了一段代码来查看标题,并为特定的列名"Case Number“标识索引号。这一列将始终存在于两个工作表中,它可以作为应该验证的行的参考点,但它可以是每个工作表一次的不同行。我将需要同样的时间循环从案例表的所有列标题,并检查从导入表的更新。

我只需要检查/循环对案例表中的几个特定列的更改。列名如下:联系人名称、标题、优先级、状态。

我的目标是取得三种可能的结果:

  1. 在导入表中没有找到来自案例单的 "Case Number“--这意味着案件自上周以来就已经结案。Action:将案例表中的整行突出显示为灰色(这将表明大小写不再打开,确认后应从列表中删除)。

  1. 导入表中的“案例编号”没有在案例表中找到--这意味着案例是新的,需要添加到底部的案例表中。Action:将数据从导入表复制到CASES工作表,并将其粘贴到底部的正确列中,并将整行高亮显示为绿色,以指示新的数据输入。对于导入表中的CASES工作表中的所有不存在列,应该跳过这些列。

  1. 从导入表中的"Case Number“在Case sheet中找到了-对于匹配的案例编号记录,我需要验证自上周以来是否在任何Case sheet列中有任何更改。Action:如果在任何单元格中发现了更改,则在案例表中使用新的数据更新单元格,并将单元格背景颜色更改为黄色,以突出显示已更新的单元格。对于没有更改的单元格,跳过。

我为冗长的问题陈述道歉。

我是JS和GAS的新手,我写了这篇文章,希望一些JavaScript专家能理解我的想法,并给出更简单的方法来完成我的项目。

目前,我一直在寻找一种正确的方法来遍历头名,然后从导入表中检查单元格值,并根据大小写名称/行将其与案例表进行比较。

  • 结果1-已完成的
  • 成果2-正在进行中
  • 结果3-tbd.

我将继续更新这一主题,以显示该项目的最新进展。到目前为止,我在互联网上发现的所有例子都是基于单元格和列的硬编码范围。我认为我的方法很有趣,因为它为数据集提供了未来证明的灵活性。

请让我知道你对更直截了当的方法的想法或想法:)

链接到活动工作表

更新代码:

代码语言:javascript
运行
复制
// Create Top Menu
function onOpen() {
  let ui = SpreadsheetApp.getUi();
  ui.createMenu('>> REPORTS <<').
  addItem('Highlight Closed Cases', 'closedCases').
  addItem('Check for new Cases', 'addCases').addToUi();
}

// IN PROGRESS (Outcome 2) - Add and highlight new cases in CASES sheet
function addCases() {

  let ss = SpreadsheetApp.getActiveSpreadsheet();

  // Get column index number for Case Number
  let activeImportCol = getColumnIndex("Case Number", "IMPORT");
  let activeCasesCol = getColumnIndex("Case Number", "CASES");

  let importHeaders = loadHeaderNames("IMPORT");
  let casesHeaders = loadHeaderNames("CASES");

  // Load Case Number columns values into array
  let loadImportValues = getColumnValues("Case Number", "IMPORT");
  let loadCasesValues = getColumnValues("Case Number", "CASES");
  // Convert to 1D array
  let newImportValues = loadImportValues.map(function (row) { return row[0]; });
  let newCasesValues = loadCasesValues.map(function (row) { return row[0]; });

  // Get number of columns
  var numImportCol = ss.getSheetByName("IMPORT").getLastColumn();

  // Loop through IMPORT sheet "Case Number" column to find new Case Numbers - execute OUTCOME 3 or 2
  for (var line in newImportValues) {
    var isMatched = newCasesValues.indexOf(newImportValues[line]);
    if (isMatched !== -1) {
      

      // "Case Number" from the IMPORT sheet WAS FOUND in the CASES sheet - EXECUTE OUTCOME 3
      // ****************************************************************************************
      // For the matching Case Number records, I need to validate if there were any changes in any CASES sheet columns since last week
      // Action: If a change was found in any of the cells, update the cell with new data in CASES sheet 
      // and change the cell background colour to yellow to highlight the cell was updated. For cells without changes, skip.

      
    } else {
      
      // "Case Number" from the IMPORT sheet was NOT FOUND in the CASES sheet - EXECUTE OUTCOME 2
      // ****************************************************************************************
      // Copy the new data row from the IMPORT sheet to the CASES sheet and paste it in the correct columns 
      // at the bottom and highlight the entire row as green to indicate a new data entry.
      // For all non-existing/not matching column names in the CASES sheet that are not in IMPORT sheet, those should be skipped.
      
    }
  }
}

// COMPLETED (Outcome 1) - Highlight entire row grey for missing values in CASES sheet
function closedCases() {

  var ss = SpreadsheetApp.getActiveSpreadsheet();

  // Load all Casen Number columns values into array
  var importValues = getColumnValues("Case Number", "IMPORT");
  var casesValues = getColumnValues("Case Number", "CASES");

  // Convert to 1D array
  var newImportValues = importValues.map(function (row) { return row[0]; });
  var newCasesValues = casesValues.map(function (row) { return row[0]; });

  // Get column index number for Case Number
  var activeCol = getColumnIndex("Case Number", "CASES");

  // Get number of columns
  var numCol = ss.getSheetByName("CASES").getLastColumn();

  // Loop though CASES "Case Number" column and highlight closed cases (not found in IMPORT tab)
  for (var line in newCasesValues) {
    var isMatched = newImportValues.indexOf(newCasesValues[line]);
    if (isMatched !== -1) {

      // If found then...
      ss.getSheetByName("CASES").getRange(+line + 2, 1, 1, numCol).setBackground(null);

    } else {
      // Higlight row with missing cases - grey
      ss.getSheetByName("CASES").getRange(+line + 2, 1, 1, numCol).setBackground("#d9d9d9");
    };
  }
}

// Load column values
function getColumnValues(label, sheetName) {

  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);

  // Get column number for Case Number
  var colIndex = getColumnIndex(label, sheetName);

  // Get number of rows in Case Number
  var numRows = ss.getLastRow() - 1;

  // Load Case Number values into array
  var colValues = ss.getRange(2, colIndex, numRows, 1).getValues();

  return colValues;

}

// Load column header names
function loadHeaderNames(sheetName) {

  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);

  let HeaderArray = ss.getRange(1, 1, 1, ss.getLastColumn()).getValues()[0];
  let colidx = {};
  HeaderArray.forEach((h, i) => colidx[h] = i);

  return HeaderArray;

}

// Get column name index value
function getColumnIndex(label, sheetName) {

  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);

  // Find last column
  var lc = ss.getLastColumn();

  // Load headers into array
  var lookupRangeValues = ss.getRange(1, 1, 1, lc).getValues()[0];

  // Search for label and return the column number
  var index = lookupRangeValues.indexOf(label) + 1;

  return index;

}
EN

回答 1

Stack Overflow用户

发布于 2021-06-22 17:58:58

使所有这些处理变得更容易的一种方法是重新排序列,使它们始终位于相同的位置,如下所示:

代码语言:javascript
运行
复制
=arrayformula( 
  iferror( 
    vlookup( 
      hlookup("Case Number"; IMPORT!A1:G; row(IMPORT!A2:G); false); 
      { 
        hlookup("Case Number"; IMPORT!A1:G; row(IMPORT!A1:G); false) \ 
        IMPORT!A1:G 
      }; 
      match(IMPORT!A1:G1; CASES!A1:G1; 0) + 1; 
      false 
    ) 
  ) 
)

该公式将重新排序IMPORT中的列,以便这些列与CASES!A1:G1中列出的列的顺序相同。

然后,您可以使用更多的公式或脚本函数来处理数据,确信特定类型的数据总是在同一列中。例如,您可以使用以下内容列出已结案的案件:

=filter( 'CASES normalized'!A2:G; isna(match('CASES normalized'!C2:C; 'IMPORT normalized'!C2:C; 0)) )

...and打开的案例如下:

=filter( 'CASES normalized'!A2:G; match('CASES normalized'!C2:C; 'IMPORT normalized'!C2:C; 0) )

看看你的样本电子表格

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67994556

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档