Создание рабочих ссылок на динамически меняющиеся после фильтра ячейки в гугл таблицах
Создаю гугл таблицу из нескольких листов с инфой про героев и их способности.
Есть два листа: Heroes и Skills. в них есть по табличке с описанием героев и скилов соответственно. У каждого героя есть не более 4 способностей. Я хочу сделать ссылки, переносящие пользователя от таблицы с героями к таблице с описанием скилов. Чтобы не копировать-вставлять название каждого скила и потом ещё к каждому отдельно не добавлять ссылку через контекстное меню, я решил написать функцию с гиперссылкой и вставить её во все ячейки со скилами в таблицу с героями. Вот что вышло (в таблице Skills названия способностей разбиты по четыре строки на каждого героя, а именно: первые четыре строки - скилы для первого героя, следующие четыре - скилы для второго героя, и т.д.):
Вставленные названия в таблице Heroes:
Вот функция, с помощью которой я этого добился:
=ГИПЕРССЫЛКА("#gid=1463005886&range=C" & (СТРОКА()-2)*4 + СТОЛБЕЦ()-8; СМЕЩ(Skills!$C$2; (СТРОКА()-2)*4 + СТОЛБЕЦ()-10; 0))
#gid=1463005886&range=C - это ссылка на столбец C на листе Skills. Можно было это записать просто как #Skills!C, но почему то у меня такая ссылка не работает.
В общем всё вроде бы хорошо, но когда я применяю фильтр к таблице Skills, происходит это:
Ссылки на ячейки остаются теми же, а значения в них уже изменённые фильтром. Я посидел, подумал, изменил функцию и получил такую:
=ГИПЕРССЫЛКА("#gid=1463005886&range=C" & СМЕЩ(Skills!$C$2; ПОИСКПОЗ(1; (Skills!$C$2:$C$100<>"")*(СТРОКА(Skills!$C$2:$C$100)-1)>= (СТРОКА()-2)*4 + СТОЛБЕЦ()-10; 0)-1; 0); СМЕЩ(Skills!$C$2; (СТРОКА()-2)*4 + СТОЛБЕЦ()-10; 0))
С ней все названия отображаются корректно даже после применения фильтра, но появилась другая проблема - гиперссылки перестали работать. То есть нет характерного подчёркивания текста и при наведении на ячейки ничего не появляется.
Конечно можно просто накидать во все ячейки ссылок через контекстное меню и это будет сделать легко и это будет работать исправно, но список состоит из около 100 героев с 4 скилами на каждого, а ссылки, созданные при помощи контекстного меню, при перетягивании на другие ячейки, не заменяются на актуальные для новых ячеек. При этом оба почти рабочих варианта не годятся, потому что и фильтрация в таблице Skills, и рабочие ссылки, хоть убей, нужны.
В общем, пожалуйста, помогите найти решение.
Суть задачи, если сначала и короче:
Есть по одной таблице на двух листах. В первой значения расположены в одном столбце, во второй необходимо сделать гиперссылки и записать значения этого столбца в 4 столбцах слева-направо сверху-вниз, чтобы при применении фильтра в первой таблице, гиперссылки для второй оставались корректными, а именно: 1) кликабельными, 2) не меняли первоначально заданного значения.
Ответы (1 шт):
Один из вариантов решения - на каждую ячейку способностей поставить ссылку на себя. Поскольку таблица навыков уже создана, а встроенного способа сделать это одновременно на все ячейки нет, то нужно воспользоваться либо скриптом, либо добавить колонку с функцией HYPERLINK рядом с именами способностей. При опосредованном обращении к ячейке со ссылкой мы получим и содержимое, и ссылку. Само обращение к этим ячейкам лучше организовать одной формулой (см. ниже).
Вариант 1: добавляем ссылки скриптом
Для этого нам понадобится метод setLinkUrl класса RichTextValueBuilder. На StackOverflow есть примеры, но они не учитывают возможность выбора нескольких непересекающихся областей. Ниже пример кода, где эта особенность учтена:
function linkToOneself() {
var sheet = SpreadsheetApp.getActiveSheet();
const gid = sheet.getSheetId();
sheet.getActiveRangeList().getRanges().forEach(range => {
var rows = range.getNumRows();
var cols = range.getNumColumns();
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
var cell = range.getCell(i + 1, j + 1);
var text = cell.getValue().toString().trim();
if (text) {
var url = `#gid=${gid}&range=${cell.getA1Notation()}`;
cell.setRichTextValue(
SpreadsheetApp
.newRichTextValue()
.setText(text)
.setLinkUrl(url)
.build()
);
}
}
}
});
}
Ключевые моменты:
Sheet.getSheetId()- получить код страницы для построения гиперссылки;Sheet.getActiveRangeList().getRanges()- получить список всех выделенных прямоугольных областей;newRichTextValue().setText(text).setLinkUrl(url)- повесить на текст ссылку.
Вариант 2: создаем ссылки формулой
Схема формулы:
=ARRAYFORMULA(HYPERLINK("#gid=...?range=..." & ROW(...), ...))
─┬─ ─┬─ ─┬─ ─┬─
код страницы ─────────┘ │ │ │
буква столбца со способностями ─┘ │ │
область с названиями способностей ─────────┴─────┘
Например, если способности перечислены в области Skills!С2:С100, то я бы добавил новую колонку D и в ячейку D2 поместил формулу:
=ARRAYFORMULA(HYPERLINK("#gid=1463005886?range=С" & ROW(С2:С100), С2:С100))
При этом на странице Heroes я бы поместил следующую формулу в верхний левый угол области скилов героев:
=WRAPROWS(Skills!D2:D100, 4)
Здесь Skills!D2:D100 - это перечисление скилов в один столбец вместе с гиперссылкой на имя скила, а 4 - это размер области способностей героев.
P.S. Добавлю, что в таких случаях удобно использовать именованные таблицы. Здесь есть сложность с терминологией, поскольку мы называем таблицей все полотно с ячейками, тогда как в английском используется два слова - Spreadsheet и Table (в Excel, кстати, аналогичный объект называется ListObject, т.е. список; пожалуй, мы могли бы использовать это слово). Так вот, работая с именованными таблицами (или списками), вы можете обращаться к ним и к отдельным их полям (т.е. колонкам, столбцам) по имени, тем самым сохраняя возможность изменять размер таблицы, не меняя при этом формулу. Создайте, например, новую таблицу с таким содержимым на первой закладке (вместо нуля в выражении #gid=0?... подставьте свой код страницы, протягивать формулу на всю колонку не надо):
| Skill | Link | Description |
|---|---|---|
| Thunder Bolt | =ARRAYFORMULA(HYPERLINK("#gid=0?range=" & LEFT(ADDRESS(1, COLUMN(SkillTable[Skill]), 4)) & ROW(SkillTable[Skill]), SkillTable[Skill])) | Abra cadabra |
| Devastating Hit | Sim sala bin | |
| Soft Bolt | Hocus pocus | |
| Double Hit | Zim zam zoom | |
| Jiggle Jaggle | Yada yada | |
| Speedy Run | Flip flop |
Выберите этот диапазон и трансформируйте его в таблицу через меню Формат>Преобразовать в таблицу. Переименуйте таблицу, указав имя SkillTable, которое я использовал в формулах (оно может быть любым, по мере набора формул система будет подсказывать вам имена созданных таблиц и их полей):
Теперь мы можем обращаться к тому или иному столбцу как SkillTable[имя_столбца], например создав страницу героев и обратившись к способностям с гиперссылками через формулу WRAPROWS(SkillTable[Link], 2):
| Hero | Skill 1 | Skill 2 |
|---|---|---|
| Ninja | =WRAPROWS(SkillTable[Link], 2) | |
| Dundee | ||
| Ratatouille |
Результат будет выглядеть приблизительно так (содержимое второй таблицы не зависит от фильтрации в первой):




