Как использовать метод .map () для размещения значений с одной страницы в другую, используя данные в качестве координат для следующей - PullRequest
2 голосов
/ 12 июля 2019

Я пытаюсь взять диапазон данных значений X и Y и поместить значение третьего столбца в другую электронную таблицу, используя значения X и Y в качестве диапазона ячеек.Как можно использовать метод .map() для использования массива для ряда задач?Является ли моя единственная реальная возможность использовать цикл «for», который может быть очень медленным, чтобы пройти через множество строк данных?

Я попытался и успешно использовал функцию «для цикла», чтобы переходить один за другим через одиннайдите значения в каждом столбце и разместите третий столбец значений на другом листе.Однако, чем больше этот список, тем медленнее процесс

function testMap() {

  //Open Active Spreadsheet App
  var ss = SpreadsheetApp.getActive();

  //Capture sheets by name
  var sheetCoord = ss.getSheetByName('Coordinates');
  var sheetPlots = ss.getSheetByName('Plots');

  //Create last row and column variables
  var lR = sheetCoord.getLastRow();
  var lC = sheetCoord.getLastColumn();
  lR = lR-1;

  //Create array of all data
  var data = sheetCoord.getRange(2, 1, lR, lC).getValues();

  //Create variables for placement into proper sheet
  var x = data.map(function(f){ return f[0] });
  var y = data.map(function(f){ return f[1] });
  var v = data.map(function(f){ return f[2] });

  sheetPlots.getRange(y, x, lR, lC).setValues(v);

}

Я ожидаю, что это отобразит значения в диапазоне, а затем постепенно примет каждое значение каждого диапазона и отобразит значение ячейки "v" в координатах наСюжетный лист.Он просто говорит

"Невозможно преобразовать 6,2,1 в (класс). (Строка 23, файл" Код ")".

Ответы [ 2 ]

3 голосов
/ 12 июля 2019
  • Вы хотите поместить значения в ячейки, используя координаты, полученные из электронной таблицы.
  • Столбцы "A", "B" и "C" листа Coordinates являются столбцамичисло, номер строки и значение, соответственно.

Если мое понимание верно, как насчет этого ответа?

Вопросы:

  • строка: целое число
    • Начальный индекс строки диапазона;индексация строк начинается с 1.
  • столбец: целое число
    • начальный индекс столбца диапазона;индексация столбцов начинается с 1.
  • numRows: Integer
    • Количество возвращаемых строк.
  • numColumns: Integer
    • Количество возвращаемых столбцов.
  • В вашем случае кажется, что значения необходимо поместить в ячейкукаждой координаты.К этому, когда данные большие, стоимость процесса станет высокой.
    • К сожалению, когда используется setValues сервиса электронных таблиц, значения помещаются в непрерывные координаты.Это не может быть использовано для ситуации, когда значения помещаются в дискретные координаты.
    • Например, если ваша цель может использовать ситуацию, когда ячейки перезаписываются значениями, включая пустые значения, setValues() может.

Решение:

Для решения вышеуказанных проблем я хотел бы предложить использовать метод batchUpdate Sheets API.Когда используется Sheets API, значения могут быть помещены в ячейки дискретных координат одним вызовом API.И из моего эксперимента , для задания значений, когда данные большие, API Sheets работает быстрее, чем сервис Spreadsheet.Исходя из этой ситуации, я предложил использовать Sheets API.

Модифицированный скрипт:

Прежде чем использовать этот скрипт, включите Sheets API в Advanced Google Services .

.
function testMap() {
  var ss = SpreadsheetApp.getActive();
  var sheetCoord = ss.getSheetByName('Coordinates');
  var sheetPlots = ss.getSheetByName('Plots');
  var lR = sheetCoord.getLastRow();
  var lC = sheetCoord.getLastColumn();
  lR = lR-1;
  var data = sheetCoord.getRange(2, 1, lR, lC).getValues();

  // I modified below script.
  var sheetId = sheetPlots.getSheetId();
  var requests = data.map(function(e) {
    var obj = {};
    if (typeof e[2] == "string") obj.stringValue = e[2];
    if (typeof e[2] == "number") obj.numberValue = e[2];
    return {updateCells: {
      range: {sheetId: sheetId, startRowIndex: e[1] - 1, endRowIndex: e[1], startColumnIndex: e[0] - 1, endColumnIndex: e[0]},
      rows: [{values: [{userEnteredValue: obj}]}],
      fields: "userEnteredValue"
    }};
  });
  Sheets.Spreadsheets.batchUpdate({requests: requests}, ss.getId());
}

Ссылки:

Если я неправильно понял ваш вопрос, и это был не тот результат, которого вы хотите, прошу прощения.В то время, можете ли вы предоставить образец таблицы?Этим я хотел бы подтвердить вашу ситуацию.

0 голосов
/ 12 июля 2019

Относительно ошибки

y и x являются массивами, но метод getRange, использующий четыре аргумента, требует, чтобы каждый из них был числом, точнее целыми числами. Другими словами, ваш код передает неверный тип данных для первых двух аргументов. https://developers.google.com/apps-script/reference/spreadsheet/sheet#getrangerow-column-numrows-numcolumns

Стоит отметить, что v также является массивом (1D Array), но для setValues требуется 2D Array.

Относительно использования Array.protoype.map

В широком смысле вы используете это правильно. Ссылка https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map, но не для того результата, который вы ожидаете получить.

Есть несколько способов достичь этого результата

  • Используйте "грубую силу", чтобы установить значения ячеек каждой координаты по одному, возможно, с помощью оператора for, Array.prototype.forEach или других подобных методов.
  • Использовать "псевдо-грубую силу", использовать Class RangeList
  • Установите все значения одновременно, создав 2D-массив, и установите все значения одновременно, используя setValues
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...