Google Apps Scriptでドライブのフォルダやファイルを取得してみる

  • このエントリーをはてなブックマークに追加
  • Pocket
  • LINEで送る
icon_for_DriveApp_getFiles_and_getFolders

今回の記事は、Google Apps Scriptを使ってGoogleドライブ上のファイルを取得する方法を紹介していきます。GASでフォルダやファイルを取得する方法はそれぞれいくつかあるのですが、取得方法にそれぞれ結構な違いがありますのでこの記事ではそれぞれの使い方をまとめて紹介したいと思います。GASでドライブ上のフォルダやファイルに対して処理を行う場合には、まずは対象のアイテム(フォルダやファイル)を取得する必要があります。

対象アイテムへの処理とは例えば、『アイテム名を取得/変更する』『オーナーを取得/変更する』『共有アカウントを取得/変更する』『アイテムを複製/削除する』このような処理があります。上記は一例ですが、このような処理を行う場合にはまず対象アイテムを取得するということが基本となります。今回、フォルダとファイルの取得について一つの記事で執筆しようとしていますが、Googleドライブではフォルダとファイルの違いがあまりないため、同じ記事で書いていくことにしました。

ちなみに、今回ご紹介するDriveAppではフォルダやファイルは別のメソッドで取得をしていきますが、Advanced Google ServicesのDrive APIを使うと、1つの処理でフォルダやファイルを区別なく取得できます。このことからも、Googleドライブ上ではフォルダやファイルの区別があまりないことが少し理解できるかと思います。

さて、前置きが長くなってしまいましたが、本題に入っていきたいと思います。

対象アイテムを取得するコード

  1. getFolderById(アイテムIDを使って指定フォルダを取得)
  2. getFolders(対象フォルダ内のフォルダをすべて取得)
  3. getFoldersByName(対象フォルダ内の指定したフォルダ名に一致するフォルダをすべて取得)
  4. getRootFolder(マイドライブを取得)
  5. getTrashedFolders(ゴミ箱に捨てられたフォルダを取得)
  6. searchFolders(検索クエリに合致するフォルダをすべて取得)
  7. getFileById(アイテムIDを使って指定ファイルを取得)
  8. getFiles(対象フォルダ内のファイルをすべて取得)
  9. getFilesByName(対象フォルダ内の指定したファイル名に一致するファイルをすべて取得)
  10. getFilesByType(対象フォルダ内の指定したファイルタイプに一致するファイルをすべて取得)
  11. getTrashedFiles(ゴミ箱に捨てられたファイルを取得)
  12. searchFiles(検索クエリに合致するファイルをすべて取得)

コードとしては、フォルダ取得用とファイル取得用に分かれていますが、使い方はほとんど同じですので、片方の使い方がわかればもう片方の使い方にも簡単に応用することができます。

上記コードの中で気づいた方もいると思いますが、対象アイテムを取得する方法としては、1つのアイテムを取得するメソッドと複数のアイテムを取得するメソッドがあります。1つのアイテムを取得するコードではファイル自体を取得できていますので、そのままFolderクラスFileクラスのメソッドを利用することが可能です。複数のアイテムを取得するコードではイテレータとしてアイテムが取得されていますので、FolderIteratorクラスやFileIteratorクラスの処理を行うことで最終的にFolderクラスやFileクラスのメソッドを利用できるようになります。

サンプルコード

それでは、これからサンプルコードを用いて実際のコードの書き方について学んでいきます。

getFolderById(id)

『引数に入れる値』

  • id(文字列) — 取得したいフォルダIDを代入
DriveApp.getFolderByIdサンプルコード
//ID指定でフォルダを取得するプログラム
function sampleCodeForDriveAppGetFolderById() {
  var id = "1ohmSR625ShiR0hoBr9DFL7Zkh9VX8jXH"; //フォルダID
  var folder = DriveApp.getFolderById(id);
  Logger.log(folder);
}

『 変数の説明 』

id = フォルダID
folder = 取得されたフォルダ

フォルダのIDの確認方法は、ブラウザ上でドライブを開き、対象のフォルダにアクセスしたときのURLから確認ができます。『https://drive.google.com/drive/folders/1ohmSR625ShiR0hoBr9DFL7Zkh9VX8jXH』赤文字の部分がフォルダ固有のIDになりますので、赤字部分をコピーしてid部分に貼り付けてください。上記コードをコピーして何も変更せずに実行してからCtrl + Enterを押してログを確認してみると『DriveAppのフォルダ/ファイルの取得』がログに表示されます。IDを入れ替えて実行した場合は置き換えたIDのフォルダ名が表示されます。上記コードの実行ログは下記スクリーンショットをご確認ください。

logForDriveApp.getFolderById

getFolders()

DriveApp.getFoldersサンプルコード
//対象フォルダにあるすべてのフォルダを取得するプログラム
function sampleCodeForDriveAppGetFolders1() {
  var id = "1ohmSR625ShiR0hoBr9DFL7Zkh9VX8jXH"; //フォルダID
  var target = DriveApp.getFolderById(id);
  var folders = target.getFolders();
  while (folders.hasNext()) {
    var folder = folders.next();
    var folderName = folder.getName();
    Logger.log(folderName);
  }
}

//マイドライブにあるすべてのフォルダを取得するプログラム
function sampleCodeForDriveAppGetFolders2() {
  var myDrive = DriveApp.getRootFolder();
  var folders = myDrive.getFolders();
  while (folders.hasNext()) {
    var folder = folders.next();
    var folderName = folder.getName();
    Logger.log(folderName);
  }
}

//ドライブ上にあるすべてのフォルダを取得するプログラム(フォルダ数によっては処理がタイムアウトします)
function sampleCodeForDriveAppGetFolders3() {
  var folders = DriveApp.getFolders();
  while (folders.hasNext()) {
    var folder = folders.next();
    var folderName = folder.getName();
    Logger.log(folderName);
  }
}

『 変数の説明 』

id = フォルダID
target = ID指定したフォルダ
myDrive = マイドライブフォルダ
folders = FolderIterator
folder = 1つのフォルダ
folderName = フォルダ名

getFoldersメソッドはFolderIteratorを返しますので、イテレータの処理をしてフォルダ名を取得しています。FolderIteratorで取得する場合には取得される順番はめちゃくちゃですので、昇順や降順で取得したい場合にはその後の処理で並べ替えをする必要があります。Drive APIのメソッドであれば取得する順番を指定できますので取得する順番を制御したい場合はDrive APIを使うのが良いかもしれません。上記のコードもそのままコピペをすれば利用できます。フォルダを指定せずに実行する『sampleCodeForDriveAppGetFolders3』については、ドライブに作成したフォルダ数が多いとエラーになる場合があります。実行が完了してからCtrl + Enterでログを確認してみると、それぞれ対象フォルダ内にあるフォルダ名がすべてログ出力されていると思います。参考までに、sampleCodeForDriveAppGetFolders1 を実行したときのログスクリーンショットを下記に掲載します。

logForDriveApp.getFolders

getFoldersByName(name)

『引数に入れる値』

  • name(文字列) — 取得したいフォルダ名を代入
DriveApp.getFoldersByNameサンプルコード
//対象フォルダ内にある指定フォルダ名と一致するすべてのフォルダ取得するプログラム
function sampleCodeForDriveAppGetFoldersByName1() {
  var id = "1ohmSR625ShiR0hoBr9DFL7Zkh9VX8jXH"; //フォルダID
  var name = "子フォルダ①";
  var target = DriveApp.getFolderById(id);
  var folders = target.getFoldersByName(name);
  while (folders.hasNext()) {
    var folder = folders.next();
    var folderName = folder.getName();
    Logger.log(folderName);
  }
}

//マイドライブのフォルダをすべて取得するプログラム
function sampleCodeForDriveAppGetFoldersByName2() {
  var myDrive = DriveApp.getRootFolder();
  var name = "子フォルダ①";
  var folders = myDrive.getFoldersByName(name);
  while (folders.hasNext()) {
    var folder = folders.next();
    var folderName = folder.getName();
    Logger.log(folderName);
  }
}

//ドライブ上のフォルダをすべて取得するプログラム(フォルダ数によっては処理がタイムアウトします)
function sampleCodeForDriveAppGetFoldersByName3() {
  var name = "子フォルダ①";
  var folders = DriveApp.getFoldersByName(name);
  while (folders.hasNext()) {
    var folder = folders.next();
    var folderName = folder.getName();
    Logger.log(folderName);
  }
}

『 変数の説明 』

id = フォルダID
name = 検索するフォルダ名
target = ID指定したフォルダ
myDrive = マイドライブフォルダ
folders = FolderIterator
folder = 1つのフォルダ
folderName = フォルダ名

getFoldersByNameメソッドもFolderIteratorを返しますので、イテレータの処理をしてフォルダ名を取得しています。上記コードでは『子フォルダ①』というフォルダを検索ワードとして指定しています。実行が完了してからCtrl + Enterでログを確認してみると、対象フォルダ内に子フォルダ①というフォルダがあればログとしてフォルダ名が出力されていると思います。参考までに、sampleCodeForDriveAppGetFoldersByName1 を実行したときのログスクリーンショットを下記に掲載します。

logForDriveApp.getFoldersByName

getRootFolder()

DriveApp.getRootFolderサンプルコード
//マイドライブフォルダを取得するプログラム
function sampleCodeForDriveAppGetRootFolder() {
  var myDrive = DriveApp.getRootFolder();
  Logger.log(myDrive);
}

『 変数の説明 』

myDrive = マイドライブフォルダ

getRootFolderメソッドではマイドライブを取得します。上記コードを何も変更せずに実行した後、Ctrl + Enterを押してログを確認すると『マイドライブ』がログに表示されます。下記スクリーンショットをご確認ください。

logForDriveApp.getRootFolder

getTrashedFolders()

DriveApp.getTrashedFoldersサンプルコード
//ゴミ箱に捨てられたすべてのフォルダを取得するプログラム
function sampleCodeForDriveAppGetTrashedFolders() {
  var trashedFolders = DriveApp.getTrashedFolders();
  while (trashedFolders.hasNext()) {
    var folder = trashedFolders.next();
    var folderName = folder.getName();
    Logger.log(folderName);
  }
}

『 変数の説明 』

trashedFolders = FolderIterator
folder = 1つのフォルダ
folderName = フォルダ名

getTrashedFoldersメソッドもFolderIteratorを返しますので、イテレータの処理をしてフォルダ名を取得しています。実行が完了してからCtrl + Enterでログを確認してみると、ログとしてゴミ箱に入っているフォルダ名が出力されていると思います。

logForDriveApp.getTrashedFolders

searchFolders(params)

『引数に入れる値』

  • params(文字列) — 検索クエリを代入
DriveApp.searchFoldersサンプルコード
//検索クエリに一致するすべてのフォルダを取得するプログラム
function sampleCodeForDriveAppSearchFolders() {
  var params = "title contains '子フォルダ'";
  var searchedFolders = DriveApp.searchFolders(params);
  while (searchedFolders.hasNext()) {
    var folder = searchedFolders.next();
    var folderName = folder.getName();
    Logger.log(folderName);
  }
}

『 変数の説明 』

params = 検索クエリ
searchedFolders = FolderIterator
folder = 1つのフォルダ
folderName = フォルダ名

searchFoldersメソッドもFolderIteratorを返しますので、イテレータの処理をしてフォルダ名を取得しています。検索パラメータとして指定できる文字列はGoogle Drive SDK Documentation(英文)に記載されています。下記に一応日本語の一覧表を記載しておきます。実行が完了してからCtrl + Enterでログを確認してみると、『子フォルダ』という言葉がファイル名に含まれているフォルダ名が出力されていると思います。

logForDriveApp.searchFolders

クエリ演算子 取得定義
contains 指定した文字列が検索項目に含まれる場合
= 指定した文字列が検索項目に一致する場合
!= 指定した文字列が検索項目に一致しない場合
< 指定した値が検索項目未満の場合
<= 指定した値が検索項目以下の場合
> 指定した値が検索項目を超える場合
>= 指定した値が検索項目以上の場合
in 指定した値がコレクションに含まれる場合
and 複数条件に合致する条件を指定する場合
or いずれかの条件に合致する条件を指定する場合
not 検索条件に合致しない場合
has 指定したパラメータがコレクションに含まれる場合

 

検索項目 使用できるクエリ 使い方
title (フォルダ名) contains, =, != アイテム名を指定します。アイテム名にはシングルクォーテーションをつけて使用します。検索名にシングルクォーテーションが含まれる場合は\(バックスラッシュ)をつけてエスケープします。

例)‘Valentine\’s Day’

fullText contains ファイルに付随するすべてのテキストデータを参照します。ファイル名、詳細説明、ファイル内テキスト、インデックステキストがテキストデータに該当します。いずれかに指定する文字が含まれる場合に検索にクエリに一致します。検索ワードにシングルクォーテーションが含まれる場合は\でエスケープします。
mimeType contains, =, != MIMEタイプで検索します。
modifiedDate <=, <, =, !=, >, => 最終更新日で検索します。指定方法はRFC3339フォーマットです。デフォルトのタイムゾーンはUTCになります。(例)2012-06-04T12:00:00-08:00
lastViewedByMeDate <=, <, =, !=, >, => 自分が最後にファイルを閲覧した日で検索します。指定方法はmodifiedDateと同じです。
trashed =, != ゴミ箱に捨ててあるかどうかで検索します。trueかfalseにて指定。
starred =, =! スター付きかどうかで検索します。trueかfalseにて指定。
parents in 親フォルダのIDで検索。
owners in オーナーアカウントで検索。
writers in 編集者アカウントで検索。
viewers in 閲覧者アカウントで検索。
sharedWithMe =, != 共有アイテムにあるかどうかで検索ができます。trueかfalseにて指定。
properties has ファイルのカスタムプロパティで検索
visivility =, != 共有設定にて検索。使える値はanyoneCanFind, anyoneWithLink, domainCanFind, domainWithLink, Limitedのいずれか。

 

getFileById(id)

『引数に入れる値』

  • id(文字列) — 取得したいファイルIDを代入
DriveApp.getFileByIdサンプルコード
//ID指定でファイルを取得するプログラム
function sampleCodeForDriveAppGetFileById() {
  var id = "1XTvefLwnomP_cEdF7StgXjj37eFMgMZm"; //ファイルID
  var file = DriveApp.getFileById(id);
  Logger.log(file);
}

『 変数の説明 』

id = ファイルID
file = 取得されたファイル

ファイルIDの確認方法はいくつかありますが、1つご紹介すると、ブラウザ上でドライブを開き、対象のファイル名上で右クリックして共有可能なURLを取得から確認ができます。『https://drive.google.com/open?id=1XTvefLwnomP_cEdF7StgXjj37eFMgMZm』赤文字の部分がファイル固有のIDになりますので、赤字部分をコピーしてid部分に貼り付けてください。上記コードをコピーして何も変更せずに実行後、Ctrl + Enterを押してログを確認してみると『Test①.csv』がログに表示されます。下記スクリーンショットをご確認ください。

logForDriveApp.getFileById

getFiles()

DriveApp.getFoldersサンプルコード
//対象フォルダ内のすべてのファイルを取得するプログラム
function sampleCodeForDriveAppGetFiles1() {
  var id = "1ohmSR625ShiR0hoBr9DFL7Zkh9VX8jXH"; //フォルダID
  var target = DriveApp.getFolderById(id);
  var files = target.getFiles();
  while (files.hasNext()) {
    var file = files.next();
    var fileName = file.getName();
    Logger.log(fileName);
  }
}

//マイドライブのすべてのファイルを取得するプログラム
function sampleCodeForDriveAppGetFiles2() {
  var myDrive = DriveApp.getRootFolder();
  var files = myDrive.getFiles();
  while (files.hasNext()) {
    var file = files.next();
    var fileName = file.getName();
    Logger.log(fileName);
  }
}

//ドライブ上のすべてのファイルを取得するプログラム(ファイル数によっては処理がタイムアウトします)
function sampleCodeForDriveAppGetFiles3() {
  var files = DriveApp.getFiles();
  while (files.hasNext()) {
    var file = files.next();
    var fileName = file.getName();
    Logger.log(fileName);
  }
}

『 変数の説明 』

id = フォルダID
target = ID指定したフォルダ
myDrive = マイドライブフォルダ
files = FileIterator
file = 1つのファイル
fileName = ファイル名

getFilesメソッドはFileIteratorを返しますので、イテレータの処理をしてフォルダ名を取得しています。FileIteratorで取得する場合には取得される順番はめちゃくちゃですので、昇順や降順で取得したい場合にはその後の処理で並べ替えをする必要があります。Drive APIのメソッドであれば取得する順番を指定できますので取得する順番を制御したい場合はDrive APIを使うのが良いかもしれません。上記のコードもそのままコピペをすれば利用できます。フォルダを指定せずに実行する『sampleCodeForDriveAppGetFiles3』については、ドライブに格納しているファイル数が多いと処理が長くなりエラーになります。実行が完了してからCtrl + Enterでログを確認してみると、それぞれ対象フォルダ内にあるファイル名がすべてログ出力されていると思います。参考までに、sampleCodeForDriveAppGetFiles1 を実行したときのログスクリーンショットを下記に掲載します。

logForDriveApp.getFiles

getFilesByName(name)

『引数に入れる値』

  • name(文字列) — 取得したいファイル名を代入
DriveApp.getFilesByNameサンプルコード
//対象フォルダ内にある指定ファイル名と一致するすべてのファイル取得するプログラム
function sampleCodeForDriveAppGetFilesByName1() {
  var id = "1ohmSR625ShiR0hoBr9DFL7Zkh9VX8jXH"; //フォルダID
  var name = "Test①.csv";
  var target = DriveApp.getFolderById(id);
  var files = target.getFilesByName(name);
  while (files.hasNext()) {
    var file = files.next();
    var fileName = file.getName();
    Logger.log(fileName);
  }
}

//マイドライブにある指定ファイル名と一致するすべてのファイル取得するプログラム
function sampleCodeForDriveAppGetFilesByName2() {
  var myDrive = DriveApp.getRootFolder();
  var name = "Test①.csv";
  var files = myDrive.getFilesByName(name);
  while (files.hasNext()) {
    var file = files.next();
    var fileName = file.getName();
    Logger.log(fileName);
  }
}

//ドライブ上にある指定ファイル名と一致するすべてのファイル取得するプログラム
function sampleCodeForDriveAppGetFilesByName3() {
  var name = "Test①.csv";
  var files = DriveApp.getFilesByName(name);
  while (files.hasNext()) {
    var file = files.next();
    var fileName = file.getName();
    Logger.log(fileName);
  }
}

『 変数の説明 』

id = フォルダID
name = 検索するフォルダ名
target = ID指定したフォルダ
myDrive = マイドライブフォルダ
files = FileIterator
file = 1つのファイル
fileName = ファイル名

getFilesByNameメソッドもFileIteratorを返しますので、イテレータの処理をしてファイル名を取得しています。上記コードでは『Test①.csv』という文字列を検索ファイル名として指定しています。実行が完了してからCtrl + Enterでログを確認してみると、対象フォルダ内にTest①.csvというフォルダがあればログとしてファイル名が出力されていると思います。参考までに、sampleCodeForDriveAppGetFilesByName1 を実行したときのログスクリーンショットを下記に掲載します。ちなみに、小ネタですが、ドライブでは同じ名前のファイルを1つのフォルダに持つことができます。デスクトップ用クライアント(Backup and Sync)をインストールしている場合はローカル上ではファイル名には(1)というような番号付けがされますが、ブラウザ版Googleドライブでは同じ名前の状態で格納されます。お気づきの方もいるかもしれませんが、今回のメソッドはgetFilesByNameですので、ファイルは複数形で表記されています。同じファイル名のファイルが同一フォルダ内に複数ある場合にはすべてのファイルが取得されます。

みなさんは同じ名前のファイルを①つのフォルダに入れられるの知ってましたか?ひと目でどっちのファイルなのか見分けられなくなりますが、GoogleドライブがIDでファイルを取得していることを理解するにはとても良い参考例だと思います。logForDriveApp.getFileByName

getFilesByType(mimeType)

『引数に入れる値』

  • mimeType(文字列) — 取得したいMIMEタイプを代入
DriveApp.getFilesByTypeサンプルコード
//対象フォルダ内の指定したファイルタイプに合致するすべてのファイルを取得するプログラム
function sampleCodeForDriveAppGetFilesByType1() {
  var mimeType = "text/csv";
  var id = "1ohmSR625ShiR0hoBr9DFL7Zkh9VX8jXH";
  var folder = DriveApp.getFolderById(id);
  var files = folder.getFilesByType(mimeType);
  while (files.hasNext()) {
    var file = files.next();
    var fileName = file.getName();
    Logger.log(fileName);
  }
}

//マイドライブ内の指定したファイルタイプに合致するすべてのファイルを取得するプログラム
function sampleCodeForDriveAppGetFilesByType2() {
  var mimeType = "text/csv";
  var myDrive = DriveApp.getRootFolder();
  var files = myDrive.getFilesByType(mimeType);
  while (files.hasNext()) {
    var file = files.next();
    var fileName = file.getName();
    Logger.log(fileName);
  }
}

//Googleドライブ上にある指定したファイルタイプに合致するすべてのファイルを取得するプログラム(時間がかかる場合があります)
function sampleCodeForDriveAppGetFilesByType() {
  var mimeType = "text/csv";
  var files = DriveApp.getFilesByType(mimeType);
  while (files.hasNext()) {
    var file = files.next();
    var fileName = file.getName();
    Logger.log(fileName);
  }
}

『 変数の説明 』

id = フォルダID
mimeType = 検索するファイルタイプ
target = ID指定したフォルダ
myDrive = マイドライブフォルダ
files = FileIterator
file = 1つのファイル
fileName = ファイル名

getTrashedFilesメソッドもFileIteratorを返しますので、イテレータの処理をしてファイル名を取得しています。実行が完了してからCtrl + Enterでログを確認してみると、ログとして指定のファイルタイプに一致したファイルのファイル名が出力されていると思います。

logForDriveApp.getFilesByType

指定可能なMIMEタイプ

拡張子 MIMEタイプ
Google Docs application/vnd.google-apps.document
Google Forms application/vnd.google-apps.form
Google My Maps application/vnd.google-apps.map
Google Slides application/vnd.google-apps.presentation
Google Apps Script application/vnd.google-apps.script
Google Sites application/vnd.google-apps.site
Google Sheets application/vnd.google-apps.spreadsheet
xls application/vnd.ms-excel
xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
xml text/xml
ods application/vnd.oasis.opendocument.spreadsheet
csv text/csv
tmpl text/plain
pdf application/pdf
php application/x-httpd-php
jpg image/jpeg
png image/png
gif image/gif
bmp image/bmp
txt text/plain
doc application/msword
js text/js
swf application/x-shockwave-flash
mp3 audio/mpeg
zip application/zip
rar application/rar
tar application/tar
arj application/arj
cab application/cab
html text/html
htm text/htm
default application/octet-stream

getTrashedFiles()

DriveApp.getTrashedFilesサンプルコード
//ゴミ箱に捨てられたすべてのファイル取得するプログラム
function sampleCodeForDriveAppGetTrashedFiles() {
  var trashedFiles = DriveApp.getTrashedFiles();
  while (trashedFiles.hasNext()) {
    var file = trashedFiles.next();
    var fileName = files.getName();
    Logger.log(fileName);
  }
}

『 変数の説明 』

trashedFiles = FileIterator
file = 1つのファイル
fileName = ファイル名

getTrashedFilesメソッドもFileIteratorを返しますので、イテレータの処理をしてファイル名を取得しています。実行が完了してからCtrl + Enterでログを確認してみると、ログとしてゴミ箱に入っているファイル名が出力されていると思います。

logForDriveApp.getTrashedFiles

searchFiles(params)

『引数に入れる値』

  • params(文字列) — 検索クエリを代入
DriveApp.searchFilesサンプルコード
//検索クエリに合致するすべてのファイルを取得するプログラム
function sampleCodeForDriveAppSearchFiles() {
  var params = "title contains 'Test'";
  var searchedFiles = DriveApp.searchFiles(params);
  while (searchedFiles.hasNext()) {
    var file = searchedFiles.next();
    var fileName = file.getName();
    Logger.log(fileName);
  }
}

『 変数の説明 』

searchedFiles = FileIterator
file = 1つのファイル
fileName = ファイル名

searchFilesメソッドもFileIteratorを返しますので、イテレータの処理をしてファイル名を取得しています。検索パラメータとして指定できる文字列はsearchFoldersの説明文と同じようにGoogle Drive SDK Documentation(英文)に記載されています。日本語訳の一覧表はsearchFoldersの説明部分を参照してください。。実行が完了してからCtrl + Enterでログを確認してみると、『Test』という言葉がファイル名に含まれているファイルのファイル名が出力されていると思います。

logForDriveApp.searchFiles

イテレータについて

さて、今までの説明の中にイテレータという言葉が何度も出てきましたが、イテレータについて簡単に説明したいと思います。私も概念的なことはなんとなくで理解していますので、詳しく突っ込まれると答えられないですが、なんとなくなイメージとして理解ができるように概要を説明します。

イテレータのイメージとしては私は中身が見えない袋のようなものだと思っています。イテレータには主にhasNext()とnext()という2つのメソッドがあります。hasNext()は袋の中に何かが入っているかどうかを確認するためのメソッドになります。袋の中に何かが入っていればtrue、何も入っていなければfalseを返すメソッドです。一方、next()は袋の中から入っているものを一つずつ取り出すメソッドです。取り出すことで袋の中身が一つずつ少なくなっていくことをイメージしてもらえれば良いかと思います。中身が見えないため、取り出すまでどれが出てくるかわからないといった塩梅です。

今回のサンプルコードでもイテレータの処理を行っているのですが、whileループを使ってループ処理を行っています。whileといえば、評価式がtrueである限りループを繰り返すループ処理になりますが、イテレータの場合、一つずつ取り出していくと最終的には袋の中に何もない状態になります。何もない状態になるとhasNext()が最終的にfalseを返すためイテレータ処理との相性が良いのです。

私も以前ハマった部分の一つですが、イテレータでnext()を行うと、元の変数の要素から取り出した要素がなくなっていきます。このため、1回のループ内で1回以上next()を行ってしまうと想定以上に取り出しを行ってしまうのでご注意ください。例えば、取り出した要素に対してファイル名とファイルIDを取得したい場合に、下記のsampleCodeForIteratorProcess1のようにコードを書いてしまうと想定通りの処理が行なえません。こういう場合は、sampleCodeForIteratorProcess2のように、一度next()で取り出した要素を変数に入れてから処理を行うようにしましょう。

イテレータの例①
//想定通りに処理ができない例
function sampleCodeForIteratorProcess1() {
  var params = "title contains 'Test'";
  var searchedFiles = DriveApp.searchFiles(params);
  while (searchedFiles.hasNext()) {
    var fileName = searchedFiles.next().getName();
    var fileId = searchedFiles.next().getId();
  }
}

//想定通りに処理ができる例
function sampleCodeForIteratorProcess2() {
  var params = "title contains 'Test'";
  var searchedFiles = DriveApp.searchFiles(params);
  while (searchedFiles.hasNext()) {
    var file = searchedFiles.next();
    var fileName = file.getName();
    var fileId = file.getId();
  }
}

なんとなくイメージはつかめてきましたでしょうか?使っていくうちに慣れてくると思います。私もこれ以上の概念的な部分は書籍でも読んだことはないので更に奥深いのかもしれませんが、そこまで理解していなくても問題なく使えています。

まとめ

今回は、Google Apps Scriptを使って、Googleドライブ上のフォルダやファイルを取得するメソッドをご紹介しました。いろいろなメソッドがありますが、使い方はどれもほとんど同じです。単一のファイルで取得するかイテレータとして取得するか。この違いが理解できていればその後の処理もそれほど難しくないと思います。状況に応じてどれを使うべきかを考えてコードを書いていきましょう。GASのドライブ上の処理は比較的時間のかかる処理が多いので、書き方によって処理時間が長くなりすぎてしまいます。処理時間がかかりすぎてしまう場合はコードのどこかに効率的に処理できる部分がないか考えてみましょう。

SNSでもご購読できます。

コメントを残す

*