用于将数据从网页提取到电子表格的 GAS,并将其与上次保存的数据进行检查



我有一个脚本:

  • 从网页获取数据
  • 将其粘贴到电子表格
  • 每天使用时间驱动的触发器执行

到目前为止,我有两个问题:

  1. 所需网页上的数据不会每天都刷新,我的问题是 是否可以进行一些脚本无法保存的调整 从网页到 SS 的数据,如果网页上的数据与上一个相同 保存?也许要测试从网页到最后一行 电子表格?怎么做?
  2. 第二个问题是执行脚本并保存所有数据 到 SS,但我收到以下消息:

"异常:数据中的列数与区域中的列数不匹配。数据有 1,但范围有 8。(第 115 行,文件"代码"(">

代码的第 115 行是:

eigenSheet.getRange(eigenRow, 1, eigenValues.length, eigenValues[0].length).setValues(eigenValues);

我认为问题可能是在网页上我有时有空行?这是一个问题还是其他问题以及如何解决它?

整个脚本代码在这里:

regularSheetName = "Regular method";
eigenSheetName = "EIGENVECTOR Analysis";
function updateSheet(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var regularSheet = ss.getSheetByName(regularSheetName);
var eigenSheet = ss.getSheetByName(eigenSheetName);
var date = Utilities.formatDate(new Date(), 'CET', "dd.MM.yyyy");
var content = UrlFetchApp.fetch("link").getContentText().split('======================================================================================================');
if(content.length<2){
return SpreadsheetApp.getUi().alert("Unable to fetch data.");
}
var strLines = content[1].split("n");
var regularValues = [];
var eigenValues = [];
var isRegular = true;
var ignore = false;
for(var i=1;i<strLines.length;i++){
var str = strLines[i];
if(str.length<10){
if(isRegular){
ignore = true;
}else{
continue;
}
}else if(str.indexOf("EFAVORITE")>-1){
ignore = false;
isRegular = false;
i++;
str = strLines[i];
}else if(str.indexOf("endfile")>-1){
ignore = true;
}
if(!ignore){
if(isRegular){
//process regular method rows
var lineSplit = str.split(" ");
var row = [date];
var curVal = "";
for(var j=0;j<lineSplit.length;j++){
if(lineSplit[j]===""){
continue;
}
if((row.length==1&&curVal==="")||(isWord(lineSplit[j])&&isWord(lineSplit[j-1]))){
if(curVal!=""){
curVal += " ";
}
curVal += lineSplit[j];
}else{
row.push(curVal);
curVal = lineSplit[j].replace(".", ",");
}
}
row.push(curVal);
regularValues.push(row);
}else{
//process eigen rows
var lineSplit = str.split(" ");
var row = [];
var curVal = "";
for(var j=0;j<lineSplit.length;j++){
if(lineSplit[j]===""){
continue;
}
if((row.length==0&&curVal==="")||(isWord(lineSplit[j])&&isWord(lineSplit[j-1]))){
if(curVal!=""){
curVal += " ";
}
curVal += lineSplit[j];
}else{
if(row.length==1&&curVal!="@"&&curVal!="N@"&&curVal!="N"){
row.push("");
}
if(row.length>0){
row.push(curVal);
}else{
row.push(date);
}
curVal = lineSplit[j].replace(".", ",");
}
}
if(row.length==6&&curVal!="@"){
row.push("");
}
row.push(curVal);
eigenValues.push(row);
}
}
}
//append to sheets
var regRow = regularSheet.getLastRow()+1;
regularSheet.getRange(regRow, 1, regularValues.length, regularValues[0].length).setValues(regularValues);
var eigenRow = eigenSheet.getLastRow()+1;
eigenSheet.getRange(eigenRow, 1, eigenValues.length, eigenValues[0].length).setValues(eigenValues);
}
function isWord(checkStr){
return (checkStr.indexOf("%")==-1 && checkStr!="@" && checkStr!="N@" && checkStr!="N" && isNaN(checkStr));
}

试试这个:

Range.getValues().filter(function(r){return r.join('').length;});//if r.join.length is zero the row is empty

补充答案

很久以前,我创建了一个实用程序来减少棘手情况下的调试时间,当必须将从一个源Range接收的一组值应用于另一个源时:

/**
* @summary checks if range can accept an array of values
* @param {GoogleAppsScript.Spreadsheet.Range} rng 
* @param {any[][]} values
* @returns {boolean}
*/
const checkBounds = (rng, values) => {
const targetRows = rng.getHeight();
const targetCols = rng.getWidth();
const { length } = values;
const [firstRow] = values;
return length === targetRows &&
firstRow.length === targetCols;
};

空行

除了 Cooper 的答案之外,您还可以利用构造函数在 false 值上返回 false 的事实Boolean()检查行是否为空(您必须小心,因为填充0s 的行也会被过滤掉(:

const isEmpty = (row) => row.every(Boolean);

或者只使用内置的方法服务isBlank()方法

最新更新