このサイトのリンクには広告リンクが含まれます。

jsonデータを連想配列にしてスプレッドシートに記入する方法【GAS】

この記事は約7分で読めます。

階層化されたjsonデータをフラットな連想配列に変換してからスプレッドシートに記入する方法をChatGPTさんに教えてもらったのでシェア。

完成したソースコード

function writeJsonToSheet(jsonData, sheetname) {
  // 記入するスプレッドシートを取得
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetname);

  // JSONデータをフラット化する関数
  function flattenJson(data, prefix = '') {
    let flatData = {};
    for (let key in data) {
      if (data.hasOwnProperty(key)) {
        const newKey = prefix ? `${prefix}.${key}` : key; // prefixがあれば階層をつなげる

        // 配列の場合、各要素をフラット化
        if (Array.isArray(data[key])) {
          data[key].forEach((item, index) => {
            Object.assign(flatData, flattenJson(item, `${newKey}[${index}]`));  // インデックスをprefixにして再起呼び出し
          });
        }
        // オブジェクトの場合は再帰的にフラット化
        else if (typeof data[key] === 'object' && data[key] !== null) {
          Object.assign(flatData, flattenJson(data[key], newKey));  // キーをprefixにして再起呼び出し
        }
        // 基本的な値(文字列、数値など)はそのまま格納
        else {
          flatData[newKey] = data[key];
        }
      }
    }
    return flatData;
  }

  // JSONをフラット化
  const flatData = flattenJson(jsonData);
  console.log(flatData);  // コンソールで確認

  // flatDataを2次元配列に変換
  const data = Object.entries(flatData); // [["キー1", "値1"], ["キー2", "値2"], ...]
  // スプレッドシートに書き込む
  sheet.getRange(1, 1, data.length, 2).setValues(data);

  Logger.log("JSONデータをスプレッドシートに書き込みました!");
}

使い方

writeJsonToSheet()にjsonオブジェクトと記入するシート名を渡します。

テキスト形式のjsonデータだとGASでは扱えないので、事前にJSON.parse()でオブジェクトに変換してから渡してください。

doPost()で受け取ったデータをシート1に記入する処理はこんな感じ。

function doPost(e) {
  const jsonData = JSON.parse(e.postData.contents);
  writeJsonToSheet(jsonData, "シート1");
}

解説

コメントを見ると分かると思うのですが、「JSONデータをフラット化する関数」と「連想配列をスプレッドシートに記入する」部分に分かれています。

ChatGPTさんソースを渡して質問すれば詳しく解説してもらえますが、私がprefixについて質問した時の回答を貼っておきます。

prefixは何に使っていますか?

prefix は、再帰的に JSON をフラット化する際に キーの階層構造を保持しつつ、ユニークなキーを作成するため に使用しています。

例えば、元の JSON データでは階層が深くなると、以下のようなネストされた構造になっています:

jsonコードをコピーする{
  "data": {
    "object": {
      "customer_address": {
        "postal_code": "3191234",
        "line1": "どっか",
        "state": "茨城県"
      }
    }
  }
}

このようなデータをフラット化するときに、prefix を使ってキーを結合し、階層を表現した一意のキーを作成します。結果として以下のような形になります:

kotlinコードをコピーするdata.object.customer_address.postal_code : 3191234
data.object.customer_address.line1       : どっか
data.object.customer_address.state       : 茨城県

prefix の動作は以下の通りです:

動作の流れ

  1. 初期状態では prefix は空文字列 '' です。
  2. 再帰呼び出しが行われる際、現在のキーを prefix に追加して渡します。
    • 例えば、datadata.objectdata.object.customer_address のように階層を反映したキーが構築されます。
  3. 配列の場合も同様に、prefix を活用してインデックス番号を含めた一意のキーを作成します。
    • 例: items[0].description, items[1].amount

実際のコードでの例

javascriptコードをコピーするfunction flattenJson(data, prefix = '') {
  let flatData = {};
  for (let key in data) {
    if (data.hasOwnProperty(key)) {
      const newKey = prefix ? `${prefix}.${key}` : key; // prefixがあれば階層をつなげる
      if (Array.isArray(data[key])) {
        data[key].forEach((item, index) => {
          Object.assign(flatData, flattenJson(item, `${newKey}[${index}]`)); // 配列の場合
        });
      } else if (typeof data[key] === 'object' && data[key] !== null) {
        Object.assign(flatData, flattenJson(data[key], newKey)); // オブジェクトの場合
      } else {
        flatData[newKey] = data[key]; // それ以外の値
      }
    }
  }
  return flatData;
}

具体例での挙動

元の JSON:

jsonコードをコピーする{
  "data": {
    "object": {
      "items": [
        { "description": "item1", "amount": 500 },
        { "description": "item2", "amount": 500 }
      ]
    }
  }
}

この JSON をフラット化した結果:

jsonコードをコピーする{
  "data.object.items[0].description": "item1",
  "data.object.items[0].amount": 500,
  "data.object.items[1].description": "item2",
  "data.object.items[1].amount": 500
}

prefix の重要性

  • 階層構造を失わないようにする。
  • キーの重複を防ぐ。
  • スプレッドシートにデータを書き込む際に、どの階層のデータかがわかる。

これにより、階層の深い JSON を整理された形でスプレッドシートに書き込むことが可能になります。

ChatGPTさんありがとう!

最後に

なるべくシンプルになるようにChatGPTさんに訊きながら作ってみました。

連想配列のスプレッドシートへの記入部分も、Object.entries()を使うことでシンプルになったと思います。

良ければ使ってみてください。

では、良いGASライフを~

この記事が参考になったら下の「参考になった」ボタンをお願いします。

コメント

タイトルとURLをコピーしました