google-apps-script - 查询 2 组表格数据并找出差异
问题描述
我正在尝试使用 Apps 脚本来查询 2 个数据集并比较它们之间的某些列。我希望...
a)识别缺失的 ID 值;
b)当 ID 值匹配时,协调其他字段的差异。
输入:
带有 2 个选项卡(tab1、tab2)的电子表格。
每个 B 列中的键 ID (Btab1, Btab2)
我想识别唯一值 (B) 在一个数据集中但不在另一个数据集中的实例(行的顺序不同)
如果 Btab1 不在 tab2 中,则运行函数并推送到输出选项卡 || Btab2 不在 tab1 中
当 B 的值在两个选项卡中时(大部分时间),我想在几列中识别数据差异的实例......
对于 B 的所有实例,将 B 和下面的相关列推到输出选项卡,如果...
- tab1 中的列 M 与 tab2 中的列 E 不匹配
- tab1 中的 P 列 <> tab2 中的 F 列
- AN 列 tab1 <> G 列 tab2
输出:显示数据集中问题区域的选项卡。
第一列是 ID 密钥。
第二列通过文本字符串解释问题
同样,这里的挑战是值的排序不同,总 # 行可能略有不同
function compare() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.insertSheet(1);
ss.getActiveSheet().setName('output');
var sheet1 = ss.getSheetByName('sheet1');
var sheet2 = ss.getSheetByName('sheet2');
var sheet_output = ss.getSheetByName('output');
var range1 = sheet1.getRange(1,1,sheet1.getLastRow(),sheet1.getLastColumn()).getValues();
var output1 = [];
var a1;
var b1;
var h1;
var i1;
var j1;
var m1;
var o1;
var p1;
var an1;
var ao1;
var x;
var range2 = sheet2.getRange(1,1,sheet2.getLastRow(),sheet2.getLastColumn()).getValues();
var output2 = [];
var a2;
var b2;
var c2;
var d2;
var e2;
var f2;
var g2;
var h2;
var y;
/// can i do for(x in range1; y in range2) { all in one function?? If so, what is the proper syntax?
for(x in range1, y in range2) {
a1 = range1[x][0];
b1 = range1[x][1];
h1 = range1[x][7];
i1 = range1[x][8];
j1 = range1[x][9];
m1 = range1[x][12];
o1 = range1[x][14];
p1 = range1[x][15];
an1 = range1[x][39];
ao1 = range1[x][40];
a2 = range2[y][0];
b2 = range2[y][1];
c2 = range2[y][2];
d2 = range2[y][3];
e2 = range2[y][4];
f2 = range2[y][5];
g2 = range2[y][6];
h2 = range2[y][7];
if (
(b1 != b2) ||
(m1 != e2) // etc etc etc
)
{
//push to output
}}
解决方案
虽然您的语法for(x in range1, y in range2)
不会返回错误,但如果行的顺序不同,它也不会为您提供所需的结果
原因:
在每次迭代期间x
和y
都会发生变化,例如 ifvar range1 = [1,2,3]
和var range2 = [4,5,6]
,您的循环将迭代 3 次,并且您的示例循环迭代中的值将是:
- 迭代
range1[x] = 1
和range2[y] = 4
- 迭代
range1[x] = 2
和range2[y] = 5
- 迭代
range1[x] = 3
和range2[y] = 6
在这种情况下,您将不会检索组合
range1[x] = 1
和range2[y] = 4
或者
range1[x] = 2
和range2[y] = 6
等等。
相反,您需要使用两个嵌套的 for 循环,这将遍历和的所有可能x
组合y
:
for(x in range1) {
for(y in range2){
...
}
}
边注:
即使您的行顺序相同,您仍然需要小心。因为for(x in range1)
反对for(x = 0; x < range1.length; i++)
让您无法控制循环将在哪个文件夹中迭代范围。
现在查询重复项
以不太复杂的方式实现功能的可能方法如下:
- 定义布尔变量并使用它来检查每个
x
是否有重复 - 如果发现重复(对于 B 列) - 将评估进一步的标准
- 如果两行符合所有条件,内部循环将退出,
break
函数将跳转到下一个x
- 如果发现具有相同键 ID 的行,但在其他列中存在差异 - 这两行都将被推入工作表
output
中以进行比较(这比指定确切的差异更容易实现) - 在此之后,内部循环也将退出
- 在上述其他情况下,
duplicate
将设置为true
- 如果在 sheet1 中找到唯一 ID(重复 = false) - 它将立即被推入
output
样本
function compare() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.insertSheet(1);
ss.getActiveSheet().setName('output');
var sheet1 = ss.getSheetByName('sheet1');
var sheet2 = ss.getSheetByName('sheet2');
var sheet_output = ss.getSheetByName('output');
var range1 = sheet1.getRange(1,1,sheet1.getLastRow(),sheet1.getLastColumn()).getValues();
var output1 = [];
var b1;
var m1;
var p1;
var an1;
var x;
var range2 = sheet2.getRange(1,1,sheet2.getLastRow(),sheet2.getLastColumn()).getValues();
var output2 = [];
var b2;
var e2;
var f2;
var g2;
var y;
var array = [];
for(x in range1) {
var duplicate = false;
for(y in range2){
b1 = range1[x][1];
m1 = range1[x][12];
p1 = range1[x][15];
an1 = range1[x][39];
b2 = range2[y][1];
e2 = range2[y][4];
f2 = range2[y][5];
g2 = range2[y][6];
if (
(b1 == b2)
)
{
Logger.log("found");
duplicate = true;
if((m1 != e2)||
(p1 != f2) ||
(an1 != g2)){
array.push(range1[x]);
array.push(range2[y]);
}
break;
}
}
if (duplicate == false){
Logger.log("duplicate false");
array.push(range1[x]);
}
}
//push to output
if(array[0]){
sheet_output.getRange(sheet_output.getLastRow()+1, 1, array.length, array[0].length).setValues(array);
}
}
推荐阅读
- angular - 为什么我的 Angular 6 页面无法加载
- c++ - 使用 void 指针从 c 函数调用模板化成员
- javascript - jquery 多语种语言切换器 js
- sql - SQL 三表连接
- symfony - 在 Symfony2 中,有没有办法判断请求/响应何时完成?
- assembly - “迭代”在“性能报告 -b --branch-history”(性能记录 -b -g)中是什么意思
- mule - 如何在 mule 中使用 dw() 函数对 arraylist 进行 Null 和空检查?
- c++ - vector push_back() 给出编译器错误 C2280
- c# - 面向客户的 API 的依赖注入
- javascript - 在 content.js(Chrome 扩展程序)中发生操作时如何检查 popup.html 页面?