#google-apps-script
#google-apps-script
Вопрос:
я пытаюсь перенести массив в столбец, зависящий от значения переменной.
По сути, я пытаюсь создать скрипт, который будет переносить лист ввода и, в зависимости от языка, используемого в конкретной строке листа ввода, переносить значения этих строк в другой столбец на выходе.
т.е. в зависимости от значения столбца (C) значения в столбцах A, B переносятся в столбец I, J, K в зависимости от значения столбца C.
Ссылка на Google таблицы: https://docs.google.com/spreadsheets/d/1wuBfK4PKg79vCGGhsBPmHPT7hjfYNdR0srvX9nj0Ajs/edit?usp=sharing
Я уже нашел простой скрипт copyto, который работает, если это один массив с тем же языком, но мне нужно, чтобы он смещался в зависимости от языка.
Любая помощь будет оценена.
пример кода:
//missing the offset
function transpose() {
var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange("A2:C").copyTo(sheet.getRange("F2"),
SpreadsheetApp.CopyPasteType.PASTE_VALUES,true);
}
Комментарии:
1. Ваш скрипт просто копирует диапазон
A2:C4
вF2:H4
. Можете ли вы привести пример того, как на самом деле будет выглядеть результат? Вы раньше использовали Apps Script или JavaScript? Вы знаете, как использовать условные операторы?2. Исправьте, этот скрипт просто переносит A2: C4 — я добавил пример в столбец O электронной таблицы. Я уже работал со сценарием приложений раньше, но я отказываюсь от этого. Я знаю, что это можно сделать с помощью условных операторов, но если ввод увеличивается до 50 языков, это вряд ли масштабируемо — вместо этого я хотел бы, например, сослаться на список языков, который сопоставляется с определенными столбцами, и смещение на основе этой ссылки.
3. Для любого количества языков, которые у вас есть, у вас всегда будет полный набор? Под «набором» я подразумеваю ввод 1, 2 и 3. То есть, если у вас 10 языков, будет ли у вас 2 x ввода 1, 2 x ввода 2, 2 x ввода 3 для каждого языка? Или возможно, что ENG имеет 2 набора входных данных, а X имеет только 1? Или возможно ли, чтобы язык имел только ввод 1, а не ввод 2 и 3? Может быть полезно иметь некоторый контекст относительно того, какую задачу вы пытаетесь выполнить и почему вам это нужно именно в этом конкретном формате. Я думаю, что этот вопрос сложнее, чем кажется, и вам, возможно, придется его немного разбить.
4. Хорошие вопросы: набор всегда будет полным, как в contain input 1,2,3 (без пробелов), но возможно, что язык EN содержит 10 записей, тогда как язык X или Y имеет разное количество записей n. Контекст следующий: у меня есть библиотека, в которой я храню копию, используемую для рекламы, и эту копию необходимо перенести в другой формат ‘feed’, простое использование формулы транспонирования не выполняет эту работу, поскольку она не распознает, на каком языке вводится, я попытался написать arrayformulaс совпадением индекса для смещения вывода, который также не сработал, следовательно-> поиск решения скрипта
Ответ №1:
Попробуйте этот код:
function Sort()
{
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sh = ss.getSheetByName("Blad1")
var input = sh.getRange(1, 1, 4, 4).getValues();
var output = sh.getRange("H1:K1").getValues();
var index = [0]; var nInput = []
for(var j = 1; j < output[0].length; j )
{
for(var i = 1; i < input.length; i )
if(output[0][j] == input[i][3]) index.push(i)
}
for(var i = 0; i < input.length; i ) nInput.push(input[index[i]])
var nData = [];
for(var i = 1; i < nInput.length; i )
{
for(var j = 0; j < nInput[0].length-1; j )
{
if(nData[j] == null) nData[j] = []
nData[j].push(nInput[i][j])
}
}
sh.getRange(2, 9, nData.length, nData[0].length).setValues(nData);
}
Комментарии:
1. Привет, спасибо за код — хотя он правильно транспонируется, аналогично коду в описании, мне не хватает функции поиска для языка (столбца) D -> я пытаюсь сопоставить Col (D) со строкой 1 в столбце I, J, K — и обновлять в зависимости от языкапредоставлено.
Ответ №2:
Попробуйте этот код:
function Sort()
{
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sh = ss.getSheetByName("Blad1")
var input = sh.getRange(1, 1, 7, 4).getValues();
var output = sh.getRange("H1:K1").getValues();
var index = [0]; var nInput = []
for(var j = 1; j < output[0].length; j )
{
nInput[j-1] = []
for(var i = 1; i < input.length; i )
if(output[0][j] == input[i][3])
for(var k = 0; k < input[0].length-1; k ) nInput[j-1].push(input[i][k])
}
var nData = [];
for(var i = 0; i < nInput.length; i )
{
for(var j = 0; j < nInput[0].length; j )
{
if(nData[j] == null) nData[j] = []
if(nInput[i][j]) nData[j].push(nInput[i][j])
else nData[j].push("")
}
}
sh.getRange(2, 9, nData.length, nData[0].length).setValues(nData)
}
Этот код будет работать, только если у вас одинаковое количество входных данных (в данном случае 3) для каждого языка.
Ответ №3:
Предлагаемый сценарий
function createReport() {
// Initilaize Sheets, Ranges, Values
let file = SpreadsheetApp.getActive();
let sheet1 = file.getSheetByName("Blad1");
let range1 = sheet1.getDataRange();
let values1 = range1.getValues();
let sheet2 = file.getSheetByName("Blad2");
let range2 = sheet2.getDataRange();
let values2 = range2.getValues();
// Deal with headers
let langs = values2[0];
values1.shift(); // to remove headers
// Creating array of sub arrays with info to paste into report
// In this format:
// [[Column to paste in, Input 1, Input 2, Input 3]]
let output = [];
values1.forEach((row, i) => {
let outputRow = [];
let whichCol = langs.findIndex((i) => i == row[3]) 1;
outputRow.push(whichCol);
for (let i = 0; i < 3; i ) {
outputRow.push(row[i]);
}
output.push(outputRow);
});
// With output array, pasting into report
output.forEach((entry) => {
let col = entry.shift();
// Find where the next free slot is in column
let occupiedRange = sheet2
.getRange(1, col)
.getDataRegion(SpreadsheetApp.Dimension.ROWS)
let height = occupiedRange.getHeight();
// Transposing array
set = entry.map((val) => [val]);
// Inserting Values to Report
let outRange = sheet2.getRange(height 1, col, 3, 1);
outRange.setValues(set);
});
}
Исходные данные в Blad1
Целевой шаблон и сценарий в действии в Blad2
Объяснение
Вы заметите, что он немного длиннее, чем ваш скрипт! То, что вы пытаетесь сделать, обманчиво сложно, поэтому я не решался ответить полностью, поскольку этот сценарий настолько далек от того, что вы изначально опубликовали, что казалось, что это вопрос «дайте мне код». Хотя вы новичок на сайте, и я уже написал большую часть кода, так какого черта. В будущем, пожалуйста, постарайтесь включить больше информации в свой первоначальный вопрос, свои попытки и исследования. Я постарался сделать его максимально кратким, но может быть определенный синтаксис, с которым вы не сталкивались, например forEach
, и map
.
- Скрипт сначала получает данные,
getValues
которые возвращают 2D-массивы значений. - Я удаляю заголовки исходных данных и использую заголовки целевых данных, чтобы найти индекс столбца, в котором будут находиться исходные данные. Так
ENG
же как и индекс 1,X
индекс 2 и т.д. - Для каждой строки в исходных данных он преобразует ее в промежуточный массив (что необязательно, но я думаю, что это понятнее для понимания каждого шага). Промежуточный массив состоит из подмассивов, представляющих каждый «набор». Каждый вложенный массив имеет этот формат
[Column_Index, Input1, Input2, Input3]
. - После того, как это было построено, каждый из этих подмассивов можно просмотреть, чтобы вставить их в выходной лист, который я назвал «Отчет».
- В рамках этого процесса необходимо получить первую незанятую строку целевого столбца. Итак, если
ENG
уже есть 3 набора, которые были заполнены, скрипт должен знать, где начинается следующий набор. Он делает это, используяgetDataRegion(SpreadsheetApp.Dimension.ROWS)
thengetHeight() 1
, чтобы найти начальную строку для вставляемого набора. - Также в рамках этого заключительного процесса необходимо преобразовать массив из этого формата:
[1,2,3]
Какие приложения скрипт понимает как строку, в столбец, который будет следующим:
[[1],[2],[3]]
что было сделано с.
map
Я рекомендую вам использовать Logger.log
для регистрации группы значений и проверки выходных данных, чтобы вы могли понять сценарий и адаптировать его к вашим потребностям. Я попытался назвать все в «дружественной» манере.
Ссылки
Комментарии:
1. Привет, янседано — сегодня я ознакомлюсь с кодом и процессом, спасибо за подробное объяснение!
2. Перечитывая мой ответ, я только что понял, что не упомянул, что «отчет» находится на отдельном листе
Blad2
, а не на том же листе, что и ваш пример. Поскольку при его использованииgetDataRange
динамически обнаруживаются все данные на листе, он будет работать только в том случае, если у вас есть только исходные данныеBlad1
и только столбцы отчета и метки строк («Ввод 1, ввод 2 и т. Д.»)Blad2
, Хотя, конечно, вы можете адаптироваться, если вам нужно.