見出し画像

GASで複数のシートをコピーして一枚のシートにまとめる

やりたいこと

ひとつのスプレッドシートの中に、複数枚のシートがある。各シートの情報をコピーして、一枚のシートにまとめたい。
各シートのヘッダーはぜんぶ同じ。

イメージ図

画像2

画像1

用意するもの

・コピー元(オリジナル)のスプレッドシート(シート複数枚)
・コピー先のスプレッドシート

これらがある状態で、コピー先のスプレッドシートにコンテナバインドでスクリプトを書きます。

完成形のコード

console.logは確認用に。

function copyToAnotherSheet() {
 //copy to コピー先のスプレッドシート
 const copytoSS = SpreadsheetApp.getActiveSpreadsheet();
 //console.log(copytoSS.getName());
 
 //copy to コピー先のシート
 const copytoSheet = copytoSS.getActiveSheet();
 //console.log(copytoSheet.getName());

 //Original コピー元のスプレッドシート
 const orginalSS = SpreadsheetApp.openById("ここにシートID");
 //console.log(orginalSS.getName());

 //Original コピー元のスプレッドシート
 const originalSheets = orginalSS.getSheets();
 //console.log(originalSheets.length);
 
 //コピー元のシート分、処理を繰り返す
 for (let i = 0; i < originalSheets.length; i = i + 1) {
   
   //シート名の取得
   //console.log(originalSheets[i].getName());
   
   //シートの内容、データを取得
   const data = originalSheets[i].getDataRange().getValues();
   
   //console.log(data);
   //取得したデータの先頭行(ヘッダ)削除
   data.shift();
   //console.log(data);
   
   //取得したデータをコピー先シートの最終行以降に転記。
   const lastlow = copytoSheet.getLastRow();
   
   //getRange(row, column, numRows, numColumns)行、列、行数、列数
   copytoSheet.getRange(lastlow+1, 1, data.length, data[0].length).setValues(data);
 }
}

for of 文でもよかったかもしれない。
データ量が大量だと、このコードがとGAS6分の壁にあたるかもしれない。

今回、シート30枚、各シート100行程度のデータをコピーする分には問題なかった。

getRangeの引数で悩んだが、lastlow+1 という点と、data.length, data[0].length を使う、というのがミソだった。

最初はappendRowで書いていて、データの次元やコピー配置が合わなくて悩んでいた。

別解その1 スプレッド構文

「私だったら見出しを削除した各シートのvaluesをスプレッド構文で結合するかな。[...values1, ...values2, ...values3]を一回だけsetValues()します。」というコメントがあった。

スプレッド構文is何?

データ量が多いときは、1回で済むスプレッド構文を使って処理したほうが良い、ということかなあ。これは今後の課題ということで。

別解その2 クエリ関数

GASではなくて、関数で処理できるらしい。クエリ関数、何者なんだ...!


謝辞

例よって、ノンプロ研のみなさんに助言をいただき、大変感謝申し上げます。

だいたい14時ごろに着想して、
電話やオンラインコール捌きつつコード書いて、
その合間にメール返して、
コードに詰まってノンプロ研slackに書いて、
たまたまタイミングよかったのかコメントいただいて、16時頃動作した!
はええ!
ノンプロ研しゅごい。





いただいたサポートで、書籍代や勉強費用にしたり、美味しいもの食べたりします!