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

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

我正在寻找一种方法来比较这两张纸,而不硬编码任何列范围。我认为最有效的方法是在两个工作表中查找列标题名称,然后检查对"Case Number“行的更改。如果你能想出更好的办法,请告诉我。
我已经成功地编写了一段代码来查看标题,并为特定的列名"Case Number“标识索引号。这一列将始终存在于两个工作表中,它可以作为应该验证的行的参考点,但它可以是每个工作表一次的不同行。我将需要同样的时间循环从案例表的所有列标题,并检查从导入表的更新。
我只需要检查/循环对案例表中的几个特定列的更改。列名如下:联系人名称、标题、优先级、状态。
我的目标是取得三种可能的结果:



我为冗长的问题陈述道歉。
我是JS和GAS的新手,我写了这篇文章,希望一些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;
}发布于 2021-06-22 17:58:58
使所有这些处理变得更容易的一种方法是重新排序列,使它们始终位于相同的位置,如下所示:
=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) )
看看你的样本电子表格。
https://stackoverflow.com/questions/67994556
复制相似问题