Транспонировать и копировать на другой лист с помощью скрипта Apps - PullRequest
0 голосов
/ 10 октября 2018

Мне нужно переместить данные столбца в строки на основе объединенного заголовка с помощью Apps Script.Ниже приведен вид того, что будет моим входом и ожидаемым выходом,

Вход

Выход

Пример листа

То, что я написал до сих пор:

function myFunction() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var range = sheet.getRange("A1:AO1");

  var mergedValues = [];

  //get the header added to the array
  mergedValues.push(sheet.getRange("A2:I2").getValues());
  Logger.log(mergedValues);

  var mergedRanges = range.getMergedRanges();
  for (var i = 0; i < mergedRanges.length; i++) {
    var calcA1Notation = "A"+(i+3) + ":C"+(i+3);
    var monA1Notation = "D"+(i+3) + ":F"+(i+3);

    //Load the Transpose values into the array
    mergedValues.push([[
      sheet.getRange(calcA1Notation).getValues().toString(),
      mergedRanges[i].getDisplayValue(),
      sheet.getRange(monA1Notation).getValues().toString()
    ]]);
  }
  Logger.log(mergedValues[0].length);

  for (var i = 0; i < mergedValues.length; i++){
    //Writes to the lastrow+1 of the sheet
    sheet.getRange(sheet.getLastRow()+1, 1).setValue(mergedValues[i]);
  }
} 

Можете ли вы, ребята, помочь мнев модификации скрипта гугл для генерации ожидаемого результата?

1 Ответ

0 голосов
/ 23 октября 2018

Вопрос включает в себя термин «Транспонирование», но это вводит в заблуждение.
Цель спрашивающего проста;копировать ячейки с одного листа на другой.С одним условием включить заголовок столбца с одного листа в качестве ячейки в целевой диапазон.

Опрашивающий продемонстрировал код, хотя и не объяснил, в какой степени это было целесообразно.Код берет три столбца данных и объединяет значения в одну ячейку.В лучшем случае это можно считать ранним проектом.

Ссылка на исходные данные несложна;получение названия месяца является основным осложнением.Я использовал два цикла для работы со строками на листе «Исходный», потому что предполагаемый результат опроса - сортировка данных по месяцам.

Я мог бы создать подпрограмму для преобразования строкового значения месяца в числовое значение, а затем отсортировать его по этому значению (я, конечно, думал об этом) - но я этого не сделал;)

Названия месяцев указаны в верхнем регистре, в качестве результата опроса используется TitleCase.Опять же, я мог бы создать процедуру для преобразования дела, и я потратил некоторое время на попытки.Но в конце концов я решил, что это не является высоким приоритетом.

function so5273586002() {

    var ss = SpreadsheetApp.getActiveSpreadsheet();

    // Declare the two sheets
    var sourcesheet = ss.getSheetByName("Input");
    var targetsheet = ss.getSheetByName("Output");

    // Get the respective starting row and ending rows.'' the target last row is declared in the loop.  
    var sourcestartrow = 3;
    var targetstartrow = 2;
    var sourcelastrow = sourcesheet.getLastRow();


    // get the the data
    var sourcerange = sourcesheet.getDataRange();
    var sourcevalues = sourcerange.getValues();


    // rubric for copying data.
    // each row of the source must create two rows in the target - one row for each month
    // the first three columns are repeats on both rows
    // each row includes the source data as well as the month name

    // target row #1
    // source columns A, B & C to target A,B,C
    // Month#1; value in D1 Source=> Target Column D (4)
    // source columns DEF to target E F G
    // target row #2
    // source columns A, B & C to target A,B,C
    // Month#2: value in G1 Source=> Target D (4)
    // source fields G, H I  to target E F G

    // the questioner's prefered layout is that all the rows are sorted by month; to achive this, I used two loops
    // the first to do the first month; the second to do the second month
    for (i = sourcestartrow; i < (sourcelastrow + 1); i++) {

        // get the last row for the target 
        var targetlastrow = targetsheet.getLastRow();

        // Columns A, B and C -> Columns A, B and C
        var targetRange = targetsheet.getRange(targetlastrow + 1, 1); //target: column =A, row = lastrow plus one
        var sourcetest = sourcesheet.getRange(i, 1, 1, 3).copyTo(targetRange); // range = active row, column=A, 1 row, 3 columns, copy to SheetTracker
        //Logger.log("source range is "+sourcesheet.getRange(i, 1, 1, 3).getA1Notation()+", target range is "+targetsheet.getRange(targetlastrow + 1, 1).getA1Notation());//DEBUG

        // Month Name from the header
        var targetRange = targetsheet.getRange(targetlastrow + 1, 4); //target: column =D, (month) row = lastrow plus one
        var sourcetest = sourcesheet.getRange(1, 4).copyTo(targetRange, {
            contentsOnly: true
        }); // range = active row, column=A, 1 row, 3 columns, copy to SheetTracker
        // Logger.log("source range is "+sourcesheet.getRange(1, 4).getA1Notation()+", target range is "+targetsheet.getRange(targetlastrow + 1, 4).getA1Notation());//DEBUG

        // Month details
        // Columns D E and F -> Columns E F and G
        var targetRange = targetsheet.getRange(targetlastrow + 1, 5); //target: column =E, row = lastrow plus one
        var sourcetest = sourcesheet.getRange(i, 4, 1, 3).copyTo(targetRange, {
            contentsOnly: true
        }); // range = active row, column=D(4), 1 row, 3 columns, copy to SheetTracker
        // Logger.log("source range is "+sourcesheet.getRange(i, 4, 1, 3).getA1Notation()+", target range is "+targetsheet.getRange(targetlastrow + 1, 5).getA1Notation());//DEBUG

    } // end loop#1


    //Loop#2 to generate rows for the second month
    for (i = sourcestartrow; i < (sourcelastrow + 1); i++) {

        // get the last row for the target 
        var targetlastrow = targetsheet.getLastRow();

        // Columns A, B and C -> Columns A, B and C
        var targetRange = targetsheet.getRange(targetlastrow + 1, 1); //target: column =A, row = lastrow plus one
        var sourcetest = sourcesheet.getRange(i, 1, 1, 3).copyTo(targetRange); // range = active row, column=A, 1 row, 3 columns, copy to SheetTracker
        //Logger.log("source range is "+sourcesheet.getRange(i, 1, 1, 3).getA1Notation()+", target range is "+targetsheet.getRange(targetlastrow + 1, 1).getA1Notation());//DEBUG

        // Month Name from the header
        var targetRange = targetsheet.getRange(targetlastrow + 1, 4); //target: column =D, (month) row = lastrow plus one
        var sourcetest = sourcesheet.getRange(1, 7).copyTo(targetRange, {
            contentsOnly: true
        }); // range = active row, column=G, 1 row, 3 columns, copy to SheetTracker
        //Logger.log("source range is "+sourcesheet.getRange(1, 7).getA1Notation()+", target range is "+targetsheet.getRange(targetlastrow + 1, 4).getA1Notation());//DEBUG

        // Month details
        // Columns G H and I -> Columns E F and G
        var targetRange = targetsheet.getRange(targetlastrow + 1, 5); //target: column =E, row = lastrow plus one
        var sourcetest = sourcesheet.getRange(i, 7, 1, 3).copyTo(targetRange, {
            contentsOnly: true
        }); // range = active row, column=D(4), 1 row, 3 columns, copy to SheetTracker
        // Logger.log("source range is "+sourcesheet.getRange(i, 7, 1, 3).getA1Notation()+", target range is "+targetsheet.getRange(targetlastrow + 1, 5).getA1Notation());//DEBUG
    } // end loop#2

}

На этом снимке экрана показан исходный лист («Исходные данные»).
Source sheet


На этих снимках экрана показана цельлист («Вывод») до и после выполнения кода.
Target sheet - Before

Target sheet - After


ОБНОВЛЕНИЕ

Как отмечалось в моих комментариях, в предыдущем проекте отсутствовали две вещи:
1) он был неэффективным и следовал неэффективным методам, поскольку записывал значение каждого поля по мере его создания.Более подходящий подход состоял бы в том, чтобы записать данные в массив, а затем скопировать массив в целевой диапазон после завершения обработки строка за строкой.
2) код состоял из двух циклов для обслуживания2 месяца в демонстрационных данных.Однако это непрактичный результат, так как, вероятно, в действительности в каждом ряду будет любое количество месяцев данных.Опять же, плохая практика, когда более подходящим подходом было принять любое количество данных за месяц.Более эффективный подход состоял бы в создании массива данных при циклическом просмотре каждой строки.

В этой ревизии устранены оба недостатка.
Кроме того, поскольку названия месяцев не сортируются в какой-либо значимой последовательности, я добавил числовой идентификатор месяца, который можно использовать для фильтрации и сортировки в выходной таблице данных.

function so5273586003() {

    var ss = SpreadsheetApp.getActiveSpreadsheet();

    // Declare the two sheets
    var sourcesheet = ss.getSheetByName("Input");
    var targetsheet = ss.getSheetByName("Output");

    // Get the respective starting row and ending rows.'' the target last row is declared in the loop.  
    var targetstartrow = 2;
    var sourcestartrow = 2;
    var sourcelastrow = sourcesheet.getLastRow();
    var sourcelastcolumn = sourcesheet.getLastColumn();
    //Logger.log("the last row is "+sourcelastow+", and the last column is "+sourcelastcolumn);

    // get the the data
    var sourcerange = sourcesheet.getDataRange();
    var sourcevalues = sourcerange.getValues();
    var sourcelength = sourcevalues.length;

    var i = 0;
    var m = 0;
    var month = 1;
    var dataarray = [];
    var masterarray = [];

    // start loop by row
    for (i = sourcestartrow; i < (sourcelastrow); i++) {


        // start loop by month (within row)
        for (m = 0; m <= (sourcelastcolumn - 6); m = m + 3) {

            dataarray = [];

            // add first three columns
            dataarray.push(sourcevalues[i][0]);
            dataarray.push(sourcevalues[i][1]);
            dataarray.push(sourcevalues[i][2]);

            //add the month name
            dataarray.push(sourcevalues[0][3 + m]);

            //add month data
            dataarray.push(sourcevalues[i][3 + m]);
            dataarray.push(sourcevalues[i][4 + m]);
            dataarray.push(sourcevalues[i][5 + m]);

            //create month id
            switch (sourcevalues[0][3 + m]) {
                case "JULY":
                    month = 1;
                    break;
                case "AUGUST":
                    month = 2;
                    break;
                case "SEPTEMBER":
                    month = 3;
                    break;
                case "OCTOBER":
                    month = 4;
                    break;
                case "NOVEMBER":
                    month = 5;
                    break;
                case "DECEMBER":
                    month = 6;
                    break;
                case "JANUARY":
                    month = 7;
                    break;
                case "FEBRUARY":
                    month = 8;
                    break;
                case "MARCH":
                    month = 9;
                    break;
                case "APRIL":
                    month = 10;
                    break;
                case "MAY":
                    month = 11;
                    break;
                case "JUNE":
                    month = 12;
                    break;
                default:
                    month = 100;
                    break;

            } // end switch

            // add the month id to the array (used for sorting)
            dataarray.push(month);

            // add the data to the master array before zeroing for next month
            masterarray.push(dataarray);

        } // months loop

    } // end row loop

    // get the length of the master array
    var masterlength = masterarray.length;
    // define the target range
    var TargetRange = targetsheet.getRange(targetstartrow, 1, masterlength, 8);
    // set the array values on the Target sheet
    TargetRange.setValues(masterarray);

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...