Вопрос включает в себя термин «Транспонирование», но это вводит в заблуждение.
Цель спрашивающего проста;копировать ячейки с одного листа на другой.С одним условием включить заголовок столбца с одного листа в качестве ячейки в целевой диапазон.
Опрашивающий продемонстрировал код, хотя и не объяснил, в какой степени это было целесообразно.Код берет три столбца данных и объединяет значения в одну ячейку.В лучшем случае это можно считать ранним проектом.
Ссылка на исходные данные несложна;получение названия месяца является основным осложнением.Я использовал два цикла для работы со строками на листе «Исходный», потому что предполагаемый результат опроса - сортировка данных по месяцам.
Я мог бы создать подпрограмму для преобразования строкового значения месяца в числовое значение, а затем отсортировать его по этому значению (я, конечно, думал об этом) - но я этого не сделал;)
Названия месяцев указаны в верхнем регистре, в качестве результата опроса используется 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
}
На этом снимке экрана показан исходный лист («Исходные данные»).
На этих снимках экрана показана цельлист («Вывод») до и после выполнения кода.
ОБНОВЛЕНИЕ
Как отмечалось в моих комментариях, в предыдущем проекте отсутствовали две вещи:
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);
}