GSheets JSON 字符串拆分器,带有动态列选择

GSheets JSON String Splitter, with Dynamic Column Selection

我有下面的脚本用来拆分 JSON 字符串。
目前它在 Col A 中有一个唯一的 ID,在 Col B 中有数据。 我希望能够在任何列中包含数据,前提是该列称为 DATA。 我希望脚本查找标题为数据的列,并将其左侧的所有列保留在输出选项卡中。
我尝试了一些方法,但其中 none 有效。
我在这里创建了一个示例工作簿来展示我的目标 Splitter Example
这里的任何帮助都会很棒!

function JSON_SPLITTER() {
  var ss = SpreadsheetApp.getActive();
  var inputsheet = ss.getSheetByName("Input");
  var outputsheet = ss.getSheetByName("Current Output");

  // 0. 
  var response = SpreadsheetApp.getUi().prompt('JSON String Heading', 'Enter Column Heading for the JSON String in Row 1 Exactly as it appears', SpreadsheetApp.getUi().ButtonSet.OK_CANCEL)
    var JSONcolumnname = response.getResponseText()

  // 1. Retrieve values from the input sheet.
  var [head, ...additionalinfo] = inputsheet.getDataRange().getValues();

  // 2. Check "DATA" column.
  var dataIdx = head.indexOf(JSONcolumnname);
  if (dataIdx == -1) throw new Error("No DATA column.");

  // 3. Retrieve all keys from JSON data of the "DATA" column.
  var headers = [... new Set(additionalinfo.flatMap(r => {
    var obj = JSON.parse(r[dataIdx]);
    return obj.hasOwnProperty("additionalInfo") ? Object.keys(obj.additionalInfo) : Object.keys(obj);
  }))];

  // 4. Create values of JSON data.
  var objValues = additionalinfo.map(r => {
    var obj = JSON.parse(r[dataIdx]);
    return obj.hasOwnProperty("additionalInfo") ? headers.map(h => obj.additionalInfo[h] || "") : headers.map(h => obj[h] || "");
  });

  // 5. Create output values.
  additionalinfo.forEach((r, i) => r.splice(dataIdx, 1, ...objValues[i]));
  head.splice(dataIdx, 1, ...headers)
  var res = [head, ...additionalinfo];

  // 6. Put the values to the output sheet.
  outputsheet.getRange(1, 1, res.length, res[0].length).setValues(res);
}

我相信你的目标如下。

  • Currently it has a unique ID in Col A, and the Data in Col B. I want to be able to have the data in any column, provided the column is called DATA. I want the script to look for column titled data and keep all columns left of that in the out put tab.为例,当你的“示例数据1”sheet被使用时,你想实现如下情况

    • 发件人: 这是输入 sheet.

      的 header 行
        Contract Oid,Name,Age,DATA
      
    • To: 这是输出 sheet 的 header 行。在您的情况下,需要为每个输入 sheet.

      搜索 DATA
        Contract Oid,Name,Age,{keys parsed from JSON data of "DATA"}
      

当我看到你的脚本时,似乎没有搜索“DATA”列。如果我的理解是正确的,下面的示例脚本怎么样?

示例脚本:

function JSON_SPLITTER2() {
  var ss = SpreadsheetApp.getActive();
  var inputsheet = ss.getSheetByName("Sample Data 1");
  var outputsheet = ss.getSheetByName("Current Output");

  // 1. Retrieve values from the input sheet.
  var [head, ...additionalinfo] = inputsheet.getDataRange().getValues();

  // 2. Check "DATA" column.
  var dataIdx = head.indexOf("DATA");
  if (dataIdx == -1) throw new Error("No DATA column.");

  // 3. Retrieve all keys from JSON data of the "DATA" column.
  var headers = [... new Set(additionalinfo.flatMap(r => {
    var obj = JSON.parse(r[dataIdx]);
    return obj.hasOwnProperty("additionalInfo") ? Object.keys(obj.additionalInfo) : [];
  }))];

  // 4. Create values of JSON data.
  var objValues = additionalinfo.map(r => {
    var obj = JSON.parse(r[dataIdx]);
    return obj.hasOwnProperty("additionalInfo") ? headers.map(h => obj.additionalInfo[h] || "") : Array(headers.length).fill("");
  });

  // 5. Create output values.
  additionalinfo.forEach((r, i) => r.splice(dataIdx, 1, ...objValues[i]));
  head.splice(dataIdx, 1, ...headers)
  var res = [head, ...additionalinfo];

  // 6. Put the values to the output sheet.
  outputsheet.getRange(1, 1, res.length, res[0].length).setValues(res);
}
  • 在此脚本中,当找不到“DATA”sheet 时,会发生错误。如果你想完成而不是报错,请修改if (dataIdx == -1) throw new Error("No DATA column.");if (dataIdx == -1) return;

参考文献:

已添加:

根据您的回复,下面的示例脚本怎么样?

示例脚本:

function JSON_SPLITTER3() {
  var ss = SpreadsheetApp.getActive();
  var inputsheet = ss.getSheetByName("Sample Data 1");
  var outputsheet = ss.getSheetByName("Current Output");

  // 1. Retrieve values from the input sheet.
  var [head, ...additionalinfo] = inputsheet.getDataRange().getValues();

  // 2. Check "DATA" column.
  var dataIdx = head.indexOf("DATA");
  if (dataIdx == -1) throw new Error("No DATA column.");

  // 3. Retrieve all keys from JSON data of the "DATA" column.
  var headers = [... new Set(additionalinfo.flatMap(r => {
    var obj = JSON.parse(r[dataIdx]);
    return obj.hasOwnProperty("additionalInfo") ? Object.keys(obj.additionalInfo) : Object.keys(obj);
  }))];

  // 4. Create values of JSON data.
  var objValues = additionalinfo.map(r => {
    var obj = JSON.parse(r[dataIdx]);
    return obj.hasOwnProperty("additionalInfo") ? headers.map(h => obj.additionalInfo[h] || "") : headers.map(h => obj[h] || "");
  });

  // 5. Create output values.
  additionalinfo.forEach((r, i) => r.splice(dataIdx, 1, ...objValues[i]));
  head.splice(dataIdx, 1, ...headers)
  var res = [head, ...additionalinfo];

  // 6. Put the values to the output sheet.
  outputsheet.getRange(1, 1, res.length, res[0].length).setValues(res);
}