【问题标题】:Stop script from creating same file again or/and overwriting existing one停止脚本再次创建相同的文件或/和覆盖现有文件
【发布时间】:2021-03-22 09:43:16
【问题描述】:

编辑 我将标题编辑为更好的标题。
来自:停止脚本再次创建相同的文件
To:停止脚本再次创建相同的文件或/和覆盖现有文件


Cooperthis postTanaikethis 的帮助下,我编写了这样的脚本。

问题
当我运行代码 1 次 AND RUN AGAIN 再次出现另一个文件。
我怎样才能阻止这个?如果我已经有了它,我不希望脚本创建第二个文件。

function excel2SheetsAndSorting4LED(){
  sta56160812();
  loadSortSheetsInFolder();
}

// this from Tanaike
function sta56160812() {
  // const folderId = "xxxxx"; // Please set the folder ID.
  var sourceFldrId = "xxxxx"; // ID of SOURCE folder
  var destinationFldrId = "zzzzz"; // ID of DESTINATION folder (can be the same folder)

  const folder = DriveApp.getFolderById(sourceFldrId);
  const files = folder.getFiles();
  while(files.hasNext()) {
    const file = files.next();
    if (file.getMimeType() == MimeType.MICROSOFT_EXCEL || file.getMimeType() == MimeType.MICROSOFT_EXCEL_LEGACY) {
      var name = file.getName().split('.')[0];
      var resource = {
        title: name + '_converted',
        parents: [{id: destinationFldrId}],
        mimeType: MimeType.GOOGLE_SHEETS
      };
      var spreadsheet = Drive.Files.copy(resource, file.getId());
      // var sheet = SpreadsheetApp.openById(spreadsheet.id).getSheets()[0];
      // var value = sheet.getDataRange().getValues();
      // Logger.log(value)
    }
  }
}

// and this from Cooper: https://stackoverflow.com/questions/66695743/how-to-add-a-formula-to-all-spreadsheets-in-a-folder-using-a-script#comment117933455_66695743
function loadAndSortSpreadsheetsInFolder() {
    const values = [
        [1, 'where Col5<>0', "=COUNTA(K4:K)",'', "=COUNTA(M4:M)", "=COUNTA(N4:N)"],
        [2, "=IF(K2=FALSE,,\" and Col5<=95\")", '', '', '', ''],
        [3, "=QUERY(SORT({A3:B,C3:C+0,D3:D,E3:G+0,Y3:AF},3,0,5,1),J1&J2,1)", '', '', '', '']
    ];
    const destinationFldrId = "zzzzz"; // ID of DESTINATION folder (can be the same folder) //
    const fldr = DriveApp.getFolderById(destinationFldrId);
    let files = fldr.getFilesByType(MimeType.GOOGLE_SHEETS);
    while (files.hasNext()) {
        let file = files.next();
        let id = file.getId();
        let ss = SpreadsheetApp.openById(id);
        let sh = ss.getSheets()[0].copyTo(ss);
        sh.setTabColor("ff0000");
        ss.moveActiveSheet(1);
        let rg1 = sh.getRange("I1:Y").clear();
        let rg2 = sh.getRange(1, 9, values.length, values[0].length).setValues(values);
        let rg3 = sh.getRange(2,11).insertCheckboxes();
    }
}

而且脚本也很慢,因为它首先创建所有文件,然后在上面写入。
如何让它在目的地创建,打开文件一次,写入,关闭,转到下一个?

谢谢。

【问题讨论】:

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


    【解决方案1】:

    我相信你的目标如下。

    • 当你运行sta56160812()的函数时,当转换后的电子表格存在相同的文件名时,你不想创建新的谷歌电子表格。
    • 您想将loadAndSortSpreadsheetsInFolder() 的函数包含在sta56160812() 的函数中。

    修改点:

    • 在这种情况下,从您的脚本中,我建议检查目标文件夹中var name = file.getName().split('.')[0] + '_converted' 的文件名。
    • 根据您的问题,当目标文件夹中存在相同的文件名时,我不确定您想要做什么。所以在这个答案中,我想用const file = files.next()覆盖现有文件。
    • 为了将loadAndSortSpreadsheetsInFolder()的函数包含在sta56160812()的函数中,修改了sta56160812()中的do while循环。

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

    修改脚本:

    请修改您的sta56160812()如下。

    从:
    while(files.hasNext()) {
      const file = files.next();
      if (file.getMimeType() == MimeType.MICROSOFT_EXCEL || file.getMimeType() == MimeType.MICROSOFT_EXCEL_LEGACY) {
        var name = file.getName().split('.')[0];
        var resource = {
          title: name + '_converted',
          parents: [{id: destinationFldrId}],
          mimeType: MimeType.GOOGLE_SHEETS
        };
        var spreadsheet = Drive.Files.copy(resource, file.getId());
        // var sheet = SpreadsheetApp.openById(spreadsheet.id).getSheets()[0];
        // var value = sheet.getDataRange().getValues();
        // Logger.log(value)
      }
    }
    
    到:
    while (files.hasNext()) {
      const file = files.next();
      if (file.getMimeType() == MimeType.MICROSOFT_EXCEL || file.getMimeType() == MimeType.MICROSOFT_EXCEL_LEGACY) {
        var name = file.getName().split('.')[0] + '_converted';
        var existingFile = DriveApp.getFilesByName(name);
        var spreadsheetId;
        if (existingFile.hasNext()) {
          var id = existingFile.next().getId();
          spreadsheetId = Drive.Files.update({}, id, file.getBlob()).id;
        } else {
          var resource = {
            title: name,
            parents: [{ id: destinationFldrId }],
            mimeType: MimeType.GOOGLE_SHEETS
          };
          spreadsheetId = Drive.Files.copy(resource, file.getId()).id;
        }
    
        // Below script is from loadAndSortSpreadsheetsInFolder().
        const values = [
          [1, 'where Col5<>0', "=COUNTA(K4:K)",'', "=COUNTA(M4:M)", "=COUNTA(N4:N)"],
          [2, "=IF(K2=FALSE,,\" and Col5<=95\")", '', '', '', ''],
          [3, "=QUERY(SORT({A3:B,C3:C+0,D3:D,E3:G+0,Y3:AF},3,0,5,1),J1&J2,1)", '', '', '', '']
        ];
        let ss = SpreadsheetApp.openById(spreadsheetId);
        let sh = ss.getSheets()[0].copyTo(ss);
        sh.setTabColor("ff0000");
        ss.moveActiveSheet(1);
        let rg1 = sh.getRange("I1:Y").clear();
        let rg2 = sh.getRange(1, 9, values.length, values[0].length).setValues(values);
        let rg3 = sh.getRange(2,11).insertCheckboxes();
      }
    }
    
    • 并且,在此修改中,请从 excel2SheetsAndSorting4LED() 中删除 loadSortSheetsInFolder();

    注意:

    • 如果您不想覆盖现有文件,请从上述修改后的脚本中删除var id = existingFile.next().getId();spreadsheet = Drive.Files.update({}, id, file.getBlob());
    • 此修改后的脚本假定在您的环境中,Drive API 已在高级 Google 服务中启用。请注意这一点。

    参考:

    新增1:

    根据您的以下回复,

    对于造成的混乱,我深表歉意。我的英语也不是很好(我希望有更多时间思考时会更好)。停止脚本再次创建相同的文件并且不覆盖现有的具有相同名称的转换文件是更详细的问题。与之前的脚本一样:源文件夹 = file01.xlsx、file02.xlsx。目标文件夹 = file01_converted、file03、file04。脚本后:目标文件夹:file01_converted(旧文件)、file02_converted(新文件)、file03、file04。我希望我现在说清楚,再次为混乱感到抱歉。谢谢@Tanaike

    在上述情况下,我了解到file01_converted (old file) (old file)file02_converted (new file) (new file) 不包含在文件名中。如果我的理解是正确的,在这种情况下,我认为在existingFile.hasNext() 时删除if 语句中的脚本是合适的。修改后的脚本如下。

    修改脚本:

    请修改你的sta56160812()如下。

    从:
    while(files.hasNext()) {
      const file = files.next();
      if (file.getMimeType() == MimeType.MICROSOFT_EXCEL || file.getMimeType() == MimeType.MICROSOFT_EXCEL_LEGACY) {
        var name = file.getName().split('.')[0];
        var resource = {
          title: name + '_converted',
          parents: [{id: destinationFldrId}],
          mimeType: MimeType.GOOGLE_SHEETS
        };
        var spreadsheet = Drive.Files.copy(resource, file.getId());
        // var sheet = SpreadsheetApp.openById(spreadsheet.id).getSheets()[0];
        // var value = sheet.getDataRange().getValues();
        // Logger.log(value)
      }
    }
    
    到:
    while (files.hasNext()) {
      const file = files.next();
      if (file.getMimeType() == MimeType.MICROSOFT_EXCEL || file.getMimeType() == MimeType.MICROSOFT_EXCEL_LEGACY) {
        var name = file.getName().split('.')[0] + '_converted';
        var existingFile = DriveApp.getFilesByName(name);
        if (!existingFile.hasNext()) {
          var resource = {
            title: name,
            parents: [{ id: destinationFldrId }],
            mimeType: MimeType.GOOGLE_SHEETS
          };
          var spreadsheetId = Drive.Files.copy(resource, file.getId()).id;
    
          // Below script is from loadAndSortSpreadsheetsInFolder().
          const values = [
              [1, 'where Col5<>0', "=COUNTA(K4:K)",'', "=COUNTA(M4:M)", "=COUNTA(N4:N)"],
              [2, "=IF(K2=FALSE,,\" and Col5<=95\")", '', '', '', ''],
              [3, "=QUERY(SORT({A3:B,C3:C+0,D3:D,E3:G+0,Y3:AF},3,0,5,1),J1&J2,1)", '', '', '', '']
          ];
          let ss = SpreadsheetApp.openById(spreadsheetId);
          let sh = ss.getSheets()[0].copyTo(ss);
          sh.setTabColor("ff0000");
          ss.moveActiveSheet(1);
          let rg1 = sh.getRange("I1:Y").clear();
          let rg2 = sh.getRange(1, 9, values.length, values[0].length).setValues(values);
          let rg3 = sh.getRange(2,11).insertCheckboxes();
        }
      }
    }
    
    • 在这种情况下,当目标文件夹中存在相同的文件名时,if (!existingFile.hasNext()) {} 的脚本不会运行。

    新增2:

    根据您的以下回复,

    美丽。你能从这里添加最后一件事吗?如何将新标签 ss.getSheets()[0].copyTo(ss) 从第二个标签位置移动到第一个?

    示例脚本:

    ss.getSheets()[0].copyTo(ss)创建的新工作表移动到第一个标签的简单示例脚本如下。

    function myFunction() {
      const ss = SpreadsheetApp.openById("###"); // or .getActiveSpreadsheet();
      const newSheet = ss.getSheets()[0].copyTo(ss);
      ss.setActiveSheet(newSheet);
      ss.moveActiveSheet(0);
    }
    

    【讨论】:

    • 非常感谢田池。我会测试并很快回来。
    • @Swen 感谢您的回复。当我误解了你的问题时,我为此道歉。到时候请告诉我。我想修改我的答案。
    • Tanaike 你理解的几乎是正确的并且脚本有效。谢谢你。但。 我不确定什么是最好的。像现在的脚本一样覆盖所有文件或保留现有文件? 因为如果文件已经在目的地,也许我必须保留文件中的修改。我怎样才能有这种替代方法来跳过目标中的现有文件?最后一件事。如何将新标签 ss.getSheets()[0].copyTo(ss) 从第二个标签位置移动到第一个?我找不到我看过的任何地方。你能包括这个还是我必须开始新的职位?再次感谢您。
    • @Swen 感谢您的回复。我带来的不便表示歉意。关于BUT. I am not sure what is best.,不幸的是,从您的问题来看,当我的回答中提到的目标文件夹中存在相同的文件名时,我无法理解您想要做什么。这是因为我的英语水平不好。我为此道歉。这样,作为示例,我包含了用于覆盖的脚本。所以你可以删除脚本。关于这一点,我认为这取决于你的实际目标。那我能问一下你想做什么吗?从这里,我想修改它。
    • @Swen 关于Because if files are already in destination, maybe there are modifications in files I must keep.,在这种情况下,我认为可以使用您当前的脚本。但是,在你的问题中,你说When I run the code 1 time AND RUN AGAIN there is another file again. How can I stop this?。所以我混淆了你的目标。我为此道歉。在这种情况下,我可以问你关于你的目标的细节吗?关于你How can I move new tab ss.getSheets()[0].copyTo(ss) from 2nd tab position to first?的第三个问题,这个可以实现。但是,我认为如何解决您的第一个问题?
    猜你喜欢
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 2018-01-18
    • 1970-01-01
    相关资源
    最近更新 更多