В нем я хочу чтобы мне согласно листу-справочнику "ОПУ" на других листах при вводе значений из списка выпадали вариации их статусов. Т.е. по сути выпадающий список, зависящий от введенного первоначального значения
для этого я написал вот такой скрипт в Apps Script
Цитата
function dependList() { let ss = SpreadsheetApp.openById('1UDrQpUKfdT9SHsOZTQE-z6kIAtUJ2vkUgi59075UCs4'); let sheet = ss.getSheetByName('111') let opy = ss.getSheetByName('ОПУ');
let ar = sheet.getActiveCell(); let valueToFind = ar.getValue();
let values = opy.getRange(4, 3,opy.getLastRow(), 1).getValues(); console.log(values); let row = values[0].indexOf(valueToFind)+5; console.log(row);
let status = opy.getRange(row, 4,1,5).getValues(); console.log(status);
let validation = SpreadsheetApp.newDataValidation().requireValueInList(status).build();
ar.offset(0,1).setDataValidation(validation);
}
Вопросов несколько
1. Самое главное) Скрипт выдает мне все что нужно через консоль, но почему то не появляется выпадающий список на листе "111"
2. Когда написал let row = values[0].indexOf(valueToFind) и вывел в консоль мне выдало -1 - не могу понять почему так. Пришлось сделать +5
3. Мне нужно чтобы скрипт наботал на листах, начинающихся со слова WBS. и при этом только в определенных столбцах. Не придумал как задать это ограничение
В нем я хочу чтобы мне согласно листу-справочнику "ОПУ" на других листах при вводе значений из списка выпадали вариации их статусов. Т.е. по сути выпадающий список, зависящий от введенного первоначального значения
для этого я написал вот такой скрипт в Apps Script
Цитата
function dependList() { let ss = SpreadsheetApp.openById('1UDrQpUKfdT9SHsOZTQE-z6kIAtUJ2vkUgi59075UCs4'); let sheet = ss.getSheetByName('111') let opy = ss.getSheetByName('ОПУ');
let ar = sheet.getActiveCell(); let valueToFind = ar.getValue();
let values = opy.getRange(4, 3,opy.getLastRow(), 1).getValues(); console.log(values); let row = values[0].indexOf(valueToFind)+5; console.log(row);
let status = opy.getRange(row, 4,1,5).getValues(); console.log(status);
let validation = SpreadsheetApp.newDataValidation().requireValueInList(status).build();
ar.offset(0,1).setDataValidation(validation);
}
Вопросов несколько
1. Самое главное) Скрипт выдает мне все что нужно через консоль, но почему то не появляется выпадающий список на листе "111"
2. Когда написал let row = values[0].indexOf(valueToFind) и вывел в консоль мне выдало -1 - не могу понять почему так. Пришлось сделать +5
3. Мне нужно чтобы скрипт наботал на листах, начинающихся со слова WBS. и при этом только в определенных столбцах. Не придумал как задать это ограничениеyurakhl
Сообщение отредактировал yurakhl - Понедельник, 27.05.2024, 12:57
-1 - это значит "значение не найдено". В скриптах нумерация массивов начинается с 0, т.е. первый элемент имеет индекс 0. Поэтому на значении -1 остановились как на признаке "не найдено". К этому значению не надо ничего добавлять - ни 5, ни 6, иначе получится какая-то ерунда.
.getValues() всегда возвращает двумерный массив, даже если в диапазон входит только одна ячейка (не путать с .getValue() без "s" на конце). Значение этой одной ячейки можно получить как values[0][0]. Т.е. указывать надо всегда два индекса: 1-й - строка, 2-й столбец. [0][0] означает 1-й столбец 1-й строки. Если указан только первый индекс values[0], то это означает целиком первую строку, возможно состоящую из нескольких ячеек.
Выражение values[0].indexOf(valueToFind) ищет в первой СТРОКЕ диапазона. Если нужен поиск по СТОЛБЦУ, то значения этого столбца сначала нужно подготовить в отдельном одномерном массиве, "вынув" их из диапазона. Обычно для таких целей у массивов используется метод map: [vba]
Код
function findInRange1stColumn() { // поиск в первой колонке диапазона var vals = SpreadsheetApp.getActiveRange().getValues(); var colarr = vals.map(v => v[0]); Logger.log(colarr.indexOf('значениеДляПоиска')); }
[/vba]
И в таблицу, наверное, надо общий доступ дать, хотя бы на просмотр. Сейчас доступ закрыт.
-1 - это значит "значение не найдено". В скриптах нумерация массивов начинается с 0, т.е. первый элемент имеет индекс 0. Поэтому на значении -1 остановились как на признаке "не найдено". К этому значению не надо ничего добавлять - ни 5, ни 6, иначе получится какая-то ерунда.
.getValues() всегда возвращает двумерный массив, даже если в диапазон входит только одна ячейка (не путать с .getValue() без "s" на конце). Значение этой одной ячейки можно получить как values[0][0]. Т.е. указывать надо всегда два индекса: 1-й - строка, 2-й столбец. [0][0] означает 1-й столбец 1-й строки. Если указан только первый индекс values[0], то это означает целиком первую строку, возможно состоящую из нескольких ячеек.
Выражение values[0].indexOf(valueToFind) ищет в первой СТРОКЕ диапазона. Если нужен поиск по СТОЛБЦУ, то значения этого столбца сначала нужно подготовить в отдельном одномерном массиве, "вынув" их из диапазона. Обычно для таких целей у массивов используется метод map: [vba]
Код
function findInRange1stColumn() { // поиск в первой колонке диапазона var vals = SpreadsheetApp.getActiveRange().getValues(); var colarr = vals.map(v => v[0]); Logger.log(colarr.indexOf('значениеДляПоиска')); }
[/vba]
И в таблицу, наверное, надо общий доступ дать, хотя бы на просмотр. Сейчас доступ закрыт.Gustav
Вот в таком виде процедура вроде бы отрабатывает как надо (переименовал ее, добавив "2" на конце): [vba]
Код
function dependList2() { let ss = SpreadsheetApp.getActive(); let sheet = ss.getSheetByName('111') let opy = ss.getSheetByName('ОПУ');
let ar = sheet.getActiveCell(); let valueToFind = ar.getValue();
let range = opy.getRange(4, 3, opy.getLastRow(), 1); let values = range.getValues(); // console.log(values);
let colarr = values.map(v => v[0]); let row = colarr.indexOf(valueToFind) + 4; // + 5; // console.log(colarr); // console.log(row);
let status = opy.getRange(row, 4, 1, 5).getValues(); let validation = SpreadsheetApp.newDataValidation().requireValueInList(status[0]).build(); // console.log(status[0]);
ar.offset(0, 1).setDataValidation(validation); }
[/vba] А как Вы ее собираетесь запускать массово? Не для каждой же ячейки вручную? Видимо, нужен цикл по каким-то особым ячейкам на всех листах WBS*. А что в этих ячейках особенного? Что они находятся в определенных столбцах этих листов?
Вот в таком виде процедура вроде бы отрабатывает как надо (переименовал ее, добавив "2" на конце): [vba]
Код
function dependList2() { let ss = SpreadsheetApp.getActive(); let sheet = ss.getSheetByName('111') let opy = ss.getSheetByName('ОПУ');
let ar = sheet.getActiveCell(); let valueToFind = ar.getValue();
let range = opy.getRange(4, 3, opy.getLastRow(), 1); let values = range.getValues(); // console.log(values);
let colarr = values.map(v => v[0]); let row = colarr.indexOf(valueToFind) + 4; // + 5; // console.log(colarr); // console.log(row);
let status = opy.getRange(row, 4, 1, 5).getValues(); let validation = SpreadsheetApp.newDataValidation().requireValueInList(status[0]).build(); // console.log(status[0]);
ar.offset(0, 1).setDataValidation(validation); }
[/vba] А как Вы ее собираетесь запускать массово? Не для каждой же ячейки вручную? Видимо, нужен цикл по каким-то особым ячейкам на всех листах WBS*. А что в этих ячейках особенного? Что они находятся в определенных столбцах этих листов?Gustav
ну я вижу 2 варианта либо 1. взять определенные колонки в каждом листе с 7 строки до "ластроу" пометил в скриншоте либо 2. Взять колонки, где в 4 строке заголовок "Статус" также с 7 строки и до "ластроу"
а вообще по долгу службы достаточно часто нужно делать зависимые списки, поэтому хотелось бы сделать скрипт более-менее универсальным
+ я не знаю технически сам способ как в других таблицах включать тот скрипт который писал для этой ну или макрос
Да это те колонки где заголовок статус
ну я вижу 2 варианта либо 1. взять определенные колонки в каждом листе с 7 строки до "ластроу" пометил в скриншоте либо 2. Взять колонки, где в 4 строке заголовок "Статус" также с 7 строки и до "ластроу"
а вообще по долгу службы достаточно часто нужно делать зависимые списки, поэтому хотелось бы сделать скрипт более-менее универсальным
+ я не знаю технически сам способ как в других таблицах включать тот скрипт который писал для этой ну или макросyurakhl
а есть способ что то вроде "активации" скрипта т.е я 1 раз его запускаю, и потом ВСЕГДА когда я что то ввожу в определенную ячейку (стоблец, массив, лист), он автоматически подставляет мне варианты статусов?
а есть способ что то вроде "активации" скрипта т.е я 1 раз его запускаю, и потом ВСЕГДА когда я что то ввожу в определенную ячейку (стоблец, массив, лист), он автоматически подставляет мне варианты статусов?
а есть способ что то вроде "активации" скрипта т.е я 1 раз его запускаю, и потом ВСЕГДА когда я что то ввожу в определенную ячейку (стоблец, массив, лист), он автоматически подставляет мне варианты статусов?
Eсть предопределенная функция-триггер onEdit. Если она создана в проекте, т.е. в проекте присутствует оформленная функция с таким названием, то она срабатывает, когда пользователь меняет в режиме редактирования (т.е. ручками, не скриптом) содержимое ячейки - любой ячейки на любом листе табличного файла. Т.е. функция срабатывает (запускается), а вот какое конкретное действие (или бездействие) она при этом выполняет - зависит от ее наполнения скриптовым кодом.
Обычно в ее начале проверяется, на каком листе (имя) и для какой ячейки (адрес) сработала функция, и далее выполняются шаги, предусмотренные для этих листа/ячейки. Если для данного сочетания листа/ячейки делать ничего не надо, происходит "незаметный" выход из функции и система переходит в режим ожидания следующего редактирования (этой же или другой ячейки). Обязательное условие срабатывания - разные значения ячейки до и после редактирования.
В вашем случае, как я понимаю, нужно будет проверять имя листа - начинается ли оно с букв "WBS". И если начинается, то далее проверять, попадает ли измененная ячейка в один из "жёлтых" диапазонов на этом листе. И если попадает, то в соседней ячейке справа от редактируемой нужно будет создать/обновить выпадающий список, т.е. фактически вызвать для редактируемой ячейки вышеупомянутую функцию dependList2.
а есть способ что то вроде "активации" скрипта т.е я 1 раз его запускаю, и потом ВСЕГДА когда я что то ввожу в определенную ячейку (стоблец, массив, лист), он автоматически подставляет мне варианты статусов?
Eсть предопределенная функция-триггер onEdit. Если она создана в проекте, т.е. в проекте присутствует оформленная функция с таким названием, то она срабатывает, когда пользователь меняет в режиме редактирования (т.е. ручками, не скриптом) содержимое ячейки - любой ячейки на любом листе табличного файла. Т.е. функция срабатывает (запускается), а вот какое конкретное действие (или бездействие) она при этом выполняет - зависит от ее наполнения скриптовым кодом.
Обычно в ее начале проверяется, на каком листе (имя) и для какой ячейки (адрес) сработала функция, и далее выполняются шаги, предусмотренные для этих листа/ячейки. Если для данного сочетания листа/ячейки делать ничего не надо, происходит "незаметный" выход из функции и система переходит в режим ожидания следующего редактирования (этой же или другой ячейки). Обязательное условие срабатывания - разные значения ячейки до и после редактирования.
В вашем случае, как я понимаю, нужно будет проверять имя листа - начинается ли оно с букв "WBS". И если начинается, то далее проверять, попадает ли измененная ячейка в один из "жёлтых" диапазонов на этом листе. И если попадает, то в соседней ячейке справа от редактируемой нужно будет создать/обновить выпадающий список, т.е. фактически вызвать для редактируемой ячейки вышеупомянутую функцию dependList2.Gustav
В вашем случае, как я понимаю, нужно будет проверять имя листа - начинается ли оно с букв "WBS". И если начинается, то далее проверять, попадает ли измененная ячейка в один из "жёлтых" диапазонов на этом листе. И если попадает, то в соседней ячейке справа от редактируемой нужно будет создать/обновить выпадающий список, т.е. фактически вызвать для редактируемой ячейки вышеупомянутую функцию dependList2.
В вашем случае, как я понимаю, нужно будет проверять имя листа - начинается ли оно с букв "WBS". И если начинается, то далее проверять, попадает ли измененная ячейка в один из "жёлтых" диапазонов на этом листе. И если попадает, то в соседней ячейке справа от редактируемой нужно будет создать/обновить выпадающий список, т.е. фактически вызвать для редактируемой ячейки вышеупомянутую функцию dependList2.
просто сделать условное форматирование? прописать все статусы и им какой то формат присвоить?
Цитата
function onEdit(e) { var range = e.range; var sheet = range.getSheet(); var editedColumn = range.getColumn(); var editedRow = range.getRow(); var colname = sheet.getRange(4,editedColumn,1,1).getValue();
просто сделать условное форматирование? прописать все статусы и им какой то формат присвоить?
Цитата
function onEdit(e) { var range = e.range; var sheet = range.getSheet(); var editedColumn = range.getColumn(); var editedRow = range.getRow(); var colname = sheet.getRange(4,editedColumn,1,1).getValue();
Можете подсказать как мне это скрипт как то сохранить чтобы использовать в будущем
я еще записал простой макрос который просто меняет шрифт и делает поля - он мне нужен буквально в каждом файле, но я не знаю как сделать так чтобы он у меня висел постоянно где то в макросах или отдельным меню
Gustav,
Можете подсказать как мне это скрипт как то сохранить чтобы использовать в будущем
я еще записал простой макрос который просто меняет шрифт и делает поля - он мне нужен буквально в каждом файле, но я не знаю как сделать так чтобы он у меня висел постоянно где то в макросах или отдельным менюyurakhl
Можно создать библиотеку - общий набор всех нужных скриптов. Библиотеку лучше всего создавать в автономном скриптовом файле (как - см. по ссылкам). Далее версию такой библиотеки можно опубликовать ("развернуть") и ссылку на нее подключить в других скриптах (например, в скриптах таблиц).
Т.е. весь код будет редактироваться в одном месте (автономный скриптовый файл), а в нескольких местах (таблицах) использования нужно будет подключить ссылки на это "общее место". Если далее нужно будет внести исправления, то они опять вносятся в этом "общем месте", далее путем развертывания выпускается новая версия библиотеки, после чего нужно пройтись по всем использующим файлам (таблицам) и поменять ссылки с прежней версии на новую.
Можно создать библиотеку - общий набор всех нужных скриптов. Библиотеку лучше всего создавать в автономном скриптовом файле (как - см. по ссылкам). Далее версию такой библиотеки можно опубликовать ("развернуть") и ссылку на нее подключить в других скриптах (например, в скриптах таблиц).
Т.е. весь код будет редактироваться в одном месте (автономный скриптовый файл), а в нескольких местах (таблицах) использования нужно будет подключить ссылки на это "общее место". Если далее нужно будет внести исправления, то они опять вносятся в этом "общем месте", далее путем развертывания выпускается новая версия библиотеки, после чего нужно пройтись по всем использующим файлам (таблицам) и поменять ссылки с прежней версии на новую.Gustav
Можно создать библиотеку - общий набор всех нужных скриптов. Библиотеку лучше всего создавать в автономном скриптовом файле (как - см. по ссылкам). Далее версию такой библиотеки можно опубликовать ("развернуть") и ссылку на нее подключить в других скриптах (например, в скриптах таблиц).
Обращение к библиотеке не очень удобно, т..у надо все равно делать новый скрипт и как то его вставлять
Можно ли сделать кнопку, макрос или что то чтобы он в панели висел всегда т.е. я созданию новый документ в шитс, а сверху кнопка "МОЙЧУДОСКРИПТ" или во вкладке макросы - и там 2-3 готовых универсальных скрипта.
Можно создать библиотеку - общий набор всех нужных скриптов. Библиотеку лучше всего создавать в автономном скриптовом файле (как - см. по ссылкам). Далее версию такой библиотеки можно опубликовать ("развернуть") и ссылку на нее подключить в других скриптах (например, в скриптах таблиц).
Обращение к библиотеке не очень удобно, т..у надо все равно делать новый скрипт и как то его вставлять
Можно ли сделать кнопку, макрос или что то чтобы он в панели висел всегда т.е. я созданию новый документ в шитс, а сверху кнопка "МОЙЧУДОСКРИПТ" или во вкладке макросы - и там 2-3 готовых универсальных скрипта.
Можно ли сделать кнопку, макрос или что то чтобы он в панели висел всегда
Полагаю, Вам надо обратить свой взор в сторону разработки дополнений (add-on). Это самостоятельные проекты, которые пишут разработчики и выкладывают их на специальный "маркет", где их могут "купить" все желающие. Наверное, можно как-то ограничить доступ и сделать дополнение только для себя, но в любом случае нужно будет соблюсти ряд правил, предъявляемых к разработкам такого рода. Я сам пока никогда свои дополнения не делал, но скачивал с маркета чужие (например, игру "Судоку"). Обычно после скачивания в меню таблиц автоматически появляется соответствующий пункт (как подпункт раздела "Расширения"), при помощи которого можно запустить функционал дополнения.
Можно ли сделать кнопку, макрос или что то чтобы он в панели висел всегда
Полагаю, Вам надо обратить свой взор в сторону разработки дополнений (add-on). Это самостоятельные проекты, которые пишут разработчики и выкладывают их на специальный "маркет", где их могут "купить" все желающие. Наверное, можно как-то ограничить доступ и сделать дополнение только для себя, но в любом случае нужно будет соблюсти ряд правил, предъявляемых к разработкам такого рода. Я сам пока никогда свои дополнения не делал, но скачивал с маркета чужие (например, игру "Судоку"). Обычно после скачивания в меню таблиц автоматически появляется соответствующий пункт (как подпункт раздела "Расширения"), при помощи которого можно запустить функционал дополнения.