从'广泛转换数据集'到了' Long'在Google Apps脚本中使用Google表格

时间:2018-04-20 04:09:59

标签: google-apps-script google-sheets

我需要一些帮助来为这个生成谷歌脚本和/或公式..

在下面附带的gsheet中,我有以下原始数据集......

Raw Data

对于第1阶段,我需要转换此广泛的'格式为“长”'格式,为“数据类型”中的每个属性创建新列。和' T1'和' T2'被压缩在他们自己的名为“时间”的专栏中。请看下面...... enter image description here

对于第2阶段,我需要加入每一行的所有信息,但需要按时间分组。请看下面...... enter image description here

最后,对于第3阶段,我需要创建一个额外的步骤,其中每个步骤由Col A分开。请参见下文... enter image description here

我试图通过“QUERY'”和“Transpose”来实现数据的重塑。但似乎无法做到。如果有人有自定义构建功能来解决这个非常常见的任务,我非常感谢你对这个任务的帮助!

数据集低于...... https://docs.google.com/spreadsheets/d/1Ujxki1wmaLmkBgZQHI-OTwSubKdlN5mvLDdGWhCBn3E/edit?usp=sharing

感谢。

1 个答案:

答案 0 :(得分:1)

这个示例脚本怎么样?我对您的问题的情况感兴趣。所以我挑战了这个。这也是我的研究。在我的回答中,我尝试使用GAS解决您的问题。我认为你的情况有几个答案。所以请把它想象成其中之一。

在此示例脚本中,"阶段1和#34;,"阶段2和#34;的值和#34;阶段3和#34;每1个数据循环创建一次。从您的问题和示例电子表格中,我认为数据循环为5.然后,创建的值将导入3张。

示例脚本:

function myFunction() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var rawData = ss.getSheetByName("Raw Data").getDataRange().getValues();
  var header = rawData[0];
  var delimiter = "| "; // Please input delimiter.
  var cycle = 5; // From your question, I thought the cycle of data is 5.

  var phase1 = [];
  var phase2 = [];
  var phase3 = [];
  rawData.shift();
  for (var i = 0; i < rawData.length; i += cycle) {
    var temp1 = [];
    var temp2 = [];
    for (var j = i; j < i + cycle; j++) {
      temp1.push([rawData[j][0], rawData[j][1]]);
      temp2.push([rawData[j][3], rawData[j][4]]);
    }
    var converted = temp2[0].map(function(_, i){return temp2.map(function(f){return f[i]})}) // Transpose
                            .map(function(e, i){return temp1[i].concat(e).concat(header[i + 3])}); // Add T1 and T2

    // Create value for phase1.
    Array.prototype.push.apply(phase1, converted);

    // Create value for phase2.
    phase2.push([converted[0].slice(0, 7).join(delimiter), converted[1].slice(0, 7).join(delimiter)]);

    // Create value for phase3.
    phase3.push([converted[0][0], header[3], header[4]]);
    phase3.push(["", converted[0].slice(1, 7).join(delimiter), converted[1].slice(1, 7).join(delimiter)]);
    phase3.push(["", "", ""]);
  }

  // If you want to change the sheet name, please modify this part.
  var all = [
    [ss.getSheetByName("Phase 1"), phase1],
    [ss.getSheetByName("Phase 2"), phase2],
    [ss.getSheetByName("Phase 3(Desired Final Output)"), phase3]
  ];
  all.forEach(function(e) {
    // Import values to 3 sheets.
    e[0].getRange(e[0].getLastRow() + 1, 1, e[1].length, e[1][0].length).setValues(e[1]);
  });
}

如果我误解了你的问题,我很抱歉。

修改

  1. 运行修改后的脚本时,所有转换后的值都将覆盖3张阶段1,阶段2和阶段3。
  2. Data Melt的名称不能用于功能名称。因此使用了DataMelt
    • 例如,将=DataMelt('Raw Data'!A2:E6)放入单元格,导入第1阶段的转换数据。
    • 在此功能中,可以使用5行为1个循环的数据。
  3. 修改后的脚本

    function myFunction() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var rawData = ss.getSheetByName("Raw Data").getDataRange().getValues();
      var header = rawData[0];
      var delimiter = "| "; // Please input delimiter.
      var cycle = 5; // From your question, I thought the cycle of data is 5.
    
      var phase1 = [];
      var phase2 = [];
      var phase3 = [];
      rawData.shift();
      for (var i = 0; i < rawData.length; i += cycle) {
        var temp1 = [];
        var temp2 = [];
        for (var j = i; j < i + cycle; j++) {
          temp1.push([rawData[j][0], rawData[j][1]]);
          temp2.push([rawData[j][3], rawData[j][4]]);
        }
        var converted = temp2[0].map(function(_, i){return temp2.map(function(f){return f[i]})}) // Transpose
                                .map(function(e, i){return temp1[i].concat(e).concat(header[i + 3])}); // Add T1 and T2
    
        // Create value for phase1.
        Array.prototype.push.apply(phase1, converted);
    
        // Create value for phase2.
        phase2.push([converted[0].slice(0, 7).join(delimiter), converted[1].slice(0, 7).join(delimiter)]);
    
        // Create value for phase3.
        phase3.push([converted[0][0], header[3], header[4]]);
        phase3.push(["", converted[0].slice(1, 7).join(delimiter), converted[1].slice(1, 7).join(delimiter)]);
        phase3.push(["", "", ""]);
      }
      phase1.unshift(["Col A", "Col B", "Catalogue", "Display", "Equivalent Single Price", "In-Store_Shopper", "Mechanic", "Time"]);
      phase2.unshift(["T1", "T2"]);
      var all = [
        [ss.getSheetByName("Phase 1"), phase1],
        [ss.getSheetByName("Phase 2"), phase2],
        [ss.getSheetByName("Phase 3(Desired Final Output)"), phase3]
      ];
      all.forEach(function(e) {
        // Import values to 3 sheets.
        e[0].getRange(1, 1, e[1].length, e[1][0].length).setValues(e[1]);
      });
    }
    
    // Added new function
    function DataMelt(e) {
      var e = [["Chalk","A0C-Len Superior Kids TP 80gm","Catalogue","No","Yes"],["Chalk","A0C-Len Superior Kids TP 80gm","Display","Shelf","GE"],["Chalk","A0C-Len Superior Kids TP 80gm","Equivalent Single Price",2.49,2.49],["Chalk","A0C-Len Superior Kids TP 80gm","In-Store_Shopper","",""],["Chalk","A0C-Len Superior Kids TP 80gm","Mechanic","LDLP","Off"]];
    
      var rawData = e;
      var header = ["Col A", "Col B", "Data Type", "T1", "T2"];
      var cycle = 5; // From your question, I thought the cycle of data is 5.
      var phase1 = [];
      var temp1 = [];
      var temp2 = [];
      for (var j = 0; j < cycle; j++) {
        temp1.push([rawData[j][0], rawData[j][1]]);
        temp2.push([rawData[j][3], rawData[j][4]]);
      }
      var converted = temp2[0].map(function(_, i){return temp2.map(function(f){return f[i]})}) // Transpose
                              .map(function(e, i){return temp1[i].concat(e).concat(header[i + 3])}); // Add T1 and T2
    
      // Create value for phase1.
      Array.prototype.push.apply(phase1, converted);
      return phase1;
    }