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

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

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

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

Q&A

解決済

1回答

1000閲覧

GAS(Google Apps Script)でフォルダコピー(サブフォルダ含む)をしたいです

takayuki2023

総合スコア1

Google Apps Script

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

0グッド

2クリップ

投稿2023/08/18 07:01

実現したいこと

お世話になります。

GASで別共有ドライブ間で指定フォルダのコピーをするスクリプトを作成しようとしています。
ネットの情報やChatGTPのアドバイスを参考に作成を進めてきたのですが、
どうしてもうまくいかない部分があったのでここで質問しようと思います。

前提

下記のようなGASを作成中です。
スプレットシートで指定されたコピー元とコピー先のアイテムID間でサブフォルダも含んだコピー
をします。無料版だと6分、有料版だと30分で処理がタイムアウトしてしまうので、
指定時間でコピー処理を自動終了し、トリガーで再実行された時にコピー処理を再開させるようにしたいです。

スクリプトの説明
1.コピー元のsourceFolderIdとコピー先のtargetFolderIdを指定するとサブフォルダ以下も含めてコピーする。
2.コピー元のsourceFolderIdはActiveSpreadsheetの'フォルダコピー'シートの'B3'セルを読み込んで指定する。
3.コピー先のtargetFolderIdはActiveSpreadsheetの'フォルダコピー'シートの'B6'セルを読み込んで指定する。
4.初回の処理開始日時をActiveSpreadsheetの'フォルダコピー'シートの'E3'セルに設定する。
5.全ての処理が完了したら処理完了日時をActiveSpreadsheetの'フォルダコピー'シートの'E4'セルに設定する。
6.コピー処理中にGASを実行しても処理が実行できないようにLockService.getScriptLock()でロックを掛ける。
7.処理時間が指定時間(デフォルト5分)を経過すると処理を中断してコピーの処理状態をPropertiesService.getScriptProperties().setPropertyで保存してロックを解放して終了する。
8.GASを再実行するとPropertiesService.getScriptProperties().getPropertyで中断していたコピー処理を再開する。
9.実行が初回の場合はコンソールログに"Starting new session."と表示するようにする。
10.実行が2回目以降の場合はコンソールログに"Resuming session."と表示するようにする。

1回目の実行では、無事にコピーがされるのですが、
2回目の実行で処理を再開させた時に

nextFile.makeCopy(nextFile.getName(), currentIteration.targetFolder);

の部分で下記エラーが出てしまいます。

発生している問題・エラーメッセージ

Exception: The parameters (String,(class)) don't match the method signature for DriveApp.File.makeCopy. nextIteration @ コード.gs:180 copyFolderRecursively @ コード.gs:131 executeCopyProcess @ コード.gs:74

該当のソースコード

GAS(Google

1 var LOCK_KEY = "COPY_PROCESS_LOCK"; 2 var MAX_RUNNING_TIME_MS = 5 * 60 * 1000; //処理時間はデフォルト5分 3 var RECURSIVE_ITERATOR_KEY = "RECURSIVE_ITERATOR_KEY"; 4 5function startTrigger() { 6 //この関数を1日一回のクーロンなどで登録しておく 7 8 // ステータスクリア 9 StatusClear(); 10 11 // 開始日時をセルに記録 12 getStartDateTime(); 13 14 // 終了日時のセルをクリアー 15 ENDDateTimeClear(); 16 17 18 // セッション情報を削除して新しいセッションを開始 19 PropertiesService.getScriptProperties().deleteProperty(RECURSIVE_ITERATOR_KEY); 20 21 //バックアップトリガーを設定 22 ScriptApp.newTrigger("executeCopyProcess").timeBased().everyMinutes(5).create(); 23} 24 25function executeCopyProcess() { 26 27 var lock = LockService.getScriptLock(); 28 29 // スプレッドシートの読み込み 30 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 31 // シートの選択 32 const sheet = spreadsheet.getSheetByName('フォルダコピー'); 33 // セルの選択 34 const range1 = sheet.getRange('B3'); 35 // セルの値を取得する 36 const sourceFolderId = range1.getValue(); 37 // セルの選択 38 const range2 = sheet.getRange('B6'); 39 // セルの値を取得する 40 const targetFolderId = range2.getValue(); 41 42 var range3 = sheet.getRange('E6'); 43 // セルの値を取得する 44 var runStatus = range3.getValue(); 45 46 47 try { 48 // Try to acquire the lock and proceed if successful 49 if (lock.tryLock(5000)) { 50 console.info("Lock acquired, starting copy process."); 51 52 copyFolderRecursively(sourceFolderId, targetFolderId, runStatus); 53 } else { 54 console.info("Lock is already taken, skipping this run."); 55 } 56 } finally { 57 58 //ステータスをRunningにセットする 59 StatusRUN(); 60 // Release the lock when done 61 lock.releaseLock(); 62 } 63} 64 65function endTrigger() { 66 //executeCopyProcessトリガーを削除 67 68 var triggers = ScriptApp.getProjectTriggers(); 69 70 for (var i = 0; i < triggers.length; i++) { 71 var trigger = triggers[i]; 72 73 if (trigger.getHandlerFunction() == "executeCopyProcess") { 74 ScriptApp.deleteTrigger(trigger); 75 } 76 } 77} 78 79function copyFolderRecursively(sourceFolderId, targetFolderId,runStatus) { 80 81 var sourceFolder = DriveApp.getFolderById(sourceFolderId); 82 var targetFolder = DriveApp.getFolderById(targetFolderId); 83 84 var startTime = new Date().getTime(); 85 86 var recursiveIterator; 87 88 89// [{folderName: String, fileIteratorContinuationToken: String?, folderIteratorContinuationToken: String}] 90 var recursiveIterator = JSON.parse(PropertiesService.getScriptProperties().getProperty(RECURSIVE_ITERATOR_KEY)); 91 if (recursiveIterator !== null) { 92 // verify that it's actually for the same folder 93 if (sourceFolder.getName() !== recursiveIterator[0].folderName) { 94 console.warn("Looks like this is a new folder. Clearing out the old iterator."); 95 recursiveIterator = null; 96 } else { 97 console.info("Resuming session."); 98 } 99 } 100 101 if (recursiveIterator === null) { 102 console.info("Starting new session."); 103 recursiveIterator = []; 104 recursiveIterator.push(makeIterationFromFolders(sourceFolder, targetFolder)); 105 PropertiesService.getScriptProperties().setProperty(RECURSIVE_ITERATOR_KEY, JSON.stringify(recursiveIterator)); 106 } 107 108 while (recursiveIterator.length > 0) { 109 recursiveIterator = nextIteration(recursiveIterator, startTime); 110 111 var currTime = new Date().getTime(); 112 var elapsedTimeInMS = currTime - startTime; 113 var timeLimitExceeded = elapsedTimeInMS >= MAX_RUNNING_TIME_MS; 114 if (timeLimitExceeded) { 115 PropertiesService.getScriptProperties().setProperty(RECURSIVE_ITERATOR_KEY, JSON.stringify(recursiveIterator)); 116 console.info("Stopping loop after '%d' milliseconds. Please continue running.", elapsedTimeInMS); 117 return; 118 } 119 } 120 121 console.info("Done copying"); 122 getENDDateTime(); 123 StatusClear(); 124 PropertiesService.getScriptProperties().deleteProperty(RECURSIVE_ITERATOR_KEY); 125 126 // executeCopyProcessのトリガーを削除 127 endTrigger(); 128} 129 130function makeIterationFromFolders(sourceFolder, targetFolder) { 131 132// if (!targetFolder) { 133// targetFolder = DriveApp.createFolder("New Target Folder"); // 適切なフォルダ名を設定してください 134// } 135 136 return { 137 folderName: sourceFolder.getName(), 138 targetFolderName: targetFolder.getName(), 139 fileIteratorContinuationToken: sourceFolder.getFiles().getContinuationToken(), 140 folderIteratorContinuationToken: sourceFolder.getFolders().getContinuationToken(), 141 sourceFolder: sourceFolder, 142 targetFolder: targetFolder, 143 144 }; 145} 146 147function nextIteration(recursiveIterator, startTime) { 148 149 var currentIteration = recursiveIterator[recursiveIterator.length -1]; //配列の最後の要素(現在のイテレーション)を取得 150 if (currentIteration.fileIteratorContinuationToken !== null) { 151 var fileIterator = DriveApp.continueFileIterator(currentIteration.fileIteratorContinuationToken); 152 if (fileIterator.hasNext()) { 153 // process the next file 154 var path = recursiveIterator.map(function(iteration) { return iteration.folderName; }).join("/"); 155 var nextFile = fileIterator.next(); 156 processFile(nextFile, path); 157 158 nextFile.makeCopy(nextFile.getName(), currentIteration.targetFolder); 159 160 currentIteration.fileIteratorContinuationToken = fileIterator.getContinuationToken(); 161 recursiveIterator[recursiveIterator.length -1] = currentIteration; 162 return recursiveIterator; 163 } else { 164 // done processing files 165 currentIteration.fileIteratorContinuationToken = null; 166 recursiveIterator[recursiveIterator.length- 1] = currentIteration; 167 return recursiveIterator; 168 } 169 } 170 171 if (currentIteration.folderIteratorContinuationToken !== null) { 172 var folderIterator = DriveApp.continueFolderIterator(currentIteration.folderIteratorContinuationToken); 173 if (folderIterator.hasNext()) { 174 // process the next folder 175 var folder = folderIterator.next(); 176 recursiveIterator[recursiveIterator.length-1].folderIteratorContinuationToken = folderIterator.getContinuationToken(); 177 var newTargetSubfolder = currentIteration.targetFolder.createFolder(folder.getName()); // 新しいサブフォルダを作成 178 recursiveIterator.push(makeIterationFromFolders(folder, newTargetSubfolder)); // ターゲットフォルダを更新した新しいイテレーションを追加 179 180 return recursiveIterator; 181 } else { 182 // done processing subfolders 183 recursiveIterator.pop(); 184 return recursiveIterator; 185 } 186 } 187throw "should never get here"; 188} 189 190 191function processFile(file, path) { 192 console.log(path + "/" + file.getName()); 193} 194 195 196 197function getStartDateTime() { 198//現在時刻を取得 199 var now = new Date(); 200 var year = now.getFullYear(); 201 var month = now.getMonth()+1; 202 var date = now.getDate(); 203 var hour = now.getHours(); 204 var minute = now.getMinutes(); 205 var second = now.getSeconds(); 206 //入力したい文字列に整形する 207 var nowDate = year + "年" + month + "月" + date + "日" + hour + "時" + minute + "分" + second + "秒"; 208// スプレッドシートの読み込み 209 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 210 // シートの選択 211 const sheet = spreadsheet.getSheetByName('フォルダコピー'); 212 //E3セルに時刻を入力 213 sheet.getRange('E3').setValue(nowDate); 214 215} 216 217function getENDDateTime() { 218//現在時刻を取得 219 var nowE = new Date(); 220 var yearE = nowE.getFullYear(); 221 var monthE = nowE.getMonth()+1; 222 var dateE = nowE.getDate(); 223 var hourE = nowE.getHours(); 224 var minuteE = nowE.getMinutes(); 225 var secondE = nowE.getSeconds(); 226 //入力したい文字列に整形する 227 var nowEDate = yearE + "年" + monthE + "月" + dateE + "日" + hourE + "時" + minuteE + "分" + secondE + "秒"; 228 // スプレッドシートの読み込み 229 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 230 // シートの選択 231 const sheet = spreadsheet.getSheetByName('フォルダコピー'); 232 //E4セルに時刻を入力 233 sheet.getRange('E4').setValue(nowEDate); 234} 235 236function ENDDateTimeClear() { 237 // スプレッドシートの読み込み 238 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 239 // シートの選択 240 const sheet = spreadsheet.getSheetByName('フォルダコピー'); 241 //E4セルに時刻を入力 242 sheet.getRange('E4').clearContent(); 243} 244 245function StatusClear() { 246 // スプレッドシートの読み込み 247 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 248 // シートの選択 249 const sheet = spreadsheet.getSheetByName('フォルダコピー'); 250 //E4セルに時刻を入力 251 sheet.getRange('E6').clearContent(); 252} 253 254function StatusRUN() { 255 // スプレッドシートの読み込み 256 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 257 // シートの選択 258 const sheet = spreadsheet.getSheetByName('フォルダコピー'); 259 //E4セルに時刻を入力 260 sheet.getRange('E6').setValue("Running"); 261} 262

試したこと

自分でネットで調べたりChatGPTにアドバイスを貰ったりしながらエラー修正を
繰り返してここまで来ましたが行きづまってしまいました。

補足情報(FW/ツールのバージョンなど)

Google Apps Script

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

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

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

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

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

YellowGreen

2023/08/18 19:54

makeCopyのときのtargetFolderがDriveAppで取得したものを JSON.stringify()して、 JSON.parse()してそのまま使っているように思えますが、 改めてDriveAppで取得せずに使えるのでしょうか。
takayuki2023

2023/08/18 20:42

コメントありがとうございます。 別の方にも同じようなアドバイスを頂いて、targetFolderの箇所に関する部分を修正することで resume後の処理でコピー処理を引き継いで実行できることが確認できました。 今、大量ファイルコピーのテスト中ですのでテストが成功したら 完成版のコードをアップしようと思います。
guest

回答1

0

自己解決

下記のGASで動作確認が取れました。
皆さま、ご協力ありがとうございました。

修正箇所:
1.folderオブジェクトの代わりにidをjson化/parseして、idでfolderオブジェクトを取得するように変更しています。

return { // 中略 targetFolder: targetFolder, }; ↓修正。 return { // 中略 targetFolderId:targetFolder.getId(), }

;

さらに、
currentIteration.targetFolder
の所を全て
DriveApp.getFolderById(currentIteration.targetFolderId)
に修正。

2.lock.releaseLock();の記述位置を変更。
3.処理時間を3分、トリガーを1分毎に設定。

GAS本文はこちらです。

Google

1 var LOCK_KEY = "COPY_PROCESS_LOCK"; 2 var MAX_RUNNING_TIME_MS = 3 * 60 * 1000; //GASの処理時間はデフォルト3分 3 var RECURSIVE_ITERATOR_KEY = "RECURSIVE_ITERATOR_KEY"; 4 5function startTrigger() { 6 //この関数を1日一回のクーロンなどで登録しておく 7 8 // ステータスクリア 9 StatusClear(); 10 11 // 開始日時をセルに記録 12 getStartDateTime(); 13 14 // 終了日時のセルをクリアー 15 ENDDateTimeClear(); 16 17 18 19 // セッション情報を削除して新しいセッションを開始 20 PropertiesService.getScriptProperties().deleteProperty(RECURSIVE_ITERATOR_KEY); 21 22 //バックアップトリガーを設定 23 ScriptApp.newTrigger("executeCopyProcess").timeBased().everyMinutes(1).create(); //トリガーは1分毎に実行 24} 25 26function executeCopyProcess() { 27 28 var lock = LockService.getScriptLock(); 29 30 // スプレッドシートの読み込み 31 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 32 // シートの選択 33 const sheet = spreadsheet.getSheetByName('フォルダコピー'); 34 // セルの選択 35 const range1 = sheet.getRange('B3'); 36 // セルの値を取得する 37 const sourceFolderId = range1.getValue(); 38 // セルの選択 39 const range2 = sheet.getRange('B6'); 40 // セルの値を取得する 41 const targetFolderId = range2.getValue(); 42 43 var range3 = sheet.getRange('E6'); 44 // セルの値を取得する 45 var runStatus = range3.getValue(); 46 47 48 try { 49 // Try to acquire the lock and proceed if successful 50 if (lock.tryLock(5000)) { 51 console.info("Lock acquired, starting copy process."); 52 53 copyFolderRecursively(sourceFolderId, targetFolderId ); 54 // 一応スリープ 55 Utilities.sleep(2000); 56 // Release the lock when done 57 lock.releaseLock(); 58 } else { 59 console.info("Lock is already taken, skipping this run."); 60 } 61 } finally { 62 63 //ステータスをRunningにセットする 64 StatusRUN(); 65 66 } 67} 68 69function endTrigger() { 70 //executeCopyProcessトリガーを削除 71 72 var triggers = ScriptApp.getProjectTriggers(); 73 74 for (var i = 0; i < triggers.length; i++) { 75 var trigger = triggers[i]; 76 77 if (trigger.getHandlerFunction() == "executeCopyProcess") { 78 ScriptApp.deleteTrigger(trigger); 79 } 80 } 81} 82 83function copyFolderRecursively(sourceFolderId, targetFolderId) { 84 85 var sourceFolder = DriveApp.getFolderById(sourceFolderId); 86 var targetFolder = DriveApp.getFolderById(targetFolderId); 87 88 var startTime = new Date().getTime(); 89 90 var recursiveIterator; 91 92 93// [{folderName: String, fileIteratorContinuationToken: String?, folderIteratorContinuationToken: String}] 94 var recursiveIterator = JSON.parse(PropertiesService.getScriptProperties().getProperty(RECURSIVE_ITERATOR_KEY)); 95 if (recursiveIterator !== null) { 96 // verify that it's actually for the same folder 97 if (sourceFolder.getName() !== recursiveIterator[0].folderName) { 98 console.warn("Looks like this is a new folder. Clearing out the old iterator."); 99 recursiveIterator = null; 100 } else { 101 console.info("Resuming session."); 102 } 103 } 104 105 if (recursiveIterator === null) { 106 console.info("Starting new session."); 107 recursiveIterator = []; 108 recursiveIterator.push(makeIterationFromFolders(sourceFolder, targetFolder)); 109 PropertiesService.getScriptProperties().setProperty(RECURSIVE_ITERATOR_KEY, JSON.stringify(recursiveIterator)); 110 } 111 112 while (recursiveIterator.length > 0) { 113 recursiveIterator = nextIteration(recursiveIterator, startTime); 114 115 var currTime = new Date().getTime(); 116 var elapsedTimeInMS = currTime - startTime; 117 var timeLimitExceeded = elapsedTimeInMS >= MAX_RUNNING_TIME_MS; 118 if (timeLimitExceeded) { 119 PropertiesService.getScriptProperties().setProperty(RECURSIVE_ITERATOR_KEY, JSON.stringify(recursiveIterator)); 120 console.info("Stopping loop after '%d' milliseconds. Please continue running.", elapsedTimeInMS); 121 return; 122 } 123 } 124 125 console.info("Done copying"); 126 getENDDateTime(); 127 StatusClear(); 128 PropertiesService.getScriptProperties().deleteProperty(RECURSIVE_ITERATOR_KEY); 129 130 // executeCopyProcessのトリガーを削除 131 endTrigger(); 132} 133 134function makeIterationFromFolders(sourceFolder, targetFolder) { 135 136 return { 137 folderName: sourceFolder.getName(), 138 targetFolderName: targetFolder.getName(), 139 fileIteratorContinuationToken: sourceFolder.getFiles().getContinuationToken(), 140 folderIteratorContinuationToken: sourceFolder.getFolders().getContinuationToken(), 141 sourceFolder: sourceFolder, 142 targetFolderId:targetFolder.getId(), 143 144 }; 145} 146 147function nextIteration(recursiveIterator, startTime) { 148 149 var currentIteration = recursiveIterator[recursiveIterator.length -1]; //配列の最後の要素(現在のイテレーション)を取得 150 if (currentIteration.fileIteratorContinuationToken !== null) { 151 var fileIterator = DriveApp.continueFileIterator(currentIteration.fileIteratorContinuationToken); 152 if (fileIterator.hasNext()) { 153 // process the next file 154 var path = recursiveIterator.map(function(iteration) { return iteration.folderName; }).join("/"); 155 var nextFile = fileIterator.next(); 156 processFile(nextFile, path); 157 158 nextFile.makeCopy(nextFile.getName(), DriveApp.getFolderById(currentIteration.targetFolderId)); 159 160 currentIteration.fileIteratorContinuationToken = fileIterator.getContinuationToken(); 161 recursiveIterator[recursiveIterator.length -1] = currentIteration; 162 return recursiveIterator; 163 } else { 164 // done processing files 165 currentIteration.fileIteratorContinuationToken = null; 166 recursiveIterator[recursiveIterator.length- 1] = currentIteration; 167 return recursiveIterator; 168 } 169 } 170 171 if (currentIteration.folderIteratorContinuationToken !== null) { 172 var folderIterator = DriveApp.continueFolderIterator(currentIteration.folderIteratorContinuationToken); 173 if (folderIterator.hasNext()) { 174 // process the next folder 175 var folder = folderIterator.next(); 176 recursiveIterator[recursiveIterator.length-1].folderIteratorContinuationToken = folderIterator.getContinuationToken(); 177 var newTargetSubfolder = DriveApp.getFolderById(currentIteration.targetFolderId).createFolder(folder.getName()); // 新しいサブフォルダを作成 178 recursiveIterator.push(makeIterationFromFolders(folder, newTargetSubfolder)); // ターゲットフォルダを更新した新しいイテレーションを追加 179 180 return recursiveIterator; 181 } else { 182 // done processing subfolders 183 recursiveIterator.pop(); 184 return recursiveIterator; 185 } 186 } 187throw "should never get here"; 188} 189 190 191function processFile(file, path) { 192 console.log(path + "/" + file.getName()); 193} 194 195 196 197function getStartDateTime() { 198//現在時刻を取得 199 var now = new Date(); 200 var year = now.getFullYear(); 201 var month = now.getMonth()+1; 202 var date = now.getDate(); 203 var hour = now.getHours(); 204 var minute = now.getMinutes(); 205 var second = now.getSeconds(); 206 //入力したい文字列に整形する 207 var nowDate = year + "年" + month + "月" + date + "日" + hour + "時" + minute + "分" + second + "秒"; 208// スプレッドシートの読み込み 209 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 210 // シートの選択 211 const sheet = spreadsheet.getSheetByName('フォルダコピー'); 212 //E3セルに時刻を入力 213 sheet.getRange('E3').setValue(nowDate); 214 215} 216 217function getENDDateTime() { 218//現在時刻を取得 219 var nowE = new Date(); 220 var yearE = nowE.getFullYear(); 221 var monthE = nowE.getMonth()+1; 222 var dateE = nowE.getDate(); 223 var hourE = nowE.getHours(); 224 var minuteE = nowE.getMinutes(); 225 var secondE = nowE.getSeconds(); 226 //入力したい文字列に整形する 227 var nowEDate = yearE + "年" + monthE + "月" + dateE + "日" + hourE + "時" + minuteE + "分" + secondE + "秒"; 228 // スプレッドシートの読み込み 229 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 230 // シートの選択 231 const sheet = spreadsheet.getSheetByName('フォルダコピー'); 232 //E4セルに時刻を入力 233 sheet.getRange('E4').setValue(nowEDate); 234} 235 236function ENDDateTimeClear() { 237 // スプレッドシートの読み込み 238 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 239 // シートの選択 240 const sheet = spreadsheet.getSheetByName('フォルダコピー'); 241 //E4セルに時刻を入力 242 sheet.getRange('E4').clearContent(); 243} 244 245function StatusClear() { 246 // スプレッドシートの読み込み 247 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 248 // シートの選択 249 const sheet = spreadsheet.getSheetByName('フォルダコピー'); 250 //E4セルに時刻を入力 251 sheet.getRange('E6').clearContent(); 252} 253 254function StatusRUN() { 255 // スプレッドシートの読み込み 256 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 257 // シートの選択 258 const sheet = spreadsheet.getSheetByName('フォルダコピー'); 259 //E4セルに時刻を入力 260 sheet.getRange('E6').setValue("Running"); 261}

投稿2023/08/19 01:25

takayuki2023

総合スコア1

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問