Google 工作表脚本,每个函数与 && 运算符结合并设置值范围以检查数组

Google sheets script, Every function combined with && operator and setting range of values to check array against

跟进

我几乎是在尝试复制我用来通知用户“坏”数据的条件格式,但使用脚本来防止发送坏数据和给出独特的错误消息。根据我上一个问题的答案,检查和防止不发送任何数据或重复的数据是有效的,但我现在坚持防止发送与四位数格式不匹配的数据。

我的条件格式是将不等于或介于 1000 和 9999 之间的任何值的背景颜色设置为橙色,但我无法让脚本正常工作——我正在尝试使用否定将这两个值之间的任何值设置为“false”,将提示错误消息,将“true”设置为让脚本的其余部分 运行 发送数据和通知电子邮件。但是,这意味着即使我确实输入了正确的数据,也有错误的值。删除否定会让任何事情都通过,就像它实际上并没有检查它一样。有什么想法吗?

我要问的部分是最后一个 else if 语句:

else if (!data.every(function(num) {return num >= 1000 && num <= 9999})) {
    SpreadsheetApp.getUi().alert("You have incorrectly formatted tallies, tallies must be four digits.", SpreadsheetApp.getUi().ButtonSet.OK);
  }

总代码如下。

 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var ssSheet = ss.getActiveSheet();

//https://techyesplease.com/code/google-apps-script-find-duplicates-sheets/
function readData() {
  var dataColumn = 3;
  var firstRow = 6;
  var lastRow = ssSheet.getLastRow();
  var numRows = lastRow - firstRow + 1;
  var columnRange = ssSheet.getRange(firstRow, dataColumn, numRows);
  //var rangeArray = columnRange.getValues();
  // Convert to one dimensional array
  //rangeArray = [].concat.apply([], rangeArray);
  var rangeArray = columnRange.getValues().flat().filter(String);
  return rangeArray;
}

// Sort data and find duplicates
function findDuplicates(dataAll) {
  var sortedData = dataAll.slice().sort();
  var duplicates = [];
  for (var i = 0; i < sortedData.length - 1; i++) {
    if (sortedData[i + 1] == sortedData[i]) {
      duplicates.push(sortedData[i]);
    }
  }
  return duplicates;
}

//Use the same string for this variable as the name for the requestor for his or her column of data. E.g., John Doe
//****GLOBALS****

var targetSheet = 'All Tallies'; //replace with sheet/tab name
var targetSpreadsheetID = 'id'  //replace with destination ID
var targetURL = 'url'

//var dataNotificationReceivingEmailAddresses = 
//Set up to be able to easily change what emails the data notification goes to?

function sendDataAndTimestamp2() {

 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var ssSheet = ss.getActiveSheet();
 var sourceRange = ssSheet.getRange('C6:C401');  
//assign the range you want to copy, could make C6:C? No, would like dynamic.
 var data = sourceRange.getValues();

 var nameRange = ssSheet.getRange('C4:D4');
 var nameValue = nameRange.getDisplayValue();


 var tallyDateRange = ssSheet.getRange('C2');
 var tallyDateValue = tallyDateRange.getDisplayValue();
 var tallyDateText = 'Tallies to run on '+ tallyDateValue;


 var tallyAmountRange = ssSheet.getRange(8,1);
 var tallyAmount = tallyAmountRange.getDisplayValue();
 var tallyAmountNumberOnly = data.filter(String).length; 
//Used as tallyAmount includes text, for some cases need the number only
 
 var thisDocumentUrl = ss.getUrl();
  //Variables for the sending/source spreadsheet above


 //Initial confirmation alert, need checks for blank or error tallies first. First condition needs to loop through data variable and check that if any values are numbers not between 1000 and 9999, throw up Ui alert error message. Second condition goes to result variable?

//Reference the earlier functions
  var dataArray = readData();
  var duplicates = findDuplicates(dataArray);

//Need to check data and have error message if  duplicates.length >=1, if 0 allow, refuse if data length less than 1
  if (duplicates.length !== 0) {
SpreadsheetApp.getUi().alert("Your tallies include duplicates, please remove them then try again.", SpreadsheetApp.getUi().ButtonSet.OK);
Logger.log(duplicates);
  }
  else if (dataArray.length ===0) {
    SpreadsheetApp.getUi().alert("You have not input any tallies.", SpreadsheetApp.getUi().ButtonSet.OK);
  }

  else if (!data.every(function(num) {return num >= 1000 && num <= 9999})) {
    SpreadsheetApp.getUi().alert("You have incorrectly formatted tallies, tallies must be four digits.", SpreadsheetApp.getUi().ButtonSet.OK);
  }

/*https://www.youtube.com/watch?v=gaC290XzPX4&list=PLv9Pf9aNgemvD9NFa86_udt-NWh37efmD&index=10
Every method
var arr = [1,2,3,4];
var allTalliesGood = data.every(function(num){
    return num < 9
});
//Use with num >= 1000, num <=9999, and then if true continue, if false stop and give error msg
*/




/*
dataFiltered = data.filter(filterlogic);

var filterlogic = function(tally){
  if (tally >= 1000 && tally <= 9999){
    return true;
  } else {
    return false
    }
}
//if use false for good tallies, and rename dataFiltered to something like "dataBad", then check if dataBad has true matches in it...
//need to check for strings? what happens if letters/symbols in tally range?
//var dataBad = data.filter(function(tally){ return tally < 1000 || tally > 9999;});
// use OR (||) for getting tallies great than or less than, what about letters/symbols? Use NOT good range?

//https://www.youtube.com/watch?v=hPCIOohF0Fg&list=PLv9Pf9aNgemvD9NFa86_udt-NWh37efmD&index=8
//sort method link above
*/



  else {
//    rest of code
  


  var result = SpreadsheetApp.getUi().alert("You're about to notify scheduler of the following number of tallies: " + tallyAmountNumberOnly, SpreadsheetApp.getUi().ButtonSet.OK_CANCEL);


  if(result === SpreadsheetApp.getUi().Button.OK) {
    //Code to send out emails and data

据我所知,在函数 sendDataAndTimestamp2() 中,您需要删除 data 中的空值。可以用filter(String)方法完成:

var data = sourceRange.getValues().filter(String); // <-- here

. . .

else if (!data.every(function(num) {return num >= 1000 && num <= 9999}))

. . .

或者,我不知道,也许你的意思是 dataArray 而不是 data:

else if (!dataArray.every(function(num) {return num >= 1000 && num <= 9999}))

顺便说一句,这条线可以缩短一点:

else if (!data.every(x => (x >= 1000) && (x <= 9999)))