【GAS】ファイル名が重複しないように連番を付加

以下のマクロを、Google Apps Script (GAS)に変換しました。

この VBAマクロ は、新しいワークブックを指定のパスに、ファイル名が重複しないように連番を付けて保存する 機能を持っています。

Google Apps Script (GAS) では、VBAで利用している FileSystemObjectローカルのファイルシステム(Cドライブなど) を直接操作することはできません。

GASは主に Googleドライブ 上のファイルや スプレッドシート を操作するために使用されます。

そのため、このVBAマクロの機能をGASに変換する際は、Googleドライブ上に「新しいGoogleスプレッドシート(または別のファイルタイプ)」を作成し、ファイル名が重複しないように連番を付与して保存する 処理に置き換える必要があります。

以下に、GASでGoogleドライブ上に新しいスプレッドシートを作成し、ファイル名が重複しないように連番を付けて保存する 関数を記述します。

/**
 * ファイル名が重複しないように連番を付加して新しいGoogleスプレッドシートを作成します。
 *
 * @param {string} fileNameWithoutExtension 拡張子を除いた基本ファイル名 (例: "MyNewWorkbook")
 * @param {string} folderId ファイルを作成するGoogleドライブフォルダのID (オプション)
 * @returns {GoogleAppsScript.Drive.File} 作成された新しいスプレッドシートファイルオブジェクト
 */
function createNewSpreadsheetWithUniqueName(fileNameWithoutExtension, folderId) {
  // 基本的なファイル名(連番なし)
  let baseName = fileNameWithoutExtension;
  let saveName = baseName;
  let counter = 1;
  let existingFile = null;
  
  // ファイルを保存する場所(フォルダIDが指定されていればそのフォルダ、なければマイドライブのルート)
  const targetFolder = folderId ? DriveApp.getFolderById(folderId) : DriveApp.getRootFolder();

  // 既にファイルが存在するかチェックし、存在する場合は連番を付与して一意のファイル名を決定
  // GASのDriveApp.getFilesByName()は、同じ名前のファイルを全て取得するため、
  // ループで連番を増やしながら、そのファイル名が存在するかをチェックします。
  do {
    // 現在のファイル名でファイルが存在するか検索
    // Google Apps Scriptのファイル検索は完全一致ではないため、名前と親フォルダで絞り込む
    let filesIterator = targetFolder.getFilesByName(saveName);

    // イテレータの次の要素が存在するか(つまり、その名前のファイルがフォルダ内に存在するか)チェック
    if (filesIterator.hasNext()) {
      // ファイルが存在する場合
      counter++;
      saveName = `${baseName} (${counter})`; // "(2)", "(3)" のように番号を追加
      existingFile = filesIterator.next(); // 存在したファイルオブジェクト(次のループで参照されないが、hasnextの結果を消費するために必要)
      
      // 厳密なファイル名の一致と親フォルダのチェックを行う場合は、
      // 取得したファイルのコレクションをループで確認する必要がありますが、
      // ここでは、`getFilesByName`で**その名前で始まるファイルが存在する**ことを確認する簡易的な方法を採用しています。
      // Googleドライブ上では、同じフォルダ内に同じ名前のファイルは作成できないため、基本的にはこれで十分です。
    } else {
      // ファイルが存在しない場合(一意の名前が見つかった)
      existingFile = null;
    }
  } while (targetFolder.getFilesByName(saveName).hasNext()); // フォルダ内にこの名前のファイルがある限りループ

  // 一意のファイル名で新しいスプレッドシートを作成
  // Spreadsheets.create()はシートの中身を操作しない場合に高速です
  const newSpreadsheet = SpreadsheetApp.create(saveName);
  
  // 新しく作成されたスプレッドシートをデフォルトフォルダから指定されたターゲットフォルダに移動
  // 新しいスプレッドシートは自動的にルートフォルダに作成されるため、移動が必要です。
  const file = DriveApp.getFileById(newSpreadsheet.getId());
  
  // ルートフォルダから削除 (もしルートフォルダにあった場合)
  // スプレッドシート.create()で作成されたファイルはルートフォルダに作成されるため、
  // 作成直後の親フォルダはDriveApp.getRootFolder()であると仮定します。
  try {
    DriveApp.getRootFolder().removeFile(file);
  } catch (e) {
    // ルートフォルダにない場合はエラーになるが無視
  }

  // ターゲットフォルダに追加
  targetFolder.addFile(file);

  return file;
}

// ----------------------------------------------------
// テスト用関数(VBAの「使用例」に相当)
// ----------------------------------------------------

/**
 * テスト用マクロ: 新しいスプレッドシートを連番付きで作成し、ドライブの特定のフォルダに保存します。
 */
function testUsage() {
  // 保存したい基本ファイル名(拡張子不要)
  const baseFileName = "test";
  
  // 🚀 【重要】保存したいフォルダのIDをここに設定してください
  // 例: '1ABc2DeF3GhI4JkL5MnOpQ6RsTuVwXyZ' のような形式
  // ルートフォルダに保存したい場合は null または '' を設定
  const targetFolderId = ""; // 例: '1234567890abcdefghijklmnopqrstuvwxyz'
  
  // 重複を避けて新しいスプレッドシートを作成
  const newFile = createNewSpreadsheetWithUniqueName(baseFileName, targetFolderId);
  
  // 処理結果の確認
  if (newFile) {
    Logger.log(`✅ 新しいファイルが作成されました: ${newFile.getName()}`);
    Logger.log(`🔗 ファイルURL: ${newFile.getUrl()}`);
  } else {
    Logger.log("❌ ファイルの作成に失敗しました。");
  }
}

VBAとGASの主な違いと対応

VBAの機能GASでの対応・考え方備考
Workbook の操作SpreadsheetApp の操作GASは主にGoogleスプレッドシートを扱います。
Workbooks.AddSpreadsheetApp.create()新しいスプレッドシートを作成します。
wb.SaveAs fileName:=...SpreadsheetApp.create(fileName)DriveApp によるファイル移動GASはファイル作成時にファイル名を指定します。作成されたファイルはDriveAppで管理・移動します。
wb.Close SaveChanges:=False不要GASはセッションベースで動作し、ファイルの開閉を明示的に行う必要がありません。
FileSystemObject (fso)DriveApp のメソッドGASはGoogleドライブ上のファイルを操作します。
fso.FileExists(path)DriveApp.getFilesByName(name) を使用したファイル検索ドライブ内のファイル検索に置き換わります。
ファイルパス (C:\TEMP\test.xlsx)ファイル名フォルダIDGASはローカルパスではなく、Googleドライブ上のファイル名とフォルダIDでファイルを管理します。
.xlsx (Excel形式)Googleスプレッドシート形式スプレッドシートをExcel形式で保存したい場合は、別途変換・エクスポートが必要です。
Sub/FunctionfunctionJavaScript形式の関数を使用します。
Dim ... As ...let/const変数宣言はJavaScriptの構文に従います。

Follow me!