Javascript извлекает подмассив из двумерного массива с использованием нотации A1 диапазона электронных таблиц - [Google Apps Script] - PullRequest
1 голос
/ 24 октября 2019

Среди многих лучших сценариев Google Apps Script , что касается повышения производительности скрипта, рекомендуется минимизировать обращения к другим сервисам:

Использование операций JavaScript в вашем скрипте значительнобыстрее, чем звонить в другие службы. Все, что вы можете выполнить в самом скрипте Служб Google, будет намного быстрее, чем совершать звонки, требующие извлечения данных с серверов Google или внешнего сервера, такие как запросы к электронным таблицам, документам, сайтам, переводу, UrlFetch и т. Д. Ваши скрипты будут работать быстрее, если вы сможете найти способы минимизировать вызовы, которые скрипты делают с этими сервисами.

В результате при работе с GAS в электронной таблице обычной практикой является копирование значений излист в целом в 2D-массив, выполните все манипуляции с массивом, затем сбросьте все данные из массива обратно на лист.

После того, как вы скопировали все данные из листа в 2D-массив, обработка столбцов можетбыть сложным, особенно с большими наборами столбцов, поэтому может быть удобно использовать функцию, которая будет извлекать / устанавливать данные из двумерного массива с использованием нотации A1, поскольку это позволяет визуально определить на листе, какой диапазон является правильным, при использованииФункция транскодирования Javascript для соответствующей идентификации столбцов и строк.

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

enter image description here

Например, принимая пользовательскую функцию getRange:

var SS = SpreadsheetApp.openById(myID); // open spreadsheet
var sheet = SS.getSheetByName("Test"); // get sheet
var sheetValues = sheet.getSheetValues(1,1,-1,-1); // copy all values from sheet to 2D array

// samples: how the function could be invoked to extract subarray using A1 notation 
var subArray = getRange(sheetValues, "A2:A"); // returns a "column" from the array begin at row 2
subArray = getRange(sheetValues, "A2"); // returns a "cell" from the array (1,0)
subArray = getRange(sheetValues, "B2:D3"); // returns a 2D subarray

Аналогично this

Редактировать:

Я скопировал следующий код из другого аналогичного поста , и теперь это работает, когда я правильно установил параметры:

var matrix = [
          ["a1", "b1", "c1", "d1"],
          ["a2", "b2", "c2", "d2"],
          ["a3", "b3", "c3", "d3"],
          ["a4", "b4", "c4", "d4"]
        ]
var startRow = 1
var startCol = 0
var endRow = 2
var endCol = 0

var section = matrix.slice(startRow, endRow + 1).map(i => i.slice(startCol, endCol + 1))
console.log(JSON.stringify(section))

Я продолжу исследовать транскодирование A1!

Ответы [ 2 ]

1 голос
/ 24 октября 2019

Я получил его на работу, комбинируя фрагмент из здесь .

Вот окончательный код, он может быть дополнительно оптимизирован (и требует проверки входных данных).

var matrix = [
   ["a1", "b1", "c1", "d1"],
   ["a2", "b2", "c2", "d2"],
   ["a3", "b3", "c3", "d3"],
   ["a4", "b4", "c4", "d4"]
]

console.log("getRange('a2:2') returns:\n" + JSON.stringify(getRange("a2:2")));

function getRange(textRange) {
   var startRow, startCol, endRow, endCol;
   var range = textRange.split(":");
   var ret = cellToRoWCol(range[0]);
   startRow = ret[0]
   startCol = ret[1]
   if (startRow == -1) {
      startRow = 0;
   }
   if (startCol == -1) {
      startCol = 0;
   }

   if (range[1]) {
      ret = cellToRoWCol(range[1]);
      endRow = ret[0]
      endCol = ret[1]
      if (endRow == -1) {
         endRow = matrix.length;
      }
      if (endCol == -1) {
         endCol = matrix.length;
      }
   } else { // only one cell
      endRow = startRow
      endCol = startCol
   }

   return matrix.slice(startRow, endRow + 1).map(function(i) {
      return i.slice(startCol, endCol + 1);
   });
}

function cellToRoWCol(cell) {
   // returns row & col from A1 notation
   var row = cell.replace(/[^0-9]+/g, '');
   var letter = cell.replace(/[^a-zA-Z]+/g, '').toUpperCase();

   var column = 0,
      length = letter.length;
   for (var i = 0; i < length; i++) {
      column += (letter.charCodeAt(i) - 64) * Math.pow(26, length - i - 1);
   }

   row = Number(row) - 1;
   column--;

   return [row, column];
}
0 голосов
/ 24 октября 2019

Насколько я понял из вашего вопроса, простой способ извлечь подмассивы из диапазона:

Пример 1:

var subarray = sheet.getRange('B1:E1').getValues()[0];

Теперь представьте, что у вас есть значения в этой строкеи поскольку это только одна строка, вам на самом деле не нужен этот массив как массив внутри другой, поэтому, поместив [0], вы можете получить подмассив в виде 1D массива .

Для возврата столбца вы можете использовать тот же пример, что и выше, но изменив диапазон для чего-то подобного

Пример 2:

var subarray = sheet.getRange('A2:A5').getValue();

Если вы хотите указать только одну ячейку, вы можете использовать

Пример 3:

var subarray = sheet.getRange('A5').getValue();

Редактировать:

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

function getRangeCol(two_d, colPosition, rowToStart) {
    var col = two_d.map(function(value, index) { 
      if(rowToStart <= index)
      return value[colPosition]; 
    }).filter(function (el) {
      return el != null;
    });
    Logger.log(col);
}

Дайте мне знать, если это поможет вам

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