【GAS×freeeAPI】オブジェクトからデータを取り出してスプレッドシートに書き出す

こんにちは!ITライターのもり(@moripro3)です!

クラウド会計ソフトfreeeのAPIを使って経理業務を自動化するネタをシリーズでお届けしています。

このシリーズでは、freeeとチャットワークを連携して「当日入金予定の取引一覧を自動でチャットワークに送信するツール」を作成します。

成果物のイメージがこちら!入金予定のある日に、自動でチャットワークに通知が届きます。

freeeシリーズ2成果物イメージ

前回の記事では、freeeAPIのレスポンスをオブジェクトに変換して「必要なデータのみを取り出す方法」を紹介しました。

【GAS×freeeAPI】APIリクエストのレスポンスから必要データのみを取り出す
「当日入金予定の取引一覧を自動でチャットワークに送信する」シリーズの第4回目。APIからのレスポンスをオブジェクトに変換して、配列が入れ子になった複雑な構造のオブジェクトから必要データのみを取得する方法を紹介しています。

今回の記事では、オブジェクトからデータを取り出し、スプレッドシートに書き出す方法を紹介します。このようなイメージです。

freeeapi2-5-1

シリーズを通してfreeeAPIを使いこなし、経理業務の自動化を進めていきましょう!

(この記事はfreee株式会社さまとのコラボ企画です。シリーズを通して、皆さんの働くの価値を上げられるようサポートしていきます!)

スポンサーリンク

(前回のおさらい)オブジェクトからデータを取り出す

前回の記事では、freeeAPIからのレスポンス(JSON形式の文字列)を、GASで扱いやすい「オブジェクト」に変換し、ドット記法でオブジェクトからデータを取り出しました。

freeeapi2-5-2

ドット記法とは、オブジェクトから値を取り出す記述方法です。オブジェクト名に対して、ドット(.)でプロパティ名を指定します。

オブジェクト名.プロパティ名

取引1件目の金額を取り出す方法です。「dealsプロパティ(配列)」→「amountプロパティ」の順にアクセスします。

Logger.log(obj.deals[0].amount); //86400

このドット記法を今回の記事でも使っていきますよ!

スプレッドシートの準備

このツールでは、下記の6項目をスプレッドシートに書き出します。

  • 発生日
  • 支払期日
  • 金額
  • 取引先ID
  • 勘定科目ID
  • 品目ID

シートの1行目にヘッダーの項目名を入力します。ヘッダー入力は最初の1回のみです。スクリプト実行の都度、2行目以降を書き換えていきます。

freeeapi2-5-3

また、この記事では、シート名を「取引」としておきます。

オブジェクトの受け渡しは必要データのみとする

この項では、取引データをスプレッドシートに書き出す関数を作成します。引数として取引データを受け取ります。

  • 関数名:OutputDeals
  • 引数:取引データ(オブジェクト)

OutputDeals関数は、取引データが存在する場合のみmain関数から呼び出されます。

main関数がOutputDeals関数を呼び出すときのポイントは、freeeAPIからのレスポンスを丸ごと渡すのではなく、dealsプロパティのみを渡すことです。

function main() {
  
  //当日入金予定の取引一覧を取得する
  var response = getDeals();
  
  //JSON形式の文字列をオブジェクトに変換する
  var obj = JSON.parse(response);
  
  //取引件数の確認
  var total_count = obj.meta.total_count;
  
  //取引データが存在する場合のみ、後続の処理を行う
  if (total_count > 0) {
    
    OutputDeals(obj.deals); //※dealsプロパティのみを渡す
    
  }
  
}

受け取る側の変数名は、dealsプロパティのみであることがわかるよう objDeals としておきます。

/**
* freeeAPIから取得した取引データをスプレッドシートに書き出す
*
* @param {object} 取引データ
*/

function OutputDeals(objDeals) {

  //スプレッドシートに書き出す処理

}

オブジェクト(変数obj)を丸ごと渡すのではなく、dealsプロパティを指定して渡す理由をお伝えします。

freeeAPIのレスポンスの中身は下記の構造になっていて、取引データはすべてdealsプロパティに格納されています。

  {
    "deals":[
      {
        //取引1件目=要素番号[0]
      },
      {
        //取引2件目=要素番号[1]
      },
      {
        //取引3件目=要素番号[2]
      }
    ],
    "meta":{
      "total_count":3
    }
  }

オブジェクト(変数obj)を丸ごと受け取った場合、取引データはすべてdealsプロパティに入っているにも関わらず、値を取り出すたびに、dealsプロパティを指定しなければなりません。

//取引1件目の6項目を取得する
Logger.log(obj.deals[0].issue_date); //2019-07-01
Logger.log(obj.deals[0].due_date); //2019-08-15
Logger.log(obj.deals[0].amount); //86400
Logger.log(obj.deals[0].partner_id); //18092592
Logger.log(obj.deals[0].details[0].account_item_id); //296536450
Logger.log(obj.deals[0].details[0].item_id); //165676671

あらかじめdealsプロパティのみを受け取っておけば、ドット(.)の連結をひとつ減らすことができます。

//取引1件目の6項目を取得する
Logger.log(objDeals[0].issue_date); //2019-07-01
Logger.log(objDeals[0].due_date); //2019-08-15
Logger.log(objDeals[0].amount); //86400
Logger.log(objDeals[0].partner_id); //18092592
Logger.log(objDeals[0].details[0].account_item_id); //296536450
Logger.log(objDeals[0].details[0].item_id); //165676671

このように、関数を呼び出すときの引数には、オブジェクトを丸ごと渡すのではなく、必要なプロパティのみを指定しましょう。

人間同士で何らかのデータをやりとりする場合も、「とりあえず全部渡すから、必要な部分だけ使ってね」よりも、相手が必要なデータだけに絞って渡してあげるほうが親切ですね。

オブジェクトのデータをスプレッドシートに書き出す

この項ではOutputDeals関数の処理を作成していきます。

支払期日2019-08-15に該当する取引は3件ありました。この3件について、必要な6項目をスプレッドシートに書き出します。

freee支払期日が20190815の取引一覧

実装のポイントは、「どのようにスプレッドシートに書き込むか?」です。

単純に「オブジェクトから値を取り出して、1つずつスプレッドシートに書き込む」と、3件×6項目 = 18 回の書き込み処理が必要です。これでは、取引件数が増えるほど、書き込み回数が増えてしまいます。

当ブログでは、GASの高速化テクニックとして「スプレッドシートへの書き込み回数を減らすこと」を推奨しています。

Google Apps Scriptのスプレッドシート読み書きを格段に高速化をする方法
Google Apps Scriptでスプレッドシートの操作をしていて実行速度が遅い!と感じたことがあると思います。今回はスプレッドシートを操作する場合に処理速度を格段に速くする方法をお伝えします。

そこで、下記の2ステップで処理を作成します。

  • ①オブジェクト(連想配列)から、必要なデータのみを配列に格納する
  • ②配列をスプレッドシートに書き出す

freeeapi2-5-4

こうすることで、取引件数がどんなに多くても、スプレッドシートへの書き込み処理はたったの1回で済むのです!

それではコードを書いていきましょう。

オブジェクト(連想配列)から配列を作成する

まずは①の処理を作成します。「キー」と「値」がペアになったオブジェクト(連想配列)から「値」のみを取り出して配列を作成します。

freeeapi2-5-5

オブジェクト(連想配列)とは、「キー」と「値」がペアになった集合体です。

{キー1 : 値1, キー2 : 値2, キー3 : 値3, ・・・}

オブジェクトから必要な「値」のみを取り出して、配列を作成します。

[値1, 値2, 値3, ・・・]

1件目の取引データから6項目を取得してみます。

取引データのdealsプロパティは配列形式であり、取引件数の分、オブジェクトが並んでいることを前回の記事でお伝えしました。
(配列の要素番号は0から始まるので、1件目の取引データを取得する場合、dealsプロパティに要素番号[0]を指定します)

取引データをすべて取得するためには、要素番号の値を変数にして、取引件数分ループ処理します。

処理の流れは下記の3ステップです。

  1. 空の配列を用意
  2. 取引データの件数分、6項目を取得(value1~value6)
  3. value1~value6を、pushメソッドで配列arrに追加

※勘定科目ID・品目IDについて
detailsプロパティは取引の「明細」です。1件の取引に複数明細が存在する場合、明細の数だけオブジェクトが並びます。ただし、全明細を取得する処理は複雑になってしまうので、このツールでは、details[0]を指定して「最初の1明細」のみを取得することにします。

  var arr = []; //空の配列を用意
  
  for(var i = 0; i < objDeals.length; i++) {
    
    var value1 = objDeals[i].issue_date; //発生日
    var value2 = objDeals[i].due_date; //支払期日
    var value3 = objDeals[i].amount; //金額
    var value4 = objDeals[i].partner_id; //取引先ID
    var value5 = objDeals[i].details[0].account_item_id; //勘定科目ID ※明細行1番目
    var value6 = objDeals[i].details[0].item_id; //品目ID ※明細行1番目
    
    //二次元配列を作成
    arr.push([value1,value2,value3,value4,value5,value6]);
    
    Logger.log(arr);
    
  }

ポイントはArrayオブジェクトのpushメソッドです。

pushメソッドとは、配列の末尾に値を追加するメソッドです。追加する値に[配列]を指定することで、配列の追加も可能です。

Arrayオブジェクト.push([配列])

変数arrのログ出力結果です。

freeeapi2-5-7

合計3回ループして、ループ処理のたびに、末尾に配列が格納されていく様子がわかりますね。

配列をスプレッドシートに書き出す

取引3件×6項目の値を格納した二次元配列arrが完成しました。

[[2019-07-01, 2019-08-15, 86400, 18092592, 296536450, 165676671], [2019-06-15, 2019-08-15, 54000, 18092591, 296536450, 165676702], [2019-06-01, 2019-08-15, 108000, 18092590, 296536450, 165676665]]

この変数arrをスプレッドシートに書き出します。②の処理です。

freeeapi2-5-6

まず、getRangeメソッドで配列を書き込むセル範囲を取得します。

Sheetオブジェクト.getRange(行番号, 列番号, 行数, 列数)

つぎに、セル範囲に対して配列をセットするsetValuesメソッドを使用します。

Rangeオブジェクト.setValues(配列)

A2セルを起点として、3行×6列の配列をセットします。

freeeapi2-5-8

配列arrのタテ・ヨコの長さ(length)を、変数i, j に格納しています。

  var i = arr.length; //タテ(行数)= 3
  var j = arr[0].length; //ヨコ(列数)= 6
  
  //スプレッドシートのA2セルを起点として、配列arrをセットする
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('取引');
  sheet.getRange(2, 1, i, j).setValues(arr);

実行結果です。1回の書き込み処理で、目的のデータをすべて書き出すことができました。

freeeapi2-5-9

前回データをクリアする

さて、無事に取引データを書き出せて一安心ですが、最後にひとつ処理を加えます。

このツールは、トリガーで毎日実行してスプレッドシートの2行目以降を上書きします。 そこで、データを書き出す前に、いったん前回データをクリアする処理が必要ですね。

OutputDeals関数の冒頭部に、値のクリア処理を加えます。

var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('取引');
var lastRow = sheet.getLastRow();
  
sheet.getRange(2, 1, lastRow, 6).clearContent();//A列~F列の2行目以降をクリアする

スクリプトまとめ

ここまでで作成したスクリプトのまとめです。getDeals関数についてはシリーズ第3回目の記事をご覧ください。

function main() {
  
  //当日入金予定の取引一覧を取得する
  var response = getDeals();
  
  //JSON形式の文字列をオブジェクトに変換する
  var obj = JSON.parse(response);
  
  //取引件数の確認
  var total_count = obj.meta.total_count;
  
  //取引データが存在する場合のみ、後続の処理を行う
  if (total_count > 0) {
    
    OutputDeals(obj.deals); //※dealsプロパティのみを渡す
    
  }
  
}

/**
 * freeeAPIから取得したデータをスプレッドシートに書き出す
 *
 * @param {object} 取引データ
 */
function OutputDeals(objDeals) {
  
  //前回データのクリア
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('取引');
  var lastRow = sheet.getLastRow();
  
  sheet.getRange(2, 1, lastRow, 6).clearContent();//A列~F列の2行目以降をクリアする
  
  
  var arr = []; //空の配列を用意
  
  for(var i = 0; i < objDeals.length; i++) {
    
    var value1 = objDeals[i].issue_date; //発生日
    var value2 = objDeals[i].due_date; //支払期日
    var value3 = objDeals[i].amount; //金額
    var value4 = objDeals[i].partner_id; //取引先ID
    var value5 = objDeals[i].details[0].account_item_id; //勘定科目ID ※明細行1番目
    var value6 = objDeals[i].details[0].item_id; //品目ID ※明細行1番目
    
    //二次元配列を作成
    arr.push([value1,value2,value3,value4,value5,value6]);
    
  }
  
  //二次元配列をスプレッドシートに書き出す
  var i = arr.length; //タテ(行数)
  var j = arr[0].length; //ヨコ(列数)
  
  //スプレッドシートのA2セルを起点として、配列arrをセットする
  sheet.getRange(2, 1, i, j).setValues(arr);
  
}

まとめ・次回予告

「当日入金予定の取引一覧を自動でチャットワークに送信する」シリーズの第5回目では、これらを紹介しました。

  • 関数を呼び出すときの「引数」には、オブジェクトのプロパティを指定して必要データのみを渡す方法
  • オブジェクトから値を取り出してスプレッドシートに書き出す方法
    →処理高速化のため、スプレッドシートへの書き込み処理は1回のみとする。値を1つずつ書き込むのではなく、必要な値のみを配列に格納し、配列ごとスプレッドシートに書き込むのがポイント!

次回は、スプレッドシートのデータからチャットワーク通知用の本文を作成します。

【GAS×freeeAPI】スプレッドシートのデータからチャットワーク通知用の本文を作成する
「当日入金予定の取引一覧を自動でチャットワークに送信する」シリーズの第6回目。スプレッドシートの値を取得して文字列結合し、チャットワークに通知する本文を作成します。

連載目次:【GAS×freeeAPI】当日入金予定の取引一覧を自動でチャットワークに送信する

「クラウド会計ソフトfreee」のAPIをGASで操作して経理業務を自動化するシリーズ。「当日入金予定の取引一覧を自動でチャットワークに送信するツール」の作成を目標とします。

  1. ノンプログラミングでOK!「会計freee連携アドオン」でスプレッドシートにデータを取得する
  2. 【GAS×freeeAPI】指定条件の取引一覧を取得する「リクエストURL」の作り方と仕組み
  3. 【GAS×freeeAPI】GETリクエストで当日入金予定の取引一覧を取得する
  4. 【GAS×freeeAPI】APIリクエストのレスポンスから必要データのみを取り出す
  5. 【GAS×freeeAPI】オブジェクトからデータを取り出してスプレッドシートに書き出す
  6. 【GAS×freeeAPI】スプレッドシートのデータからチャットワーク通知用の本文を作成する
  7. 【GAS×freeeAPI】当日入金予定の取引一覧を毎日自動でチャットワークに送信する
タイトルとURLをコピーしました