CSV转换脚本到Google工作表格式的行为不正确

r6vfmomb  于 2022-12-15  发布在  Go
关注(0)|答案(1)|浏览(126)

我,目前使用这个自动脚本自动转换成谷歌格式的动态csv表,为进一步修改。

function importCSVFromGoogleDrive() {
  var file = DriveApp.getFilesByName('Inventory.csv').next();
  var csvData = Utilities.parseCsv(file.getBlob().getDataAsString());
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
}

然而,尽管脚本在大多数情况下都能正常工作,但偶尔它会添加行的副本,而不是替换初始数据,从而导致重复。
这是数据应该是这样的:

House Number   Color   Family  Complaints 
 22             Red     Smiths  4
 A65            Blue    Stefans 5 
 18             Yellow  Dolmens 2

在perfect world中,每次激活脚本时,它都会从动态csv中拉取数据并替换现有数据。
然而,偶尔经过一天的脚本工作每分钟或5分钟。我发现它在这种状态:

House Number    Color   Family  Complaints 
   22           Red     Smiths  4
   A65          Blue    Stefans 5 
   18           Yellow  Dolmens 2 
   22           Red     Smiths  4 
   A65          Blue    Stefans 5 
   18           Yellow  Dolmens 2 
   22           Red     Smiths  5 
   A65          Blue    Stefans 5 
   18           Yellow  Dolmens 3

正如您所看到的,它不是修改现有的行,而是偶尔为数据创建新的行集,现在这种情况很少发生,因为在每5分钟运行一次脚本之后,我可能只有4-5个额外的行集。
你会注意到在这个例子中,最后一组行中的数据是变化的,这只是为了说明由于动态csv的特性,数据会发生变化。但是,它应该覆盖原来的数据,而不是创建新的行集。
什么才是正确的解决办法呢?

f87krz0w

f87krz0w1#

不知道为什么会失败,但也许这就是解决办法,所以我们自己解析csv。
splitCsv()函数来自SO中的另一个帖子。我似乎找不到它...

function importCSVFromGoogleDrive() {
  const file = DriveApp.getFilesByName('Inventory.csv').next();
  const csv = file.getBlob().getDataAsString()
  const csvData = csv.split("\n").map(row => splitCsv(row));
  const sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
}

/**
 * Splits the csv line to columns and escaping the comma's inside double qoutes.
 * @param {string} str the csv line string.
 * @returns {array} array of columns
 */
function splitCsv(str) {
  return str.split(",").reduce(
    (acc, cur) => {
      if (acc.isConcatting) {
        acc.soFar[acc.soFar.length - 1] += "," + cur;
      } else {
        acc.soFar.push(cur);
      }
      if (cur.split('"').length % 2 == 0) {
        acc.isConcatting = !acc.isConcatting;
      }
      return acc;
    },
    { soFar: [], isConcatting: false }
  ).soFar;
}

相关问题