0

我一直在使用 Google 提供的脚本从 Google 表格生成和发送 CSV。我对其进行了自定义,使其不要求范围或文件名。这样,它会定期自动向我发送电子邮件,其中包含我的范围内的内容。

问题是 CSV 最后包含空行,我希望脚本自动过滤掉这些行(我无法实现,因为我只是没有知识)。反过来,这样做的原因是该范围包含空行 - 但有一个很好的理由,即范围中的行有时会扩展,有时会收缩,具体取决于基础数据。(该范围实际上与数据透视表有关)。

作为奖励,如果行中的两列中的任何一列中有一个零,我也非常希望它跳过行。(我应该能够在数据透视表中过滤掉它;我可以,但是如果出现新值,过滤器将无法正常工作)。

这是我通过电子邮件发送的 CSV 目前正在查看的示例:

0,0
,0
0.65,0
0.75,16900
0.78,2000
0.79,500
0.8,110800
0.83,1200
0.85,20000
0.87,4500
0.9,3500
1,5000
1.1,4000
1.2,41500
,
,
,
,
,
,
,
,
,
,
,
,
,
,

这是我希望如何接收该 CSV 的示例:

0.75,16900
0.78,2000
0.79,500
0.8,110800
0.83,1200
0.85,20000
0.87,4500
0.9,3500
1,5000
1.1,4000
1.2,41500

对此的任何帮助将不胜感激。谢谢。

这是我目前使用的脚本:

var settings = {
  "recipients": "myemailaddress",
  "emailSubject": "CSV file",
  "emailMessage": "Your CSV file is attached",
  "fileExtension": ".csv",
  "carriageReturn": "\r\n"
};

function onOpen() {
  var subMenus = [];
  subMenus.push({name: "Email Named Range as CSV", functionName: "run"});
  SpreadsheetApp.getActiveSpreadsheet().addMenu("CSV", subMenus);
}

function run() {
  /var namedRange = Browser.inputBox("Enter named range to convert to CSV (e.g. sampleDataRange):");/
  var namedRange = "FORCSVEXPORT";
  var fileName = "EPCSELLOFFERS.CSV";

  if (namedRange.length !== 0 && fileName.length !== 0) {  
    settings.dataRangeName = namedRange;
    settings.csvFileName = fileName + settings.fileExtension;
    var csvFile = convertNamedRangeToCsvFile_(settings.dataRangeName, settings.csvFileName);
    emailCSV_(csvFile);
  }
  else {
    Browser.msgBox("Error: Please enter a named range and a CSV file name.");
  }
}

function emailCSV_(csvFile) {
  MailApp.sendEmail(settings.recipients, settings.emailSubject, settings.emailMessage, {attachments: csvFile});
}

function convertNamedRangeToCsvFile_(rngName, csvFileName) {
  var ws = SpreadsheetApp.getActiveSpreadsheet().getRangeByName(rngName);
  try {
    var data = ws.getValues();
    var csvFile = undefined;

    if (data.length > 1) {
      var csv = "";
      for (var row = 0; row < data.length; row += 1) {
        for (var col = 0; col < data[row].length; col += 1) {
          if (data[row][col].toString().indexOf(",") != -1) {
            data[row][col] = "\"" + data[row][col] + "\"";
          }
        }

        // Join each rows columns
        // Add carriage return to end of each row
        csv += data[row].join(",") + settings.carriageReturn;
      }
      csvFile = [{fileName: csvFileName, content: csv}];
    } 
    return csvFile;
  }
  catch(err) {
    Logger.log(err);
    Browser.msgBox(err);
  }
}
4

1 回答 1

1

convertNamedRangeToCsvFile_()我建议在您的 中添加一个额外的步骤,而不是破解原始run()文件,这将调用一个新函数来从 csv 文件中删除不需要的行。这里是:

/**
 * Remove unwanted lines from given csvFile
 */
function minimizeCsvFile( csvFile ) {
  // take apart the csv file contents, into an array of rows
  var rows = csvFile[0].content.replace(/\r\n/g, "\n").split("\n");
  var newRows = [];
  for (var i = 0; i < rows.length; i++ ) {
    if (rows[i] == "") continue;   // skip blanks
    if (rows[i] == ",") continue;  // skip null values
    // skip rows with either numeric value == 0
    var vals = rows[i].split(",");
    if (parseFloat(vals[0]) == 0.0 || parseFloat(vals[1]) == 0.0) continue;
    // If we got here, we have a keeper - add it to newRows
    newRows.push(rows[i]);
  }
  debugger;   // pause to observe in debugger
  var csv = newRows.join(settings.carriageReturn);
  // Return a single element array with an object, exactly like
  // the one from convertNamedRangeToCsvFile_.
  return [{fileName: csvFile[0].fileName, content: csv}];
}

要使用它,请将emailCSV_()行更改run()为:

var minimizedCsvFile = minimizeCsvFile(csvFile);
emailCSV_(minimizedCsvFile);

而至于这个...

作为奖金...任何对此的帮助将不胜感激。谢谢。

我们在这里想要的只是让 StackOverflow 的新成员在收到帮助时确认!查看此答案以获取有关如何接受答案的提示。(您可以通过提问、回答和接受答案来建立代表!)

但我一直想要一辆法拉利...

于 2013-04-12T20:10:49.563 回答