質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

1964閲覧

(GAS)フォルダ内のファイルの特定シートのセルの値を取得したい

yuiu

総合スコア17

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2018/10/19 00:53

編集2018/10/19 01:46

以前に下記URLで質問し、返答頂いたコードに改良したい。
https://teratail.com/questions/148362

現象:
添付画像(画像①.png)のように取得するフォルダのファイル内にて[集計]シート(const sheetName = "集計";)が存在しないファイルが存在する場合、
スクリプトを実行すると下記エラーが出てしまい、フォルダ内のファイルの特定シートのセルの値を取得できません。
・[TypeError: null のメソッド「getRange」を呼び出せません。]

イメージ説明

追加したい内容
①フォルダのファイル内に[集計]シートが存在するファイルの値のみ取得
※[集計]シートが存在しない場合はスキップするような処理を入れたい。

②添付画像(画像②.png)のように指定したフォルダ(const folderId = "1ZjdNiax9PKRegRA8yfmOoTo4MmYMzyoC"; )内の配下に全てのファイルから集計シートのセルの値を取得したい。
イメージ説明

補足:
①はどうにか解決したいです。
②はできたら・・・解決したい内容となります。
とりあえず①は解決したいと思っております。
よろしくお願いいたします。

※※※コメントに記載している内容についての画像③.png※※※
イメージ説明


以前に解決して頂いたコードとなります。(/questions/148362)
function getFiles(folderId) {

var files = DriveApp.getFolderById(folderId).getFilesByType(MimeType.GOOGLE_SHEETS);
var ret = []
while(files.hasNext()) {
ret.push(files.next().getId());
}
return ret;
}

//実作業
function last_retu() {
const folderId = "1ZjdNiax9PKRegRA8yfmOoTo4MmYMzyoC"; // テストフォルダのid
const sheetName = "集計";
const targetRange = "H:H";
var files = getFiles(folderId);
var totals = []; //結果が入るやつ
files.forEach(function(element, index, array) { //シートidを繰り返しで処理
var sh = SpreadsheetApp.openById(element).getSheetByName(sheetName);
//H列の最終行を取得
var lr = sh.getRange(targetRange).getLastRow();
totals.push(sh.getRange(lr, 8).getValue());//取得した最終行の(最終行, 列の番号)
});

//以下、質問のまま
//取得した時間の書き出すシート
var spreadsheet = SpreadsheetApp.openById('1wyhhUB5GhFihJ9GdMpyUKgdiph5CqpzawomT-D4GFU4');
var sheet = spreadsheet.getSheetByName('取得した時間を書き込む');

//配列でtestcodeファイル内の「取得した時間を書き込む」シートに書きこむ
var ary = [[]];
for (var i=0; i<totals.length; i++) {
ary[0].push(totals[i]);
}
sheet.getRange(1,1,1,ary[0].length).setValues(ary);
}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

下記を足していただいて

javascript

1function getSubDirs(folderId) { 2 const dirIter = DriveApp.getFolderById(folderId).getFolders(); 3 var dirIds = []; 4 while(dirIter.hasNext()) { 5 dirIds.push(dirIter.next().getId()); 6 } 7 dirIds.forEach(function(element, index, aray) { 8 dirIds = dirIds.concat(getSubDirs(element)); 9 }); 10 return dirIds; 11} 12function getFilesWithSubDirs(folderId) { 13 const dirs = [folderId].concat(getSubDirs(folderId)); 14 var fileIds = []; 15 dirs.forEach(function(element, index, array){ 16 fileIds = fileIds.concat(getFiles(element)); 17 }); 18 return fileIds; 19}

function last_retu()の中の

javascript

1// var files = getFiles(folderId); //<-ここを 2var files = getFilesWithSubDirs(folderId); // こうする

でどうでしょう?

ファイルを準備するのがたいへんなので、テストはしてませんが。

投稿2018/10/24 03:44

編集2018/10/25 06:36
papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yuiu

2018/10/25 06:25

return fielIds; を  return fileIds; に書き換えたら期待通りの集計ができました!! ありがとうございました!!!m(_ _)m
papinianus

2018/10/25 06:38

ご指摘感謝します。回答を修正しました。 再帰性があり、API呼び出しを多用しているので、あまり複雑なフォルダ構成にすると途中で処理が打ち切られる危険がありますので、ご注意ください。
guest

0

javascript

1var sh = SpreadsheetApp.openById(element).getSheetByName(sheetName); 2if(sh === null) {return;} //これを追記 3//H列の最終行を取得

投稿2018/10/19 01:07

papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

papinianus

2018/10/19 01:12

2.の問題についてはこちらとしては意図的です。 そもそもシートしか取らないように積極的に制限しています。 フォルダをなんとかすることはできますが、仕様が必要です。 +テスト ++フォルダA +++フォルダAA ++++フォルダAAA ++++-シートAAA1 ++-シートA1 ++フォルダB +-シート1 +-シート2 このように、テスト(というか最上位のフォルダ)に対して、複数の子フォルダがあるのか、またその子のなかに孫、ひ孫がいるのかなど具体的にお願いします。
yuiu

2018/10/19 01:13

ありがとうございます!!!! ①は解決できました!
yuiu

2018/10/19 01:22 編集

②について +テスト ++フォルダA ++-シートA1 ++フォルダB ++-シートB1 +-シート1 +-シート2 という構造になっています。 よって階層のお話としては、フォルダ内に1つフォルダが存在するイメージです。 フォルダA(スクリプトに記載しているconst folderIdの指定するフォルダ) > フォルダB内にファイルがあります。  ※フォルダAの配下には3つほどフォルダが存在します。 これ以上は深くなりません。
yuiu

2018/10/19 01:23 編集

はええな  →返答:if(sh === null) {return;} こちらを入れて実行したら集計シートのないファイルはスキップできました! papinianus様の返答も早くてビックリしました・・・!
papinianus

2018/10/19 01:32

自分の図が下手だったせいで逆に理解できませんでした。 ・テストの下にフォルダAがあり、さらにAの中に3フォルダあって、それら3つの中にはフォルダはない、でOK? ・テストの下にフォルダBがある?それともテスト→フォルダA→フォルダB?どちらでしょう?
yuiu

2018/10/19 01:52

申し訳ございません。 テストフォルダの配下にフォルダA, Bがあります。 フォルダA,Bの配下にはフォルダはないです。 ※フォルダA,Bは同じ階層です。  補足にイメージ(画像③.png)を添付しました。   (この画像にはフォルダBは表記されていませんが、フォルダAと同じ階層となります。)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問