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

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

新規登録して質問してみよう
ただいま回答率
85.47%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

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

Q&A

解決済

1回答

1443閲覧

【GAS】フォルダ内の全ファイルに対し処理を行う際の処理順

donguriko

総合スコア30

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

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

0グッド

2クリップ

投稿2023/03/26 07:54

編集2023/03/26 07:58

前提

・親フォルダ直下にマージファイルがあり、そこにGASを登録。

・子フォルダ内にGAS処理をしたいファイルが複数入っています。
フォルダ内の全ファイルに対し、総あたりでGAS処理をしたい。

<GAS処理内容>
子フォルダ内のファイルの内容の一部を抜粋し、
親フォルダ直下のマージファイルの指定シート※にコピーしたい。

※転記先シートは全4種。
工程①マージ、工程②マージ、二次マージ、ALLマージ
各シートへの転記PGMはそれぞれ独立したfunctionとし、
別のボタンに割付しています。 

(コピー元イメージ)
イメージ説明

(マージファイルイメージ)
イメージ説明

やりたいこと

子フォルダ内で総あたり処理する際、ファイル名順等 決まった
順番で処理したい。

(例)
ファイル1(No111111)、ファイル2(No222222)、ファイル3(No333333)
の3ファイル格納の場合毎回、左→右の順で 
ファイル1→ファイル2→ファイル3とマージファイルに転記してほしい。

発生している問題

動作確認の際、タイミングの問題なのか処理順が
1→2→3
2→3→1 等 変化し、安定しない。

処理順を指定してGAS処理をさせることは可能でしょうか?

それとも、その時の回線? 等の状況次第のため、処理順の
コントロールは難しいので、いったん処理順を気にせず、
マージシートに書き出し、あとで整える方が確実でしょうか?

後者の場合、丸投げで大変申し訳ありませんが、
列方向でソートをかける方法が思いつきません。
何かよい方法がないかアドバイスをいただけないでしょうか?

該当のソースコード

以下、工程①マージシートへの転記処理のコード全文です。

GAS

1function copyToMergeSheet() { 2 3 //▼転記元ファイルの指定 4 //Ss変換済フォルダ内の全ファイルをSsFilesとして取得 5 //Ss変換済フォルダのフォルダID FromfIdはxlsToSs変換処理用ファイルprocessSsのはじめにシート_セルC10 6 7 //xlsToSs変換処理用ファイル 8 //https://docs.google.com/spreadsheets/d/  省略 /edit#gid=1045004046 9 //ファイルID:省略 10 const processSs = SpreadsheetApp.openById(' 省略 '); 11 const FromfId = processSs.getSheetByName('はじめに').getRange(10, 4, 1, 1).getValue(); 12 console.log('FromfId ' + FromfId); 13 14 //Ss変換済フォルダFromFolId内の全ファイルをSsFilesとして取得 15 const SsFiles = DriveApp.getFolderById(FromfId).getFiles(); 16 17 //const FromSheet = PrimSs.getSheets)[0]; //左から1番目のシート 18 19 //▼転記先ファイル、シートの指定★変更要★ 20 const ToSs = SpreadsheetApp.getActiveSpreadsheet(); 21 const ToSheet = ToSs.getSheetByName('工程①'); 22 23 while (SsFiles.hasNext()) { 24 const file = SsFiles.next(); //順番にファイルを処理 25 const FromSheet = SpreadsheetApp.open(file).getSheets()[0]; 26 27//▼転記元ファイルのシート名の変更 28//シート名はセルS1から取得 29//getRange(行目,列目,行分,列分) 30const Name = FromSheet.getRange(1,19,1,1).getValue(); 31console.log('Name ' + Name); 32FromSheet.setName(Name); 33 34//▼氏名を転記先シートセルE5以降に転記 35const lastCol = ToSheet.getLastColumn(); 36console.log('lastCol '+ lastCol); //D列=4が正解 37 38//5行目データあり最終列に氏名を転記 39ToSheet.getRange(5,lastCol+1,1,1).setValue(Name); 40 41//▼Noを転記先シートセルE4以降に転記 42//Noは転記元ファイルのセルK1から取得 43//getRange(行目,列目,行分,列分) 44const empNo = FromSheet.getRange(1,11,1,1).getValue(); 45console.log('empNo '+ empNo); 46ToSheet.getRange(4,lastCol+1,1,1).setValue(empNo); 47 48//6行目に工程①氏名を転記 49//工程①氏名は転記元ファイルのセルAC3から取得 50const TL = FromSheet.getRange(3,29,1,1).getValue(); 51console.log('工程① '+ 工程①); 52ToSheet.getRange(6,lastCol+1,1,1).setValue(TL); 53 54//▼項目結果の転記 55//項目#1~#25までを二次元配列RateArr0としてまとめて取得 56//取得範囲はセルZ6:Z38 57const RateArr0 = FromSheet.getRange(6,26,36,1).getValues(); 58console.log('RateArr0 ',RateArr0); 59 60//二次元配列RateArr0のデータなし空白行を.filter() .map()で削除し 61//新配列RateArr1を生成 62const RateArr1 = RateArr0.filter(([v]) => v).map(row => row.filter(v => v)); 63console.log('RateArr1 ', RateArr1); 64 65//新配列RateArr1をToSheetセルE7以降に転記 66ToSheet.getRange(7,lastCol+1,27,1).setValues(RateArr1); 67 68//▼総合評価の転記 69//工程①総合評価は転記元ファイルのセルZ3から取得 70const sogoRate = FromSheet.getRange(3,26,1,1).getValue(); 71console.log('sogoRate '+ sogoRate); 72ToSheet.getRange(34,lastCol+1,1,1).setValue(sogoRate); 73 74} 75//▼完了Msgの表示 76SpreadsheetApp.flush(); 77Browser.msgBox("マージシートへの転記が完了しました。",Browser.Buttons.OK); 78} 79 80

試したこと

マイドライブ内でマージファイルや親フォルダ、子フォルダの
格納場所を変えてみてトライしましたが、安定して1→2→3の順で
処理をさせることができません。

補足情報

検索したところ以下質問が類似かと思い、参照しましたが、
自己解決には至りませんでした。
Q220684)

はじめにシートのイメージは下リンク先参照
リンク

次回から自己解決できるようになりたいので、
お忙しいところ申し訳ありませんが、
非エンジニアビギナーでも理解できるレベルでの解説、
アドバイスをお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

順に処理をしたいファイル名がNo111111, No222222, No333333のように名前の前半が数字以外で後半が数字のみになっている場合、フォルダ内の全てのファイルを配
列に取得してしまってから、正規表現で名前の数字部分を取り出して配列をソートしておいて、後は配列の並び順に処理をするという方法でいかがでしょうか。
修正の例は、

javascript

1while (SsFiles.hasNext()) { 2 const file = SsFiles.next(); //順番にファイルを処理

の2行を

javascript

1 const files = []; 2 while (Ssfiles.hasNext()) { 3 files.push(Ssfiles.next()); 4 } 5 files.sort((a, b) => a.getName().replace(/.+?(?=\d)/,'') - b.getName().replace(/.+?(?=\d)/,'')); 6 for (const file of files) {

に書き換えて、その次の行からは、
whileループがforループに変わっただけなので処理はそのままでいいと思います。
処理の順序は、数字の大小なのでNo1111111はNo4よりも後に実行されます。

投稿2023/03/26 08:53

編集2023/03/26 09:23
YellowGreen

総合スコア731

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

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

donguriko

2023/03/27 23:38 編集

YellowGreenさま 回答ありがとうございます。 そして返信が遅くなり申し訳ありません。 ファイル名の連番等の番号を利用して、ソートして、処理順をコントロール すればよいのですね。 知識不足で大変申し訳ありませんが、正規表現の部分と下記の部分がわかりません。 お手数ですが補足説明をいただけないでしょうか? ①正規表現:条件に一致するすべての文字列を表すパターンを作成すること .replace(/.+?(?=\d)/,'') の()の中の記載が正規表現、であっていますか? ②()内の意味は .+?(?=\d を '' (←ブランクのこと??)に置き換えなさい、  ですか? ③.+?(?=\d) の解説が欲しいです。    
YellowGreen

2023/03/28 01:45

1) /と/との間が正規表現です。 2) そうです。str.replace(A, B)がstrに含まれるAをBに置き換えなさい。Aの中が正規表現で、「数字が現れる直前までの1文字以上の文字列」を抽出します。 3) . が改行以外の任意の文字、 + が前の文字の1文字以上の繰り返し、 ?がその前の表現にマッチした中で最小範囲の部分、(?=がそれ以降に続く部分は抽出対象外とする、\dは数字1文字 なので、正規表現としては、任意の改行以外の文字が1文字以上続き、最初に数字が現れる直前までの文字列を抽出するとなります。 No111111などのファイル名という設定だったのでこうしましたが、万が一数字だけのファイル名の場合はこのままだと最初に1文字がマッチして抽出されますので、「123456」は「23456」になります。 そもそも数字だけのファイル名ならreplaceしなくてもいいですね。 以上の説明でわかりにくい部分などありましたら、お聞かせください。
YellowGreen

2023/03/28 01:46

1) /と/との間が正規表現です。 /はそれで囲んだ部分が正規表現だよという意味になります。
YellowGreen

2023/03/28 01:57

?がその前の表現(.+)にマッチした中で最小範囲の部分 ?を付けずに/.+(?=\d)/とすると、通常、.+などの表現は条件にマッチする中で最も広い範囲とマッチするので 「No12345678」の場合「No1234567」とマッチします。 最初に数字が現れる直前ではなく、最後に数字が現れる直前となります。
YellowGreen

2023/03/28 02:00

以下のコードでお試しください。 function regExpTest() { const str1 = '12345678'; console.log(str1.replace(/.+?(?=\d)/, '')); const str2 = 'No12345678'; console.log(str2.replace(/.+?(?=\d)/, '')); const str3 = 'No12345678'; console.log(str3.replace(/.+(?=\d)/, '')); }
donguriko

2023/04/01 03:40

YellowGreenさま コメントへの返信が遅くなり申し訳ありません。 正規表現 「.+?(?=\d)」 についての理解が追い付かず回答いだいた 内容の理解に苦戦しています。。。。 お忙しいところ大変申し訳ありませんが、「さら問い」です。 Q1:「.」 は1文字、「+?」は ()内の部分の1回以上の繰り返し、という    意味であっていますか? また、「.+?」 と 「.+」の違いについては、記載いただいたコードで なんとなくですが、イメージがつかめました。 が、()内の ?=\d 部がよくわかりません。 Q2:大変申し訳ありませんが、?=\dが何を意味しているのか、もう少し   補足説明をいただけないでしょうか?   https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions   上記リンク文書で「\d」は、0~9のアラビア数字を意味していることは分かりました。
YellowGreen

2023/04/01 03:43

そのリンクからアサーションを確認してみてください。
YellowGreen

2023/04/01 03:51

先読みアサーションの説明です。
YellowGreen

2023/04/01 04:01

Q1:「.」 は1文字、「+?」は ()内の部分の1回以上の繰り返し、という    意味であっていますか? 合っていません。+はその前の表現の一回以上の繰り返しなので.にマッチする文字の1回以上の繰り返しです。
donguriko

2023/04/01 04:04

YellowGreenさま コメントありがとうございます。 先読みアサーション なのですね。 自分で使えるように、理解を深めたいと思います。 お忙しい中、回答ありがとうございました。
donguriko

2023/04/01 04:09

12:58のリンクありがとうございます。 こちらの方がとっつきやすいですね。勉強してみます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問