2024/6/21追記:このツールで担当科目の課題をダウンロードしてみましたら、どうもファイルが抜けるときがあるようです。ダウンロードしたファイルをみると空だったときにClassroomをみると中身があるという状況です。Wordですが。Flushしなければならないとか書き込みを見かけたことがありますがそのせいなのかはわかっていません。とりあえず何かおかしな提出(Wordはあるのに中身が空とか)があった場合はClassroomを確認することをオススメします。
昨日、以下の記事を書きました。
とりあえずやりたいことはできるのですが効率が悪い。フォルダIDを手動で取ってくるのが面倒ですしファイル抽出がなかなか遅い、のでした。
ということで、GASをスプレッドシートにアタッチしてUIをつけました。

黄色セルにClassroomの科目のフォルダIDをいれまして、get forlder idsボタンを押すと、その科目の課題フォルダのID群がA列に出力されます。そこから重複ファイルを除外する処理をしたい課題を選択(いらないのを削除)し、extract filesボタンを押すと、マイドライブのトップに、それぞれ11課題などの名前がついたフォルダができてその中に重複ファイルを除外したファイル群がコピーされます。
スプレッドシート自体を公開することができないので片手落ちですが、とりあえずこの版のGASを以下にメモしておきます。
function getFolderIds() { let ss = SpreadsheetApp.getActive(); let sheet = ss.getSheetByName("シート1"); let fid = sheet.getRange("C1").getValue(); let files = Drive.Children.list(fid); let list = []; for (const file of files.items) { const f = Drive.Files.get(file.id); if (f.fileExtension == undefined ) { //フォルダーなら(拡張子がないようなのでこれで判断する) list.push([f.title, f.id]); } } let range = sheet.getRange(1, 1, list.length, list[0].length); range.setValues(list); } function main() { let ss = SpreadsheetApp.getActive(); let sheet = ss.getSheetByName("シート1"); let range = sheet.getRange(1, 1, 20, 2); //一度に処理するのは20個まで let ll = range.getValues(); let i = ll.length - 1; while (ll[i--][0] == '') { ll.pop(); } const option = { // "orderBy": "title", "maxResults": 1000, } for (const l of ll) { //ファイル情報を取得する let list = []; const files = Drive.Children.list(l[1], option); for (const file of files.items) { const f = Drive.Files.get(file.id); list.push([f.lastModifyingUserName + "_" + f.originalFilename, Utilities.formatDate(new Date(f.createdDate), "JST", "MM/dd HH:mm:ss"), f.id]); } //重複(ユーザ名とファイル名が同じ)している行を削除(日時の古⇒新に並んでいるので後ろを残す) list = list.sort(); list2 = [] let i = 0, j = 0; while (i < list.length) { j = i; while (j < list.length && list[i][0] == list[j][0]) j++; list2.push(list[j-1]); i = j; } // フォルダとファイルをコピーする const latestFolder = DriveApp.createFolder(l[0]); for (let i = 0; i < list2.length; i++) { const file = DriveApp.getFileById(list2[i][2]); //file id file.makeCopy(list2[i][0], latestFolder); } // ショートカットを作成する(高速だけどファイル名が変えられない) /* let dist = DriveApp.createFolder(l[0]); for (let i = 0; i < list2.length; i++) { dist.createShortcut(list2[i][2]); }*/ } }
ちなみに、処理が遅い問題は、ファイルをコピーするのではなくショートカットを作成するようにすれば早くなるのではないかと思いました。で、ググって調べるといい感じの記事がありました。ありがとうございます。
コメントアウトしていますが、上記のコードの最終処理の部分になります。実行時間を比較したところ、単純ファイルコピーでは10分くらいかかりますが(ファイル数は180くらい)、ショートカットだと3分で処理完了しました。「おーいいじゃん」と思ったんですが、ショートカットでは元のファイル名を書き換えることができないのでダウンロードすると元のファイル名になってしまいす。。。これでは誰のファイルなのかわからなくなります。
// ショートカットを作成する(高速だけどファイル名が変えられない) let dist = DriveApp.createFolder(l[0]); for (let i = 0; i < list2.length; i++) { dist.createShortcut(list2[i][2]); }
ということでした。おしまい。