Yuki's bnb blog

こんにちは!Yukiといいます。本業のかたわら大阪で2016年夏から民泊運営のお手伝いをしています。民泊業務に関する様々なことを自動化・効率化したいと思い日々活動しています。 お気軽にコメント・お問い合わせください :) TOEICスコア 985

【コピペでOK!】フォルダー直下の全ファイルの共有リンクを一括作成する方法

f:id:yukibnb:20191201154402p:plain

こんにちは!
Yuki (@yukibnb) です。

前回はGoogle Apps Script (GAS) でフォルダーを指定する方法を紹介しました。
www.yukibnb.com

今回は一歩進んで、GASでフォルダー直下の全ファイルの共有リンク (共有URL) を一括作成してスプレッドシートにペーストする方法を紹介します。

以下のようにファイルをひとつずつ手作業で共有リンク作成するのって面倒ですよね。GASを使えば複数ファイルの共有リンクを一括で作成できます。
f:id:yukibnb:20191201124505g:plain

 

完成イメージ

指定したフォルダー直下の全ファイルの共有リンクをスプレッドシートに書き出します。

f:id:yukibnb:20191201125606g:plain
 
上記動画では「チェックインガイド」フォルダー直下に保存されているチェックインガイドPDF7個の共有リンクを一括作成し、スプレッドシートにペーストしました。

7個ぐらいなら手作業でできないこともないですが手間ですよね。数十個ともなると手作業でするのは非効率ですし精神的にも苦痛です。

ではGASのコードを見ていきましょう!コピペで使用できます!

 

コピペでOK!共有リンク一括作成するためのコード

以下のコードをそのままコピペして使用できます

コメントを多めに書いていますが、大事なポイントはさらに詳しく解説します。

memo

フォルダーIDはみなさん自身のものに置き換えてください。フォルダーIDが何かわからない場合、以下記事にてフォルダーIDの確認方法をご覧ください。
【簡単!】GASでフォルダーを指定する方法

function createSharedUrl() {
  //アクティブなシートを取得する
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sh = ss.getActiveSheet();
  
  //変数folderに指定したフォルダーを格納する
  //★★★ フォルダーIDを記入 ★★★
  var folder = DriveApp.getFolderById("フォルダーID");
  
  //フォルダー内の全ファイルを変数folderFilesに格納する
  //変数folderFiles格納されるデータはイテレーターという形式
  //※フォルダー直下のファイルのみ格納する
  var folderFiles = folder.getFiles();
  
  //ファイル名を格納するための空の配列を宣言する
  var allFiles = [];
  
  //変数folderFilesに格納されている全ファイルのファイル名と
  //共有リンクを配列allFilesに二次元配列で格納する
  while(folderFiles.hasNext()) {
    //配列allFilesに追加する配列(ファイル名と共有リンク)を
    //ループ中に一時的に格納するための空の配列tempFileを宣言する
    var tempFile = [];
    
    //変数folderFilesからファイルのイテレーターをひとつ取り出し
    //変数fileIteratorに格納する
    var fileIterator = folderFiles.next();
    
    //ファイル名を取得する
    var fileName = fileIterator.getName();
    
    //ファイルIDを取得し、ファイルIDをもとにファイルを
    //指定し変数fileに格納する
    var fileId = fileIterator.getId();
    var file = DriveApp.getFileById(fileId);
    
    //変数fileの共有設定を「リンクを知っている全員が閲覧化」に変更する
    file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
    
    //共有リンクを変数shareUrlに格納する
    var shareUrl = file.getUrl();
    
    //配列tempFileにファイル名と共有リンクを格納する
    //この時点で配列tempFileは以下のようになっている
    //tempFile = [ファイル名, 共有リンク]
    tempFile.push(fileName);
    tempFile.push(shareUrl);
    
    //配列tempFileを配列allFilesに格納する
    //配列の中に配列を入れるのでallFilesは
    //以下のような二次元配列になる
    //allFiles = [[ファイル名1, 共有リンク1],[ファイル名2,共有リンク2],....]
    allFiles.push(tempFile);  
  }
    
  //配列allFiles内の要素数、つまり必要な行数を確認する
  var numRow = allFiles.length;
  
  //配列allFiles内の一つ目レコードの要素数、つまり必要な列数を確認する
  //今回はレコードの要素は「ファイル名」と「共有リンク」なので2になる
  var numCol = allFiles[0].length;
  
  //アクティブなシートの2行目にペースト
  sh.getRange(2,1, numRow, numCol).setValues(allFiles);
}

 

ポイントを徹底解説!

GASで行った処理のポイントを細かく紹介します!

「細かいことはいいから使えたらいい!」という方や、GAS内のコメントで十分という方はこの項目は飛ばして頂いて大丈夫です。

 

スプレッドシートとシートを指定する

ファイル名と共有リンクを書き出すためのスプレッドシートとシートを指定します。

  //アクティブなシートを取得する
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sh = ss.getActiveSheet();

上記はアクティブなスプレッドシートのアクティブなシートを取り出しています。

スプレッドシートやシートを細かく指定したい場合以下のようなコードを使用してください。

  var ss = SpreadsheetApp.openById(スプレッドシートID);
  var sh = ss.getSheetByName(シート名);

 
スプレッドシートやシートの指定方法は以下記事にて詳しく紹介しています。

www.yukibnb.com

www.yukibnb.com

 

指定したフォルダー直下のファイル情報を取得する

指定したフォルダー直下の全てのファイル情報を取得し変数folderFilesに格納します。

変数folderFilesには配列ではなくイテレーターという形式でファイル情報が格納されています。

  //変数folderに指定したフォルダーを格納する
  //★★★ フォルダーIDを記入 ★★★
  var folder = DriveApp.getFolderById("フォルダーID");
  
  //フォルダー内の全ファイルを変数folderFilesに格納する
  //変数folderFilesに格納されるデータはイテレーターという形式
  //※フォルダー直下のファイルのみ格納する
  var folderFiles = folder.getFiles();

 

空の配列を宣言する

空の配列allFilesを宣言します。

現段階では「とりあえず箱だけ用意した」という状況です。

以降の処理でこの配列allFilesに二次元配列形式でデータを格納していきます。

そして最終的にこの配列allFilesをシートにペーストします。

  //ファイル名を格納するための空の配列を宣言する
  var allFiles = [];

 

変数folderFilesからファイル情報をひとつずつ取り出す

変数folderFilesにはフォルダー直下のすべてのファイル情報がイテレーターという形式で格納されています。

while(folderFiles.hasNext()) {}」のループ内で以下のような処理を行います。

  1. 空の配列tempFileを作成する
  2. 変数folderFilesからファイルイテレーターをひとつ取り出す
  3. (2)からファイル名を取り出す
  4. (2)からファイルIDを取り出す
  5. (4)のファイルIDをもとにファイルを指定し共有設定を行う
  6. (5)をもとに共有リンクを作成する
  7. 配列tempFilesにファイル名と共有リンクを格納する
  8. 配列tempFilesを配列allFilesに格納する
  9. (1)~(8)をループ
  10. すべてのファイル情報の処理を終えるとループがストップする
ひとつずつ見ていきましょう!  

1. 空の配列tempFileを作成

まず空の配列tempFileを作成します。

そして以降のループ内でファイル名を共有リンクを配列tempFileに格納します。格納すると以下のようになります。

tempFile = [ファイル名, 共有URL]

ループが一周する最後に配列allFilesに配列tempFileを格納します。そうすることで配列allFilesは二次元配列となり、ループを重ねるごとに以下のようにファイル名と共有リンクが蓄積されていきます。

allFiles = [[ファイル名1, 共有リンク1], [ファイル名2,共有リンク2], [ファイル名3,共有リンク3]....

ループ内に配列tempFileを置き、ループの最初に空の配列tempFileを宣言することが重要です。そうすることでループが一周する度に配列tempFileの中身が空になるため、配列allFilesの中のデータが重複しなくなります。

   //配列allFilesに追加する配列(ファイル名と共有リンク)を
  //ループ中に一時的に格納するための空の配列tempFileを宣言する
  var tempFile = [];

 

2. 変数folderFilesからファイルイテレーターをひとつ取り出す

変数folderFilesにはフォルダー直下の全てのファイル情報が含まれています。

ループ内でひとつずつファイルイテレーターを取り出し、変数fileIteratorに格納します。

その変数fileIteratorからファイル名を取り出したりファイルIDを取り出したりします。

  //変数folderFilesからファイルのイテレーターをひとつ取り出し
  //変数fileIteratorに格納する
  var fileIterator = folderFiles.next();

 

3. (2)からファイル名を取り出す

変数fileIteratorからファイル名を取り出し、変数fileNameに格納します。

ファイル名を取り出すには「getName()メソッド」を使用します。

  //ファイル名を取得する
  var fileName = fileIterator.getName();

 

4. (2)からファイルIDを取り出す

変数fileIteratorからファイルIDを取り出し、変数fileIdに格納します。

ファイルイテレーターに対してリンク(URL)を取得することはできますが、直接共有設定を編集することはできません。そのため、まずファイルIDを取り出しからそれを元に共有設定を編集します。

  var fileId = fileIterator.getId();

 

5. (4)のファイルIDをもとにファイルを指定し共有設定を行う

変数fileIdに格納したファイルIDをもとにファイルを指定し、変数fileに格納します。

そして変数fileに対して「setSharing()メソッド」を使用することで共有設定を行います。

今回は「リンクを知っている全員が閲覧化」を設定しました。

  var file = DriveApp.getFileById(fileId);
  
  //変数fileの共有設定を「リンクを知っている全員が閲覧化」に変更する
  file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);

 
setSharing()メソッド」の公式はこのようになります。
f:id:yukibnb:20191201142152j:plain

「対象者」は正確には「AccessType」と言います。ファイルを誰に共有するか設定できます。

「DriveApp.Access.ANYONE_WITH_LINK」を以下のように置き換え可能です。

AccessType 内容
DriveApp.Access.ANYONE 一般公開:
検索結果にも表示されるようになり、インターネット上の誰でもアクセスできます。
DriveApp.Access.ANYONE_WITH_LINK リンクを知っている全員:
共有リンクを知っている人であれば誰でもアクセスできます。
DriveApp.Access.DOMAIN ドメイン内で公開:
Google Workspace (旧G Suite) を使っている組織の場合、そのドメイン内の誰でも検索しアクセスできます。
DriveApp.Access.DOMAIN_WITH_LINK ドメイン内でリンクを知っている全員:
ドメイン内かつ共有リンクを知っている人であれば誰でもアクセスできます。
DriveApp.Access.PRIVATE 制限付き (プライベート):
ファイルを共有した相手のみアクセスできます。

 
「権限」は正確には「permissionType」と言います。

共有した相手がファイルに対してどのような行動をすることができるか設定できます。

「DriveApp.Permission.VIEW」を以下のように置き換え可能です。

permissionType 内容
DriveApp.Permission.VIEW 閲覧者:
ファイルを閲覧のみできます。コメントや編集はできません。
DriveApp.Permission.COMMENT コメント可:
ファイルを閲覧でき、コメントも残すことができます。編集はできません。
DriveApp.Permission.EDIT 編集者:
ファイルを編集することができます。

 

6. (5)をもとに共有リンクを作成する

「setSharing()メソッド」はあくまで共有設定を行うだけで、共有リンク自体は作成しません。

そのため共有設定が終わった後に共有リンクを作成し、変数shareUrlに格納します。

getUrl()メソッド」を使用し、ファイルのリンクを取得します。

※「getUrl()メソッド」はあくまでファイルのリンクを取得するメソッドです。ファイルのリンクを取得したとしても正しく共有設定できていないと意図通りにならないため、共有リンクを作成したい場合は「setSharing()メソッド」とセットで使用ください。

  //共有URLを変数shareUrlに格納する
  var shareUrl = file.getUrl();

 

7. 配列tempFIlesにファイル名と共有リンクを格納する

現時点で変数fileNameにはファイル名が、変数shareUrlには共有リンクが格納されています。

これらを空の配列tempFileに格納します。

push()メソッド」を使って配列tempFileに格納します。

  //配列tempFileにファイル名と共有リンクを格納する
  //この時点で配列tempFileは以下のようになっている
  //tempFile = [ファイル名, 共有URL]
  tempFile.push(fileName);
  tempFile.push(shareUrl);

 

8. 配列tempFilesを配列allFilesに格納する

現時点で配列tempFileは以下のようになっています。

tempFile = [ファイル名1, 共有リンク1]

この配列tempFileを配列allFilesに格納します。格納するとループの一週目が終了です。

  //配列tempFileを配列allFilesに格納する
  //配列の中に配列を入れるのでallFilesは
  //以下のような二次元配列になる
  //allFiles = [[ファイル名1, 共有リンク1],[ファイル名2,共有リンク2],....]
  allFiles.push(tempFile); 

 

9. (1)~(8)をループ

現時点(ループ一週目終了時点)で配列allFilesは以下のようになっています。

allFiles = [[ファイル名1, 共有リンク1]]

配列の中に配列があるので二次元配列になっています。

一週目のループが終了したので、またループのはじめから開始して2つ目のファイルを処理します。

 

10. すべてのファイル情報の処理を終えるとループがストップする

ループがストップすると配列allFilesには以下のようにフォルダー直下の全てのファイル情報が格納されます。

allFiles = [[ファイル名1, 共有リンク1],[ファイル名2,共有リンク2],....]

見やすくすると以下のような状態です。

f:id:yukibnb:20191201150314p:plain

 
あとは配列allFilesをスプレッドシートのシートにペーストすれば完了です!

二次元配列がややこしいという方はよければ以下解説記事をご覧ください。
www.yukibnb.com

 

ペーストするために必要な行数と列数を計算する

シートに二次元配列をペーストするには、貼り付ける範囲「getRange()」と貼り付ける二次元配列の値「setValues()」の行数と列数が一致する必要があります。

以下のような場合はペーストできずエラーとなります。

f:id:yukibnb:20191201151809p:plain

 
今回のGASでは行数、列数は以下となります。

  • 行数: ファイル数 (内側の赤色括弧の数)
  • 列数: ペーストする項目数 (内側の括弧の中に入っている要素数)

今回の列数は2で固定ですがファイル数は皆さんそれぞれです。

そのため「getRange()」で指定する行数は固定ではなく、ファイル数に応じて変動させなければなりません。

行数は以下画像の赤色括弧の数を数えて、変数numRowに格納します。

列数は一つ目の赤色括弧の中のデータの数を数えて、変数numColに格納します。(今回は列数2ですが、カスタマイズしやすいように列数も計算しました)

f:id:yukibnb:20191201150314p:plain

  //配列allFiles内の要素数、つまり必要な行数を確認する
  var numRow = allFiles.length;
  
  //配列allFiles内の一つ目レコードの要素数、つまり必要な列数を確認する
  //今回はレコードの要素は「ファイル名」と「共有リンク」なので2になる
  var numCol = allFiles[0].length;

 

シートにペーストして完了!

「getRange()」で指定する行数、列数を計算できたので、いよいよ後はペーストするだけです。

  //アクティブなシートの2行目にペースト
  sh.getRange(2,1, numRow, numCol).setValues(allFiles);

 
貼り付ける範囲「getRange()」と貼り付ける二次元配列の値「setValues()」の行数と列数が一致したため、エラーなく貼り付けることができました。

f:id:yukibnb:20191201161241p:plain

 
無事完了です!
f:id:yukibnb:20191201125606g:plain

まとめ

今回はGASでフォルダー直下の全ファイルの共有リンク (共有URL) を一括作成してスプレッドシートにペーストする方法を紹介しました。

紹介したGASのコードを丸々コピペしてフォルダーIDを置き換えるだけで使用できます。

内部でどういう処理をしているか細かく知りたい、カスタマイズして使いたいという方は細かい解説がお役に立てればうれしいです。

今後もGASを活用した業務効率化のヒントをご紹介しますのでご期待ください!