Google Sheets — Немного про IMPORTRANGE()
Michael SmirnovПравильный канал о Таблицах (Google Sheets): @google_sheets
Чат канала: @google_spreadsheets_chat
Здравствуйте, товарищи!
По случаю радостного повода — гугловцы героически починили IMPORTRANGE()
, пишем небольшую статью по теме этой функции.
Сейчас будем импортировать данные, фильтровать и подписывать, откуда они взялись.
Если кто не знает, IMPORTRANGE()
(документация на функцию) достаёт из других таблиц данные и располагает их там, где прописана формула. Нужно это, например, для того, чтобы собрать однотипные данные с разных таблиц и в одном месте всё проанализировать.
У меня в таблице три листа: import, Финансовый Отдел, Инженерный Отдел. На 2-м и 3-м листах данные, на первый буду импортировать.
В реальной ситуации данные обычно импортируются из разных таблиц, Id'шники в функции импорта разные. Тут искусственный пример, всё происходит в рамках одной таблицы, Id'шники будут везде одинаковые − пусть это никого не смущает.
Данные
Случайным образом нагенерил данных два столбца по 10 строк: даты и суммы.
=ARRAYFORMULA(INT(RANDARRAY(10; 2) * {20\ 1000} + {TODAY()\ 500}))
Импортируем
Пробуем импортировать:
=IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "финансовый отдел!A:B")
Теперь объединим данные от двух импортов:
={ IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Финансовый Отдел!A:B"); IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Инженерный Отдел!A:B") }
Поправим пару мелких неудобств:
- Заголовки повторяются
- Импортировались и пустые строки тоже, данные со второго импорта идут только после них
Заголовки можно было бы оставить в одном из импортов, но мы вынесем в отдельную строку, чтобы импорты были однотипные. Добавим фильтрацию с помощью QUERY()
– в первом столбце должны быть значения (у вас могут быть другие критерии):
=QUERY( { "Дата"\ "Сумма"; IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Финансовый Отдел!A2:B"); IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Инженерный Отдел!A2:B") }; "WHERE Col1 IS NOT NULL"; 1 )
Теперь всё хорошо, можно работать.
Подписываем данные − откуда взялись
Иногда возникает желание в соседнем столбце иметь информацию, откуда конкретная строка взялась. Ниже несколько способов, как это можно реализовать.
Способ 1 − через QUERY
Добавляем заголовок "Источник"
, оборачиваем каждый импорт в QUERY()
, где добавляем столбец с повторяющимся текстом:
=QUERY( { "Дата"\ "Сумма"\ "Источник"; QUERY( IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Финансовый Отдел!A2:B"); "SELECT Col1, Col2, 'Финансовый Отдел' LABEL 'Финансовый Отдел' ''"; ); QUERY( IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Инженерный Отдел!A2:B"); "SELECT Col1, Col2, 'Инженерный Отдел' LABEL 'Инженерный Отдел' ''"; ) }; "WHERE Col1 IS NOT NULL"; 1 )
Плюсы:
- ✅ Относительно компактно
- ✅ Относительно просто для понимания
Минусы:
- ❌ Надо явно перечислять все столбцы в
SELECT
- ❌ Подписи (название источника) в разных местах, хоть и рядом с каждым импортом. Если забыть её поменять при копипасте, всё будет работать, но можно и не понять, почему данные не импортируются (а они импортируются, у них просто подпись одинаковая).
Способ 2 − через схлопывание и 2D виртуальный диапазон
☠ Сразу скажу, способ не очень хороший, так как требует, чтобы в источниках было одинаковое количество строк. Обычно это не так.
Что за схлопывания (TRANSPOSE(QUERY(TRANSPOSE(...)))
), можно изучить здесь. 2D виртуальный диапазон − это столбцы с импортированными данными {...\ ...}
(внимание на \
) и строка с подписями {"Финансовый Отдел"\ "Инженерный Отдел"}
:
=QUERY( { "Дата"\ "Сумма"\ "Источник"; ARRAYFORMULA( SPLIT( FLATTEN(TRANSPOSE( { TRANSPOSE(QUERY(TRANSPOSE( IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Финансовый Отдел!A2:B") & "♥️" );; 10^7))\ TRANSPOSE(QUERY(TRANSPOSE( IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Инженерный Отдел!A2:B") & "♥️" );; 10^7)) } & " " & {"Финансовый Отдел"\ "Инженерный Отдел"} )); "♥️ ";; ) ) }; "WHERE Col1 IS NOT NULL"; 1 )
Результат тот же, картинки не будет.
Плюсы:
- ✅ Более универсальная конструкция. Нет никаких зависимостей от количества столбцов и строк. (На самом деле есть: в заголовках, но это один раз перечислить).
- ✅ Все подписи в одном месте. Если забыть добавить подпись для нового импорта сразу будет ошибка.
Минусы:
- ❌ Источники должны содержать одинаковое количество строк. Эту проблему можно обойти через добавление столбца с источником через
QUERY()
(как в Способе 1), но второй плюс этого способа потеряется. - ❌ Сложная для понимания конструкция
- ❌ Много преобразований строк, что требует ресурсов
Короче, способ не шибко хороший. Для повышения общего уровня культуры. Схлопывания и ARRAYFORMULA()
на 2D диапазонах − крайне полезные вещи, часто пригождаются.
Способ 3 – через дополнительные импорты
Можно добавить столбцы с названием источника через повторение значения с помощью IF(SEQUENCE(); ...)
. Но для этого потребуются дополнительные импорты, с помощью которых мы узнаем количество строк в каждой таблице:
=QUERY( { "Дата"\ "Сумма"\ "Источник"; { { IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Финансовый Отдел!A2:B"); IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Инженерный Отдел!A2:B") }\ ARRAYFORMULA( { IF(SEQUENCE(ROWS(IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Финансовый Отдел!A2:A"))); "Финансовый Отдел"); IF(SEQUENCE(ROWS(IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Инженерный Отдел!A2:A"))); "Инженерный Отдел") } ) } }; "WHERE Col1 IS NOT NULL"; 1 )
Результат тот же.
Плюсы:
- ✅ Можно навставлять ссылок на конкретные строки
- ✅ Не нужно перечислять колонки
Минусы:
- ❌ Импортов в два раза больше (хоть мы и не всё повторно импортируем, а только первую колонку) из-за того, что надо знать количество импортированных строк.
Добавляем ссылки на источник
Способ 3 хорош для добавления ссылок на источник.
У нас есть ссылка на лист (вы её видите в браузере):
https://docs.google.com/spreadsheets/d/{SpreadsheetId}/edit#gid={SheetId}
{SpreadsheetId}
− Id таблицы{SheetId}
− Id листа (да, надо пойти и посмотреть)
Если к ней добавить &range={range}
, где {range}
– это диапазон на листе, получится ссылка на конкретный диапазон (он будет выбран при открытии таблицы):
https://docs.google.com/spreadsheets/d/{SpreadsheetId}/edit#gid={SheetId}&range={range}
Мы для простоты будем добавлять ссылки на колонку A:A
соответствующей строки:
=QUERY( { "Дата"\ "Сумма"\ "Источник"; { { IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Финансовый Отдел!A2:B"); IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Инженерный Отдел!A2:B") }\ ARRAYFORMULA( "https://docs.google.com/spreadsheets/d/18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys/edit#" & { "gid=1424146655&range=A" & SEQUENCE(ROWS(IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Финансовый Отдел!A2:A")); 1; 2); "gid=1978378908&range=A" & SEQUENCE(ROWS(IMPORTRANGE("18bnna1mIbuzZtwOzI4GLoXnlZTjScQ9I4lma-bHX1Ys"; "Инженерный Отдел!A2:A")); 1; 2) } ) } }; "WHERE Col1 IS NOT NULL"; 1 )
С данными что-то не так? Нажимаем на ссылку и смотрим в источнике, может, правим.
Заключение
Выбирайте способ, какой больше нравится. Или придумывайте свои, и делитесь с товарищами в чате, будем рады.
Если готовить ссылки и подписи в источнике, жить будет гораздо проще: достаточно будет импортировать и отфильтровывать пустые (то, что мы в самом начале делали).
И не забывайте, что существует Собиратор (сейчас версия 4.0, а когда будут более новые − ищите их в канале), который быстро всё статично импортирует (IMPORTRANGE()
не сломается и не будет тупить, потому что не будет использоваться) через Sheet API. Там есть и добавление метки.
На этом всё. Спасибо за внимание.
Ссылки
Google Sheets Functions
IMPORTRANGE()
— документация на функциюQUERY()
— документация на функциюTRANSPOSE()
— документация на функциюSEQUENCE()
— документация на функцию
Хитрые техники
- Собиратор 4.0
- Повторяем значения необходимое число раз
- Примеры, объяснения и картинки про горизонтальные и вертикальные схлопывания с помощью
QUERY()
иTRANSPOSE()
.
Правильный канал о Таблицах (Google Sheets): @google_sheets
Чат канала: @google_spreadsheets_chat