みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
「初心者でもわかるGoogle Apps Scriptのクラス」ということでシリーズをお送りしております。
前回の記事はこちら。
「var self = this」を使って、関数内でもインスタンスを表すthisを使える方法をお伝えしました。
ナンノコッチャ…という方は、ぜひ記事をご覧いただければと…
さて、GASでスプレッドシートの表のデータを扱うクラスを作って参りましたが、今回がラストです。
インスタンスで色々とデータを操作した後に、スプレッドシートに反映させるメソッドを作っていきますよ。
ということで、Google Apps Scriptでオブジェクトのデータをスプレッドシートに反映させるメソッドの作り方です。
では、行ってみましょう!
前回のおさらい
まず、お題としているスプレッドシートはこちらです。
このスプレッドシートの一行ずつのデータを表すクラスがこちらの、クラスPersonです。
(function(global){ var Person = function(record){ var _id = record[0]; this.name = record[1]; this.gender = record[2]; this.birthday = record[3]; Object.defineProperties(this, { id: { get: function(){ return _id; } } }); }; Person.prototype.greet = function(){ Browser.msgBox(this.name + "です、こんにちは!"); }; Person.prototype.log = function(){ Logger.log('%s|%s|%s|%s|', this.id, this.name, this.gender, this.birthday); }; global.Person = Person; })(this);
このクラスから生成されたインスタンスを集合として取り扱うクラスPersonsがこちらです。
(function(global){ var Persons = function() { var values = SpreadsheetApp.getActiveSheet().getDataRange().getValues(); values.shift(); for(var i = 0; i < values.length; i++){ var p = new Person(values[i]); this[p.id] = p; } }; Persons.prototype.add = function(record){ var p = new Person(record); this[p.id] = p; return this[p.id]; }; Persons.prototype.remove = function(id){ delete this[id]; }; Persons.prototype.log = function() { var self = this; Object.keys(this).forEach( function(id) { self[id].log(); } ); } global.Persons = Persons; })(this);
前回はPersonsクラスのlogメソッドを頑張ってつくりました。
そして、その確認のためのmyFunctionはこんシンプルなものでした。
function myFunction() { var persons = new Persons(); persons.log(); }
今回は、このPersonsクラスのメンバーに追加や変更や削除などをした結果を、再度スプレッドシートに反映するメソッドを作っていきます。
オブジェクトのデータをスプレッドシートに反映するメソッド
早速、スプレッドシートにPersonsオブジェクトのデータを反映するapplyToSheetメソッドを紹介していきましょう。
こちらを、コンストラクタPersonsに追加します。
ちょっと長くて申し訳ないのですが、修正したコンストラクタPersonsを再掲します。
(function(global){ var sheet = SpreadsheetApp.getActiveSheet(); var Persons = function() { var values = sheet.getDataRange().getValues(); values.shift(); for(var i = 0; i < values.length; i++){ var p = new Person(values[i]); this[p.id] = p; } }; Persons.prototype.add = function(record){ var p = new Person(record); this[p.id] = p; return this[p.id]; }; Persons.prototype.remove = function(id){ delete this[id]; }; Persons.prototype.log = function(){ var self = this; Object.keys(this).forEach( function(id) { self[id].log(); } ); }; Persons.prototype.applyToSheet = function(){ sheet.clearContents(); var values = []; values.push(['id', 'name', 'gender', 'birthday']); var self = this; Object.keys(this).forEach( function(id) { values.push([id, self[id].name, self[id].gender, self[id].birthday]); } ); sheet.getRange(1, 1, values.length, values[0].length).setValues(values); }; global.Persons = Persons; })(this);
Personsクラスの変更点
まず、3行目ですがSheetオブジェクトはPersonsインスタンスを生成するときと、applyToSheetメソッドと両方で使うので、外出して変数sheetに入れました。
48~62行目がそのapplyToSheetメソッドです。
- sheetの値を全部クリアする
- sheetに書き込むデータを2次元配列として変数valuesにpush
- valuesをシートに書き込む
実行テスト
では、実行して確認してみましょう。
以下のようなmyFunctionを作成して実行します。
function myFunction() { var persons = new Persons(); persons.add(['a04', 'Jay', 'male', new Date('1995/7/7')]); persons.remove('a01'); persons['a02'].name = 'Tim'; persons.applyToSheet(); }
スプレッドシートは以下のように変更されました。
OKですね。
データを配列に変換して取得するメソッド
一点だけ、PersonsクラスのapplyToSheetメソッドですが、各データを配列にしてpushする57行目がちょっと長いですね。
例えば、Personクラスに以下のように、オブジェクトのデータを配列に変換して返すtoArrayメソッドを追加してみましょう。
Person.prototype.toArray = function(){ return [this.id, this.name, this.gender, this.birthday]; };
スプレッドシートは配列での取り扱いが便利ですから、このメソッドもあちこちで使い所ありそうですね。
すると、PersonsクラスのapplyToSheetメソッドは、このように変更できます。
Persons.prototype.applyToSheet = function(){ sheet.clearContents(); var values = []; values.push(['id', 'name', 'gender', 'birthday']); var self = this; Object.keys(this).forEach( function(id) { values.push(self[id].toArray()); } ); sheet.getRange(1, 1, values.length, values[0].length).setValues(values); };
10行目がちょっぴりエコになりましたね。
先ほどのmyFunctionを実行して、正しくスプレッドシートが反映されることを確認しましょうね。
まとめ
以上、Google Apps Scriptでオブジェクトのデータをスプレッドシートに反映させるメソッドの作り方をお伝えしました。
なんでわざわざクラス作ってやるのか…という感じがするかも知れませんが、全体としては
- スプレッドシートのデータをオブジェクト化する
- オブジェクトに対してあれこれ操作をする
- オブジェクトのデータをスプレッドシートに反映する
とこのような手順をとることになります。
クラスを作るのはそこそこ大変ですが、できちゃえばメインの処理であるmyFunctionはたったの10行程度でした。
つまり、クラスに処理を追いやることで、メインの処理をシンプルに作れるようになるんですね。
例えば、サイドバーやWebページから操作するときなどに、応用できると思いますよ。
また、クラスを使った事例があれば紹介していきたいと思います。
どうぞお楽しみに!