【问题标题】:Google Apps Script Auto Duplicate Sheets between conversion of Excel to Google SheetsGoogle Apps 脚本在将 Excel 转换为 Google 表格之间自动复制表格
【发布时间】:2019-02-11 07:42:49
【问题描述】:

我是编码游戏的新手,每天都在学习如何编码。 最近迷上了 Google App Script,学习制作一个简单的数据库。 我试图对脚本进行解码和重新编码,但我就是无法让它工作。它应该转换和替换现有的 google 表格,而不是脚本只是将 excel 转换并复制到原始 excel 文件中的多个版本(1、2、3)的表格中。

// Convert the user's stored excel files to google spreadsheets based on the specified directories.
// There are quota limits on the maximum conversions per day: consumer @gmail = 250.
function convertCollection1() 
{
  var user = Session.getActiveUser(); // Used for ownership testing.
  var origin = DriveApp.getFolderById("1dPsDfoqMQLCokZK4RN0C0VRzaRATr9AN");
  var dest = DriveApp.getFolderById("1M6lDfc_xEkR4w61pUOG4P5AXmSGF1hGy");

  // Index the filenames of owned Google Sheets files as object keys (which are hashed).
  // This avoids needing to search and do multiple string comparisons.
  // It takes around 100-200 ms per iteration to advance the iterator, check if the file
  // should be cached, and insert the key-value pair. Depending on the magnitude of
  // the task, this may need to be done separately, and loaded from a storage device instead.
  // Note that there are quota limits on queries per second - 1000 per 100 sec:
  // If the sequence is too large and the loop too fast, Utilities.sleep() usage will be needed.
  var gsi = dest.getFilesByType(MimeType.GOOGLE_SHEETS), gsNames = {};
  while (gsi.hasNext())
  {
    var file = gsi.next();
    if(file.getOwner().getEmail() == user.getEmail())
      gsNames[file.getName()] = true;
  }

  // Find and convert any unconverted .xls, .xlsx files in the given directories.
  var exceltypes = [MimeType.MICROSOFT_EXCEL, MimeType.MICROSOFT_EXCEL_LEGACY];
  for(var mt = 0; mt < exceltypes.length; ++mt)
  {
    var efi = origin.getFilesByType(exceltypes[mt]);
    while (efi.hasNext())
    {
      var file = efi.next();
      // Perform conversions only for owned files that don't have owned gs equivalents.
      // If an excel file does not have gs file with the same name, gsNames[ ... ] will be undefined, and !undefined -> true
      // If an excel file does have a gs file with the same name, gsNames[ ... ] will be true, and !true -> false
      if(file.getOwner().getEmail() == user.getEmail() && !gsNames[file.getName()]
      {
        Drive.Files.insert (
          {title: file.getName(), parents: [{"id": dest.getId()}]},
          file.getBlob(),
          {convert: true}
        );
        // Do not convert any more spreadsheets with this same name.
        gsNames[file.getName()] = true;
      }
    }
  }
}

【问题讨论】:

    标签: javascript excel google-apps-script google-drive-api google-sheets-api


    【解决方案1】:

    脚本的逻辑是正确的。但是,您使用的函数 .getName()Drive.Files.insert 存在一些细微的问题,这会导致代码中出现意外行为。

    folder.getName() 获取文件的全名,其中包括 .xls/.xlsx 扩展名。但是,当您使用 Drive.Files.insert 转换这些文件时,将删除扩展名。因此,您的 gsNames 对象具有不带扩展名的文件名,但是当代码尝试使用具有文件扩展名的 !gsNames[file.getName()] 访问特定元素时。它总是返回 undefined,它被评估为 True。

    因此,您需要先删除文件扩展名,然后再尝试检查同一文件是否已被转换。删除文件扩展名的正则表达式被无耻地从here 复制。您的逻辑将被修改如下:

    if(file.getOwner().getEmail() == user.getEmail() && !gsNames[file.getName().replace(/\.[^/.]+$/, "")])
    

    您的文件代码将是:

    function convertCollection1() 
    {
      var user = Session.getActiveUser(); // Used for ownership testing.1aJcbdGhwliTs_CZ-3ZUvQmGRDzBM7fv9
      var origin = DriveApp.getFolderById("1dPsDfoqMQLCokZK4RN0C0VRzaRATr9AN");
      var dest = DriveApp.getFolderById("1M6lDfc_xEkR4w61pUOG4P5AXmSGF1hGy");
    
      // Index the filenames of owned Google Sheets files as object keys (which are hashed).
      // This avoids needing to search and do multiple string comparisons.
      // It takes around 100-200 ms per iteration to advance the iterator, check if the file
      // should be cached, and insert the key-value pair. Depending on the magnitude of
      // the task, this may need to be done separately, and loaded from a storage device instead.
      // Note that there are quota limits on queries per second - 1000 per 100 sec:
      // If the sequence is too large and the loop too fast, Utilities.sleep() usage will be needed.
      var gsi = dest.getFilesByType(MimeType.GOOGLE_SHEETS), gsNames = {};
      while (gsi.hasNext())
      {
        var file = gsi.next();
        if(file.getOwner().getEmail() == user.getEmail())
          gsNames[file.getName()] = true;
    
        Logger.log(JSON.stringify(gsNames))
      }
    
      // Find and convert any unconverted .xls, .xlsx files in the given directories.
      var exceltypes = [MimeType.MICROSOFT_EXCEL, MimeType.MICROSOFT_EXCEL_LEGACY];
      for(var mt = 0; mt < exceltypes.length; ++mt)
      {
        var efi = origin.getFilesByType(exceltypes[mt]);
        while (efi.hasNext())
        {
          var file = efi.next();
          // Perform conversions only for owned files that don't have owned gs equivalents.
          // If an excel file does not have gs file with the same name, gsNames[ ... ] will be undefined, and !undefined -> true
          // If an excel file does have a gs file with the same name, gsNames[ ... ] will be true, and !true -> false
          if(file.getOwner().getEmail() == user.getEmail() && !gsNames[file.getName().replace(/\.[^/.]+$/, "")])
          {
            Drive.Files.insert (
              {title: file.getName(), parents: [{"id": dest.getId()}]},
              file.getBlob(),
              {convert: true}
            );
            // Do not convert any more spreadsheets with this same name.
            gsNames[file.getName()] = true;
          }
        }
      }
      Logger.log(JSON.stringify(gsNames))
    }
    

    注意Logger.log() 的使用,以后使用它来确定程序可能正在访问的内容与您认为它正在执行的操作。

    干杯!

    【讨论】:

    • 嘿,杰克,我可以问一个简单的问题吗?如果我想在一个文件夹中包含所有子文件夹,可以吗?
    • 你能再帮我一次吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-18
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    相关资源
    最近更新 更多