Работа с диапазонами и массивами в Гугл Таблице
  • Ігор Білецький
  • 22.11.2021
  • Коментарі відсутні

Сегодня мы рассмотрим некоторые моменты при обработке диапазонов с данными. Статья является дополнением к основной статье по гугл скриптам и программным решениям при работе с гугл таблицей.

Соответственно, если вы еще не читали основную статью, самое время это сделать сейчас 🙂

А мы продолжаем. Для дальнейшего рассмотрения предположим, что у нас в переменной sheet лежит ссылка на лист нашей таблицы:

let sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

Возьмем произвольный диапазон на листе

let myRange = sheet.getRange(2,1,10,15);

Не буду углубляться в описание данного метода, т.к. это подробно описано в общей статье по скриптам, сделаю небольшую расшифровку:

let myRange = sheet.getRange(строка, колонка, кол-во строк, кол-во колонок);

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

Чтобы узнать размеры нашего диапазона, нужно воспользоваться методами getNumRows и getNumColumns.

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

//перебор всех ячеек заданного диапазона
for (let i = 1; i <= myRange.getNumRows(); i++) {
    for (let j = 1; j <= myRange.getNumColumns(); j++) {
      let currentCell = myRange.getCell(i, j).getValue();
    }
}

В коде, приведенном выше, используется вложенный цикл. Внутренним циклом перебираем все ячейки для каждой строки, что перебираем внешним циклом. При каждой итерации в переменной currentCell лежит очередное значение ячейки нашего диапазона.

Иногда удобнее сохранить сразу весь диапазон в массив. Чтобы сохранить наш диапазон, используем метод getValues():

let arrRange = myRange.getValues();

В результате получаем массив arrRange, содержащий значения нашего диапазона.

Чтобы теперь перебрать значения массива, можем также воспользоваться вложенным циклом:

for (let i = 0; i < arrRange.length; i++) {
    for (let j = 0; j < arrRange[0].length; j++) {
      Logger.log(arrRange[i][j]);
    }
}

Данным скриптом все значения нашего массива буду выведены в консоль.

❗ Обратите внимание, что в отличие от диапазона в массиве индексация начинается с нуля.

Для определения границ массива мы использовали свойство length (длина). Во внешнем цикле — размер массива — кол-во строк, во внутреннем — размер первой строки — кол-во элементов.

Также можно воспользоваться специальным методом перебора значений массива — forEach:

arrRange.forEach(element => Logger.log(element));

Данная строка также выведет в консоль все элементы нашего массива.

В общем, если подытожить, массивы — мощная штука, которая может облегчить решение той или иной задачи, если с ними разобраться. На просторах интернета можно найти по ним массу информации.

На завершение поделюсь некоторыми наработками касательно диапазонов и массивов.

💻 Чтобы получить выделенный пользователем диапазон, используем метод getSelection():

let myRange = sheet.getSelection().getActiveRange(); //получаем выделенный диапазон

А что, если пользователь выделил несколько диапазонов, например с помощью кнопки Ctrl+правая кнопка мышки? Как нам получить значения из диапазонов, выделенных таким образом?

👇Привожу вариант решения:

let myRange = sheet.getSelection().getActiveRangeList().getRanges();

В результате в переменной myRange будут все выделенные на нашем листе диапазоны.

Чтобы теперь их перебрать, воспользуемся оператором forEach:

let arr1 = new Array();
myRange.forEach(element => arr1.push(element.getValues()));

В начале мы объявляем новый массив и с помощью оператора перебора вносим в него все значения из выделенных пользователем диапазонов.

💻 Еще пример подобного использования, который был у меня в реальной задаче.

Имелся список клиентов. Нужно было реализовать рассылку в телеграм произвольно выделенным клиентам (с помощью мышки и клавиши Ctrl).

Идентификатор телеграм каждого клиента, чтобы отправлять сообщения в телеграм с помощью бота, лежал в строке клиента в одной из колонок.

По сути, мне нужно было узнать номера строк тех клиентов, что выделил пользователь. При этом можно было кликать на любую из ячеек, что относились к данным клиента (ФИО, код и т.п.).

👇 Решение задачи

let myRange = SpreadsheetApp.getActiveSpreadsheet().getSelection().getActiveRangeList().getRanges();
let arr1 = new Array();
myRange.forEach(element => arr1.push(element.getRowIndex())); //получаем номер строки

В результате в массиве arr1 лежат номера всех строк, выделенных пользователем.

Теперь с помощью простого цикла достаточно перебрать все элементы массива и по номеру строки получить соответствующий клиенту идентификатор, чтобы отослать клиенту сообщение.

📌 Еще один из полезных методов.

Иногда после обработки данных мы можем получить массив значений, но как-бы все значения вложенные (типа в свою очередь состоят из массивов). Естественно, обработка таких значений несет определенные проблемы, соответственно, нужно как-то решить проблему.

function testArr() {
//из массива массивов получить одномерный массив (метод map. используем функцию callback)
  let oldArr = [['user1'],['user2'],['user3']]; //моделируем ситуацию
  let newArr = oldArr.map(function(row){return row[0]});

  Logger.log(newArr);
  -------------
  out: [user1,user2,user3] //получаем в результате обработки
}

Думаю, комментарии излишни.

Продолжаем. Иногда необходимо узнать, содержит массив требуемое значение или нет.

Конечно, можно в цикле перебрать все значения массива и проверить, есть ли среди них искомое, однако есть метод, который также можно использовать для подобной задачи.

const inputUser = 'user1';
const users = ['user1', 'user2', 'user3'];

if (users.includes(inputUser)) {
	//наш код
	console.log('доступ разрешен');
}

В примере скрипта метод includes проверяет, входит ли заданный элемент (inputUser) в наш массив (users) или нет.

Иногда нужно из списка значений получить только уникальные. Как один из вариантов решения задачи, можно использовать коллекцию (Set). Сам по себе объект Set предполагает наличие только уникальных значений

function testUnique() {
// получить уникальные значения из массива
  let arr1 = ['Яблоко', 'Груша', 'Яблоко', 'Слива', 'Груша']; //исходные данные
  let uniqueList = new Set(arr1); //создаем коллекцию
  for (let item of uniqueList.values()) {
    Logger.log(item);
  }
  //out: Яблоко, Груша, Слива - результат вывода в консоль
 
}

Будьте внимательны, т.к. коллекция имеет свои методы работы с данными, отличающиеся от методов массива.

На сегодня пока все.

Статья будет обновляться и добавляться новыми материалами, поэтому сохраните ссылку.

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

Кстати, если наш сайт принес вам пользу и вы хотите сказать нам «Спасибо» и поддержать нас 🙏, то это можно сделать ЗДЕСЬ.

 

Рекомендую почитать:

 

Залишити коментар