【发布时间】:2020-07-27 10:34:10
【问题描述】:
我试图通过比较位于列中的Codes 与位于Database 表的列中的Codes 来查找添加到Data 表的NEW 行。我通过找出这两个代码之间的差异来做到这一点。
...
// Get Mappings array
let Maplist = shtMap.getRange(2, 1, r_Map - 1, 2).getValues();
// find new codes that have come in the Data sheet
let DataCodes = [...new Set(shtData.getRange(2, 1, r_Data - 1, 1).getValues().flat())];
let DatabaseCodes = [...new Set(shtDatabase.getRange(2, 2, r_Database - 1, 1).getValues().flat())];
let diff =[];
// ===> Below is the line I want to modify to incorporate all the logic given in my Notes section.
diff = DataCodes.reduce( (diff,x) => !DatabaseCodes.includes(x) ? [...diff, [x]] : diff, []);
// Map Emp name to diff Array ===> not working....getting error!
diff = diff.map(function(x, i , arr){
if(arr.indexOf(x) == i){
return [...diff, [arr[i][1]]);
}
}, (Maplist));
// Add Data Validation to `Status` column
var Rng = shtDatabase.getRange(r_Database + 1, 7, diff.length -1, 1);
Rng.clearDataValidations().clearContent();
var rule = SpreadsheetApp.newDataValidation().requireValueInList([`Open`,`Complete`], true).build();
Rng.setDataValidation(rule); // Update `Status` value
...
上面的代码给了我进入Database工作表的Difference i.e. new Codes。有没有办法修改上面的Reduce function code 以拉入entire new rows,以便diff Array 可以附加到Database 工作表的末尾?
注意:
-
这里
Database Sheet中的Delivery Date指的是Data Sheet中的FinalDate。是否可以修改上面的代码以考虑到不匹配的列名,使FinalDate列的值准确地放在Delivery Date列中? -
对于
diff array中的每个新行,我还需要将包含值Open,Complete的DataValidation dropdown添加到Database Sheet的Status Column中。上面的代码怎么会考虑到Data Validation code呢? -
如您所见,
Database Sheet中的matching columns不是连续的,并且与Data Sheet的顺序相同,而是分布在工作表中。是否可以修改代码以将每个 diff 数组值正确放入各自的列中? -
最后,我必须将
Database Sheet中的每个Owner名称与Mapping Sheet数组(其中包含Owner名称及其对应的Emp名称)进行比较,然后匹配其对应的Emp名称并将其添加到Database Sheet中的Emp列中。
原因:
- 我想在内存中完成这一切,最后一口气将这个内存数组转移到
Database Sheet。否则,重复访问(读/写)表格需要花费大量时间来运行代码,尤其是在数据很大的情况下。这可以通过一些简洁的代码实现吗?
这里是 [示例文件][4] 的链接。
[4]:
编辑: https://docs.google.com/spreadsheets/d/1DARGtbN8EyEKyF9ceuOusStvuPIXjUR_8OrqfhPxpNQ/edit?usp=sharing
@TheMaster,这是文件中编写的完整代码:
function myTest(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const shtData = ss.getSheetByName("Data");
const shtMap = ss.getSheetByName("Mapping");
const shtDatabase = ss.getSheetByName("Database");
// get Data Sheet unique list of Owners
let r_Data = FindLastRow(shtData);
let c_Data = FindLastColumn(shtData);
let list = shtData.getRange(2, 4, r_Data - 1, 1).getValues();
let Datalist = [...new Set(list.flat())];
// get Mapping Sheet unique list of Owners
r_Map = FindLastRow(shtMap);
c_Map = FindLastColumn(shtMap);
list = shtMap.getRange(2, 1, r_Map - 1, 1).getValues();
let Maplist = [...new Set(list.flat())];
// find new codes that have come in the Data sheet
r_Database = FindLastRow(shtDatabase);
c_Database = FindLastColumn(shtDatabase);
let DataCodes = [...new Set(shtData.getRange(2, 1, r_Data - 1, 1).getValues().flat())];
let DatabaseCodes = [...new Set(shtDatabase.getRange(2, 2, r_Database - 1, 1).getValues().flat())];
// find the difference between the 2 arrays and append the new ones to Mapping Sheet, then sort.
let diff = Datalist.reduce( (diff,x) => !Maplist.includes(x) ? [...diff, [x,'Unassigned']] : diff,[]);
if(diff.length !== 0){
shtMap.getRange(r_Map + 1, 1, diff.length, diff[0].length).setValues(diff);
}
// Sort the Mappings Sheet on 2nd column, then 1st column
shtMap.getDataRange().offset(1, 0, shtMap.getDataRange().getNumRows() - 1).sort([{column: 2, ascending: true}, {column: 1, ascending: true}]);
// diff =[];
// ===> Below is the line I want to modify to incorporate all the logic given in my Notes section.
diff = DataCodes.reduce( (diff,x) => !DatabaseCodes.includes(x) ? [...diff, [x]] : diff, []);
// From Notes : Map Emp name to diff Array ===> not working....getting error!
diff = diff.map( function(x, i, arr){
if(arr.indexOf(x) == i){
return [...diff, arr[1][i]];
}
}, (Maplist));
// From Notes : Add Data Validation to `Status` column
var Rng = shtDatabase.getRange(r_Database + 1, 7, diff.length -1, 1);
Rng.clearDataValidations().clearContent();
var rule = SpreadsheetApp.newDataValidation().requireValueInList([`Open`,`Complete`], true).build();
Rng.setDataValidation(rule); // Update `Status` value
}
function FindLastRow(sht) {
return sht.getRange(1,1).getDataRegion().getLastRow();
};
function FindLastColumn(sht) {
return sht.getRange(1,1).getDataRegion().getLastColumn();
};
编辑:
@Tanaike,我已经更新了帖子中的屏幕截图以及电子表格。例如Data 工作表中的黄色行是new rows,因此需要正确放置在Database 工作表中,并在Status 列中添加数据验证,Emp 名称在Emp 列中(匹配后@987654371 @ 带有映射表)。 Data 表中的FinalDate 列是Database 表中的Delivery Date 列。
我们的想法是创建一个简洁的代码,该代码将创建一个 2D 数组(应包括 datavalidation 和 Emp 名称),以将所有新数据正确放置在 Database 表中。我想避免每次都将数据写入工作表以更新Database工作表中的每一列。
【问题讨论】:
-
评论不用于扩展讨论;这个对话是moved to chat。
标签: google-apps-script google-sheets row reduce difference