[英]Google Apps Script Sheets PasteDataRequest paste to column instead of row?
[英]Google Apps Script - Compare two sheets for changes by column names instead of hardcoded ranges
我有兩張紙,“進口”和“案例”。
在“導入”表中,我從有時有更多列或現有列每次以不同方式排列的外部源導入數據。
在“案例”表中,這是我存儲上周所有導入數據的每周快照的地方,我添加了包含更多信息的附加列,例如評論、后續步驟等。
我正在尋找一種方法來比較兩個工作表而不對任何列范圍進行硬編碼。 我認為最有效的方法是在兩張表中查找列 header 名稱,然后檢查參考“案例編號”行的更改。 如果您能想到更好的方法,請告訴我。
我已經設法編寫了一個代碼來查看標題並識別特定列名“案例編號”的索引號。 此列將始終出現在兩個工作表中,它可以作為應該驗證的行的參考點,但它可能是每張工作表的不同行。 我將需要同時遍歷 CASES 表中的所有列標題並檢查 IMPORT 表中的更新。
我只需要檢查/循環 CASES 表中幾個特定列的更改。 列名稱,例如:聯系人姓名、職務、優先級、狀態。
我的目標是實現 3 個可能的結果:
對於冗長的問題陳述,我深表歉意。
我是 JS 和 GAS 的新手,我寫這篇文章是希望一些 JavaScript 專家能理解我的想法並建議可能更簡單的方法來完成我的項目。
目前,我一直在尋找一種正確的方法來循環遍歷 Header 名稱,然后檢查 IMPORT 表中的單元格值,並根據 Case Name 值/行將其與 CASES 表進行比較。
我會繼續更新這個話題,展示這個項目的最新進展。 到目前為止,我在 Internet 上找到的所有示例都是基於單元格和列的硬編碼范圍。 我認為我的方法很有趣,因為它為數據集提供了面向未來的靈活性。
請讓我知道您的想法或想法,以獲得更直接的方法:)
更新代碼:
// 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;
}
使所有這些處理更容易的一種方法是重新排序列,以便它們始終位於同一個位置,如下所示:
=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)) )
...並像這樣打開案例:
=filter( 'CASES normalized':A2;G: match('CASES normalized';C2:C; 'IMPORT normalized'!C2:C; 0) )
請參閱您的示例電子表格。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.