【问题标题】:how to remove empty rows and columns using batch request如何使用批处理请求删除空行和列
【发布时间】:2021-04-19 08:50:40
【问题描述】:

我有一个代码,通过它我可以从工作表中删除所有空行和列。是否可以使用批处理请求来加快脚本的工作,因为当文件很多时,需要很长时间?

代码如下

    while ( files.hasNext()){
   var file1 = files.next().getId();
 var sheet = SpreadsheetApp.openById(file1);
var allsheets = sheet.getSheets();
for (var s in allsheets){
var sheet=allsheets[s]
var maxColumns = sheet.getMaxColumns(); 
var lastColumn = sheet.getLastColumn();
var maxRows = sheet.getMaxRows(); 
var lastRow = sheet.getLastRow();
if (maxRows-lastRow === 0){}
else {
if (maxRows-lastRow != 0){
      sheet.deleteRows(lastRow+1, maxRows-lastRow);
      }
      console.log(sheet)
if (maxColumns-lastColumn != 0){
      sheet.deleteColumns(lastColumn+1, maxColumns-lastColumn);
      }
      console.log(sheet)
    }
  }
 }

如果有任何帮助,我将不胜感激

【问题讨论】:

    标签: google-apps-script google-drive-api google-sheets-api batch-request


    【解决方案1】:

    我相信你的目标如下。

    • 您希望降低脚本的处理成本。
    • 您想使用批处理请求。

    修改点:

    • 在这种情况下,作为一种简单的方法,我想建议使用 Sheets API 的 batchUpdate 方法来删​​除行和列。我认为这样可以减少一点流程成本。

    当以上几点反映到你的脚本中时,它变成如下。

    修改脚本:

    在使用此脚本之前,please enable Sheets API at Advanced Google services

    while (files.hasNext()){
      var file1 = files.next().getId();
      var ss = SpreadsheetApp.openById(file1);
      var sheets = ss.getSheets();
      var requests = sheets.reduce((ar, sheet) => {
        var sheetId = sheet.getSheetId();
        var maxColumns = sheet.getMaxColumns(); 
        var lastColumn = sheet.getLastColumn();
        var maxRows = sheet.getMaxRows(); 
        var lastRow = sheet.getLastRow();
        if (lastRow > 1 && maxRows > lastRow) {
          ar.push({deleteDimension: {range: {sheetId: sheetId, dimension: "ROWS", startIndex: lastRow}}});
        }
        if (lastColumn > 1 && maxColumns > lastColumn) {
          ar.push({deleteDimension: {range: {sheetId: sheetId, dimension: "COLUMNS", startIndex: lastColumn}}});
        }
        
        // For empty sheet, when you want to leave only cell "A1", please use the following script.
        // if (lastRow == 0 && lastColumn == 0 && maxRows > 1 && maxColumns > 1) {
        //   ar.push({deleteDimension: {range: {sheetId: sheetId, dimension: "ROWS", startIndex: 1}}});
        //   ar.push({deleteDimension: {range: {sheetId: sheetId, dimension: "COLUMNS", startIndex: 1}}});
        // }
    
        return ar;
      }, []);
      if (requests.length > 0) {
        Sheets.Spreadsheets.batchUpdate({requests: requests}, id);
      }
    }
    
    • 运行此脚本时,将删除电子表格中所有工作表中的空行和空列。
    • 对于空工作表,当您只想在工作表中保留单元格“A1”时,请使用注释脚本。

    注意:

    • 我认为上面的示例脚本可能适合文件数量较少的情况。但是,当文件数量很大时,当使用 Drive API 检索文件列表时,处理成本可能会降低更多。在这种情况下,使用 Drive API v3 检索文件列表的过程成本低于使用 Advanced Google 服务的 Drive API v2 检索文件列表的过程成本。因此,此示例脚本使用了使用 UrlFetchApp 的 Drive API v3。在此示例脚本中,从您的脚本中,它假定文件存在于文件夹下。请注意这一点。

    • 当您使用此脚本时,请在 Google 高级服务中启用 Drive API。

        function myFunction() {
          var topFolderId = "###";  // Please set the folder ID of the top folder.
      
          // Retrieve file list using Drive API v3.
          const headers = {authorization: `Bearer ${ScriptApp.getOAuthToken()}`};
          const q = `'${topFolderId}' in parents and mimeType='${MimeType.GOOGLE_SHEETS}' and trashed=false`;
          const url = `https://www.googleapis.com/drive/v3/files?pageSize=1000&q=${q}&fields=${encodeURIComponent("nextPageToken,files(id)")}`;
          let pageToken = "";
          let files = [];
          do {
            const res = UrlFetchApp.fetch(url + "&pageToken=" + pageToken, {headers: headers, muteHttpExceptions: true});
            if (res.getResponseCode() != 200) throw new Error(res.getContentText());
            const obj = JSON.parse(res.getContentText());
            files = files.concat(obj.files);
            pageToken = obj.nextPageToken || "";
          } while(pageToken);
      
          // Remove empty rows and columns using Sheets API.
          files.forEach(({id}) => {
            var ss = SpreadsheetApp.openById(id);
            var sheets = ss.getSheets();
            var requests = sheets.reduce((ar, sheet) => {
              var sheetId = sheet.getSheetId();
              var maxColumns = sheet.getMaxColumns(); 
              var lastColumn = sheet.getLastColumn();
              var maxRows = sheet.getMaxRows(); 
              var lastRow = sheet.getLastRow();
              if (lastRow > 1 && maxRows > lastRow) {
                ar.push({deleteDimension: {range: {sheetId: sheetId, dimension: "ROWS", startIndex: lastRow}}});
              }
              if (lastColumn > 1 && maxColumns > lastColumn) {
                ar.push({deleteDimension: {range: {sheetId: sheetId, dimension: "COLUMNS", startIndex: lastColumn}}});
              }
              if (lastRow == 0 && lastColumn == 0 && maxRows > 1 && maxColumns > 1) {
                ar.push({deleteDimension: {range: {sheetId: sheetId, dimension: "ROWS", startIndex: 1}}});
                ar.push({deleteDimension: {range: {sheetId: sheetId, dimension: "COLUMNS", startIndex: 1}}});
              }
              return ar;
            }, []);
            if (requests.length > 0) {
              Sheets.Spreadsheets.batchUpdate({requests: requests}, id);
            }
          });
        }
      

    参考资料:

    【讨论】:

    • 非常感谢,第二个脚本的执行速度惊人。
    • @Антон Кожевников 感谢您再次回复和测试。很高兴您的问题得到解决。
    • 我问一个新问题,请看[链接]:stackoverflow.com/questions/65731588/…
    • 这个问题请stackoverflow.com/questions/65733610/…>
    • @Антон Кожевников 我看到了你的新问题,我建议修改后的脚本作为答案。你能确认一下吗?如果这些不是您期望的方向,我深表歉意。
    猜你喜欢
    • 1970-01-01
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    相关资源
    最近更新 更多