スプレッドシート(以降スプシ)の値をコピーしたいケースは社内でしばしば出てきますが、今回は値のみ別のスプシにコピーするケースの実装方法を紹介します。
今回やりたいこと
以下を満たしたいと思います
- あるスプシにあるシート全体のデータをコピーする
- 値のみコピーする
- コピー元のスプシとコピー先のスプシは別にある
- コピー先スプシは新規作成する
- コピー先スプシはGoogleドライブの任意のフォルダに格納できる
なんでこんな対応したの?
等メディアはコーポレートエンジニアの知見共有が目的なので、一応背景まで解説したいと思います!
興味のある人だけ読んでくださいね。
今回この対応が必要になったのは、外部の企業と数値を共有する必要があったためです。
そのスプシの中には関数等や参照データが入っており、外部の担当者さんはそこにアクセスする権限がなく、かつ社内担当者はその共有したファイルを開く必要性があまりなかったため、社内担当者がデータ参照を許可するためだけに共有スプシを開くという無駄な作業が出てきてしまいかねません。
そうならないためにも、最初から最終的な値のみを直接共有したいスプシに反映させるように対応しました。
対応内容とソースコード
やること
同一スプシの別シートにコピーしたい場合はcopyTo()が使えますが、別のスプレッドシートにコピーする場合はそれができません。
なので、以下の実装が必要になります。
- コピー先となるスプレッドシートを作成(元々あれば取得)
- コピー元のコピーしたいデータの値を取得
- コピー先のシートに値を貼り付け
当然といえば当然なんですが、専用のメソッドは無いようなので致し方ありません。
実際のソースコード
以下がサンプルのコードです。
※サンプル用に別途書いたものなので、Typoとかあったらごめんなさい。
const ANY_FOLDER_ID = "フォルダのID"
function myFunction(){
// (GASとスプシが紐づいている前提で)コピー元のスプレッドシートを取得
const spreadsheet = SpreadSheetApp.getActiveSpreadSheet()
// コピー元となる先頭にあるシートを取得
let sheet = spreadsheet.getSheets()[0]
// シート全体の範囲を取得
let range = sheet.getDataRange()
// コピー元シートの値のみを取得
let data = range.getDisplayValues()
// 新規スプシを作成
// create()は実行アカウントのマイドライブ直下に生成される
let ssNew = SpreadSheetApp.create("New_SpreadSheet")
console.log(ssNew.getUrl())
if(ssNew){
// 先頭のシートにコピー元の値をセットする
ssNew.getSheets()[0].getRange(1, 1, range.getLastRow(), range.getLastColumn()).setValues(data)
// スプシを任意のフォルダに格納する
DriveApp.getFileById(ssNew.getId()).moveTo(DriveApp.getFolderById(ANY_FOLDER_ID))
}
}
なお、フォルダのIDは格納したいGoogleドライブのフォルダを実際に開いて、そのURLの”folders/”のあとに記載される文字の羅列になります。
最後に
SpreadSheetAppとDriveApp、FolderとFileクラスなど、似ているようで違うものが混在しているので、実際に書いててごっちゃになることがありますので、その辺は注意が必要です。
「新しい関数できたよ!」「もっと良い方法あるよ!」というご意見は大変ありがたいので、もしあればぜひコメントください。