Google Drive上の指定のフォルダ以下のファイル一覧をSpreadSheetに書き出す

## はじめに

前回、 [Google Driveにpythonでデータを登録する & Siderを使ってチェックしてみる](https://qiita.com/akiko-pusu/items/f05a5dcba544e97c057c) というメモを書きました。

なんとか手元のファイル一式をGoogleDrive側にアップロードすることができましたが、実際数が多かったので、本当に全部アップロードできたのか確認したい...。

ということで、GoogleDriveのとあるフォルダにアップロードしたファイル一覧を、GoogleSpreadSheetに書き出す、ということをして、件数をチェックすることにします。

すでにたくさんの方がもっと詳しく、同様の内容を書いてくださっていますので、特段目新しいことはないのですが、また自分自身が必要になった時のために書き残しておきます。

### 今回やること

このような流れでチェックします。

- 書き出すGoogleSpreadSheetを作成する
- Google Apps Scriptを使って、特定のフォルダに入っているファイルを書き出す

## シートを作って実行してみる

まずは書き出すためのスプレッドシートを作成します。
次に、メニューから「スクリプトエディタ」を選択し、Google Apps Scriptの編集画面を表示します。

![script-editor.png](https://qiita-image-store.s3.amazonaws.com/0/27976/13dd47d6-51bf-196f-a224-f1be9bff9d68.png)

エディタには以下のようなコードを書きました。


```javascript

function getFileListInFolder() {
  var folder_id = ’対象のフォルダのID';
  var url = 'https://drive.google.com/drive/folders/' + folder_id,  // URL of Google Drive folder.
      paths = url.split('/'), // Separate URL into an array of strings by separating the string into substrings. 
      folderId = paths[paths.length - 1], // Get a last element of paths array.
      folder = DriveApp.getFolderById(folderId),
      files = folder.getFiles(),
      list = [],
      rowIndex = 1, // The starting row of a range.
      colIndex = 1, // The starting row of a column.
      ss, sheet,range,
      sheetName = 'シート1';
  
  // Creating a data array from a files iterator.
  // Note: Latest file is the first.
  while(files.hasNext()) {
    var buff = files.next();
    list.push([buff.getName(), buff.getUrl()]);
  };
  
  // folder.getFiles()では、ファイルは新しいものが最初に来ます
  // 登録された順にしたいので、reverse() で調整します
  list = list.reverse()
  
  ss = SpreadsheetApp.getActive();
  sheet = ss.getSheetByName(sheetName);
  range = sheet.getRange(rowIndex, colIndex, list.length, list[0].length);

  // 対象の範囲にまとめて書き出します
  range.setValues(list);
}
```

出来上がったら、三角のボタンを押して実行します。
（初回は、実行権限や認証のダイアログがでます）

![GAS.png](https://qiita-image-store.s3.amazonaws.com/0/27976/6b721701-f094-28a4-74f5-ec0c06829056.png)


結果、このように「シート1」に抽出結果が表示されました。

![実行結果.png](https://qiita-image-store.s3.amazonaws.com/0/27976/782387a2-69be-4cc6-b305-ed905deea8a4.png)

## Scriptについての補足

さて、これだけでは簡単なので、もう少し補足してみます。

### 書き出すシートの特定

今回は ss.getSheetByName(‘シート1'); という形で対象のシートを特定しました。
ここでは、**SpreadSheet**クラスのオブジェクトに対してメソッドを発行しています。

- [Class Spreadsheet](https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet)

名前が分かっている場合はいいのですが、最初のシートや最後のシートを対象にする場合は、getSheets() を利用します。

例えば、SpreadSheet.getSheets()[0] で最初のシートとなります。

### ファイルの一覧を取得する

フォルダの中のファイル一覧を取得するのは、この箇所です。

```
      folder = DriveApp.getFolderById(folderId),
      files = folder.getFiles(),
```

フォルダのIDからフォルダのオブジェクトを取得します。
次に、getFiles()メソッドで、一覧そのものではなくiteratorを取得します。

- [getFiles()](https://developers.google.com/apps-script/reference/drive/drive-app#getFiles())
- [Class FileIterator](https://developers.google.com/apps-script/reference/drive/file-iterator)

コメントで触れている通り、getFiles()を利用してループでファイルを抽出する場合、作成日時の新しいものから先に取り出されます。

もしSpreadSheetには登録したものを最初に書き出したい場合、一覧を逆順にします。

### データを書き出す

書き出すシートを特定したら、セルの位置を特定してデータを登録する流れになります。
setValue(value) の場合は、セル1つに対して値を設定となりますが、今回は、setValues(Object) を使って、起点のセルから範囲選択をして、そこにデータの配列（二次元配列）をまとめて渡して書き込んでいます。

- https://developers.google.com/apps-script/reference/spreadsheet/range#setValues(Object)

```
  range = sheet.getRange(rowIndex, colIndex, list.length, list[0].length);

  // 対象の範囲にまとめて書き出します
  range.setValues(list);
```

### 作成の時に気づいた点

Apps Scriptでもデバッグはできますが、できるだけ小さい処理に分割して、こまかく実行して動作チェックをするのがいいなというのは、ここでも感じました。
（なんにしても同じですね！)

### 参考情報

- [
Google Apps Script Video Library](https://developers.google.com/apps-script/guides/videos)
 - 軽く聞いただけですが、聞き取りやすい英語だったのでヒアリングの勉強にもなります...
- https://github.com/gsuitedevs/apps-script-samples
  - GitHub上のサンプルスクリプト集です
- https://script.google.com/
  - すべてのApps Scriptが参照 / 変更可能です

## まとめ

今回は特に解説もなく、これだけです...。

もし対象のフォルダは定期的にデータがアップされるような性質のものでしたら、Apps Scriptを定期実行させて一覧を更新し、Slackに通知したりもいろいろできるかな、と思います。