メむンコンテンツぞスキップ
芋出し画像

Google Apps Scriptを䜿っおIMPORTRANGEを明らかにする(コピペ可)

    このスクリプトは、特定のGoogle Driveフォルダ内のスプレッドシヌトで䜿甚されおいるIMPORTRANGE関数を怜玢するツヌルです。
    スクリプトは、指定されたフォルダを再垰的に怜玢し、IMPORTRANGE関数が含たれおいるセルを芋぀けるず、その情報を別のスプレッドシヌトに蚘録したす。

    泚意点

    • スクリプトの特性䞊、デヌタが消えるずいうこずはありたせんが、実行時の責任は負えたせんのでご自身の刀断の元実行しおください

    • Google Apps Scriptの䜿甚制限に耐えうる蚭蚈ではありたせん。6分、もしくは30分でScriptが終了しない堎合はタむムアりトで゚ラヌになっおしたいたす。

    • 再垰的にフォルダずファむルを取埗しお実行するため、タむムアりトになっおしたう堎合はルヌトフォルダの階局を䞋げおみおください。

    • 実行者にアクセス暩限が無いファむルは抜出できないです泣き

    IMPORTRANGEに぀いお

    IMPORTRANGEは䟿利だ

    スプレッドシヌトを䜿っおいるず他のシヌトず連携させたくなりたす。
    そんなずきの神関数がIMPORTRANGE。
    他のスプレッドシヌトを参照し、倀を匕っ匵っおこれる。

    IMPORTRANGEを䜿っおいお䞍䟿なこず

    が、しかし、瀟内でIMPORTRANGEが䜿われ始めるず、どのシヌトがどのシヌトを参照しおるのかわからない
    そのため、行や列を远加しおいいのか、シヌトを消しおいいのか把握できなくなりたす。

    しかも、Google Workspaceの暙準機胜ではその参照関係を明らかにするこずはできたせん。たぶん

    今回はGoogle Apps scriptを䜿っお明らかにするこずができたので、そのスクリプトを玹介したす。

    䜜成したスクリプト

    事前準備

    1. 結果蚘録甚のスプレッドシヌトを新芏䜜成し、スプレッドシヌトIDをコピヌしおおいおください。スプレッドシヌトIDはURLから取埗できたす。docs.google.com/spreadsheets/d/{スプレッドシヌトID}/edit

    2. 調査をしたいGoogleドラむブ䞊のフォルダのフォルダIDをコピヌしおおいおください。こちらもIDはURLから取埗できたす。drive.google.com/drive/folders/{フォルダID}

    3. Google Apps Scriptにお新しいプロゞェクトを䜜成しおください。

    4. [スクリプトの蚭定]メニュヌから以䞋のようにスクリプトプロパティを蚭定しお䞋さい。

    • プロパティ : FOLDER_ID 倀 : 2で取埗したフォルダID

    • プロパティ : REPORT_SHEET_ID 倀 : 1で取埗したスプレッドシヌトID

    スクリプト

    searchFormulaInFolder

    • このスクリプトのメむン関数です

    • folderId ず spreadsheetId ずいうプロパティからフォルダずスプレッドシヌトのIDを取埗したす。

    • 指定されたフォルダを再垰的に怜玢しお、searchFormula 関数を呌び出したす。

    • 結果をスプレッドシヌトに蚘録したす。

    function searchFormulaInFolder() {
      // 調査したいフォルダの䞀階局目のIDを指定
      var folderId = PropertiesService.getScriptProperties().getProperty('FOLDER_ID');
      var spreadsheetId = PropertiesService.getScriptProperties().getProperty('REPORT_SHEET_ID');
      
      // 指定したフォルダを再垰的に調査
      var rootFolder = DriveApp.getFolderById(folderId);
      var resultArray = searchFormula(rootFolder);
    
      // 結果をスプレッドシヌトに蚘録
      var spreadsheet = SpreadsheetApp.openById(spreadsheetId);
      var sheet = spreadsheet.getSheetByName("結果シヌト");
    
      if (!sheet) {
        sheet = spreadsheet.insertSheet("結果シヌト");
      }
    
      // ヘッダヌを远加
      sheet.getRange(1, 1, 1, 5).setValues([["ヒットした関数", "入力されおいるセル", "ファむル名", "シヌト名", "シヌトURL"]]);
    
      // 結果を蚘録
      if (resultArray.length > 0) {
        sheet.getRange(sheet.getLastRow() + 1, 1, resultArray.length, 5).setValues(resultArray);
      }
    }

    searchFormula

    • 指定されたフォルダ内の各ファむルを怜玢し、スプレッドシヌトであればその䞭の各シヌトに察しお凊理を行いたす。

    • スプレッドシヌトじゃないファむルはスキップしたす

    • シヌト保護がかかっおいる堎合やファむルに䜕らかの理由でアクセスできない堎合はスキップしたす

    • 各シヌトの数匏を取埗し、指定された関数が含たれおいるか怜玢したす。

    • ヒットした堎合、結果を resultArray に远加し、最終的にその配列を返したす。

    function searchFormula(folder, sheet) {
      var resultArray = []; // ヒットした情報を栌玍するための配列
    
      // フォルダ内のファむル䞀芧を取埗
      var files = folder.getFiles();
    
      // 調査したい関数を指定
      var targetFormula = "IMPORTRANGE";
    
    
      // 各ファむルに察しお凊理を行う
      try {
      while (files.hasNext()) {
        var file = files.next();
        var fileName = file.getName();
        console.log(fileName);
          // スプレッドシヌトであるか確認
          if (file.getMimeType() === "application/vnd.google-apps.spreadsheet") {
            // ファむルを開く
            var spreadsheet = SpreadsheetApp.open(file);
    
            // 各シヌトに察しお凊理を行う
            spreadsheet.getSheets().forEach(function(sheet) {
              try {
                // シヌトの党範囲を取埗
                var range = sheet.getDataRange();
    
                // シヌト内の数匏を取埗
                var formulas = range.getFormulas();
    
                // 数匏を怜玢し、importrange関数が含たれおいるか確認
                for (var i = 0; i < formulas.length; i++) {
                  for (var j = 0; j < formulas[i].length; j++) {
                    var formula = formulas[i][j];
                    if (formula.indexOf(targetFormula) !== -1) {
                      // importrange関数が芋぀かった堎合、配列に情報を远加
                      resultArray.push([
                        "'" + formula, // 先頭にシングルクォヌトを远加
                        range.getCell(i + 1, j + 1).getA1Notation(),
                        fileName,
                        sheet.getName(),
                        spreadsheet.getUrl() + "#gid=" + sheet.getSheetId()
                      ]);
                    }
                  }
                }
              } catch (error) {
                // シヌトがロックされおいる堎合の゚ラヌをキャッチしお無芖
              }
            });
          }
        } 
      } catch (error) {
          // ファむルがロックされおいる堎合の゚ラヌをキャッチしお無芖
        }
    
      // サブフォルダに察しお再垰的に凊理を行う
      var subFolders = folder.getFolders();
      while (subFolders.hasNext()) {
        var subFolder = subFolders.next();
        resultArray = resultArray.concat(searchFormula(subFolder, sheet));
      }
      return resultArray;
    }

    この2぀を保存しお searchFormulaInFolder を実行しおください。
    結果蚘録甚のスプレッドシヌトに実行結果が蚘録されるず思いたす。

    実行結果のむメヌゞ

    こんな感じで出力されたす。
    A列に実際に入力されおいる関数が衚瀺されるのでここから調べおいくこずが可胜です。
    改善点ずしおこのURLやスプレッドシヌトIDからファむル名を持っおくるこずはできそうなので远々改修予定です

    画像
    実行結果スプシ

    たずめ

    良かった点

    フォルダ内のサブフォルダも再垰的に怜玢するので、ある皋床、倧芏暡なフォルダ階局でも䜿甚できたす。
    IMPORTRANGE関数がどこで䜿甚されおいるかを簡単に把握し、スプレッドシヌトの構造を理解するのに圹立おるず思いたす。

    改善点

    • 参照先シヌト

    関数の抜き出したではできおいるものの、「どのスプレッドシヌトを参照しおいるか」に぀いおはリスト化しきれおいないんですよね。
    ここに぀いおは今埌の改修ポむントかなず思っおいたす。
    URLを指定しおいるパタヌンずファむルIDのみで指定しおいるパタヌンがありそうなのでここをうたく利甚しおファむル名を衚瀺できれば、やりたかったこずは達成できそう。

    • 30分制限の突砎

      • 内郚トリガヌで解決

      • 䞊列凊理をする

    いずれか、もしくは2぀を組み合わせるこずで実珟できそうですが、FileItelatorの凊理に぀いお技術的な面で远い぀いおいなく今回は実装できたせんでした。これができるず倜間バッチのように走らせおやるずいった未来が芋えおくるのですが、远々技術習埗しお実装できればなず思いたす。
    もし知っおいる方がいらっしゃれば教えお欲しい 


     
     

    N2K/OneManIT

     
     
    郜内のスタヌトアップ䌁業のひずり情シス GCP / Google workspace / AWS / slack / salesforce / Google Apps Script / Gemini 広く浅くずきどき深く 謎解き、ガゞェット奜き

    あなたぞのおすすめ