При работе с управляемыми формами в 1С часто возникает потребность добавить интерактивные элементы в динамические списки, например, кнопку для выполнения определенной процедуры над текущей строкой. Это может быть подписание документа, запуск отчета или любое другое действие, специфичное для выбранного элемента списка. Давайте рассмотрим подробно, как реализовать такую функциональность, а также как настроить поведение списка и передавать в него параметры.
Представленная задача весьма актуальна для начинающих разработчиков, так как затрагивает базовые принципы взаимодействия с управляемыми формами, динамическими списками и обработкой событий. Мы разберем различные подходы: от добавления стандартной команды формы до создания кнопки прямо в колонке списка, а также выясним, как передавать данные для отбора. В качестве альтернативного интерактивного элемента также полезно рассмотреть способ реализации флажков в динамическом списке для удобного взаимодействия со строками.
Прежде чем добавлять кнопки, нам необходимо убедиться, что у нас есть корректно настроенный динамический список (ДС) на форме. Динамический список — это мощный инструмент для отображения данных из базы данных, который автоматически формирует запросы и обеспечивает эффективную работу с большими объемами информации.
Шаг 1: Создание динамического списка (ДС)
Для начала, если у вас его еще нет, создайте реквизит формы с типом ДинамическийСписок. Для этого в редакторе формы перейдите на закладку Реквизиты, добавьте новый реквизит и укажите его тип. Затем в свойствах этого реквизита необходимо настроить его источник данных. Как правило, это либо основная таблица объекта метаданных (например, документ СписокДокументов), либо произвольный запрос, который вы определяете на закладке Настройки списка.
После создания реквизита перетащите его из списка реквизитов на форму. Система предложит автоматически добавить поля списка — соглашайтесь, это удобно для быстрого старта.
Шаг 2: Добавление команды формы
Один из самых простых и распространенных способов добавить функциональную кнопку — это создать команду формы. Давайте разберем этот процесс по шагам:
Перейдите на закладку Команды в редакторе формы. Здесь мы будем управлять командами, доступными на вашей форме.
Добавьте новую команду, нажав кнопку «Добавить». Присвойте ей осмысленное имя (например, ОбработатьТекущуюСтроку) и синоним, который будет виден пользователю (например, "Обработать").
Создайте обработчик для этой команды. Для этого выберите команду и в ее свойствах нажмите кнопку рядом с полем "Действие". Система предложит создать обработчик на клиенте, который затем может вызывать серверный код.
&НаКлиенте
Процедура ОбработатьТекущуюСтроку(Команда)
// Здесь мы получаем данные текущей строки
ТекущиеДанныеСписка = Элементы.СписокДокументов.ТекущиеДанные;
Если ТекущиеДанныеСписка <> Неопределено Тогда
ОбработатьДокументНаСервере(ТекущиеДанныеСписка.Ссылка);
Иначе
Предупреждение("Не выбрана строка для обработки!");
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ОбработатьДокументНаСервере(СсылкаДокумента)
// Здесь описывается логика обработки документа
ДокументОбъект = СсылкаДокумента.ПолучитьОбъект();
Если ДокументОбъект <> Неопределено Тогда
// Пример: выполняем какое-то действие с документом
ДокументОбъект.Комментарий = "Документ обработан через кнопку";
ДокументОбъект.Записать();
Сообщить("Документ " + ДокументОбъект.Представление + " успешно обработан.");
КонецЕсли;
// Оповещаем список об изменениях, чтобы он обновился
Элементы.СписокДокументов.Обновить();
КонецПроцедуры
В этом примере мы получаем ссылку на текущий документ с помощью Элементы.СписокДокументов.ТекущиеДанные.Ссылка, затем передаем ее на сервер для обработки.
Теперь эту команду необходимо разместить на форме. Перетащите ее из списка команд:
Шаг 3: Добавление команды как колонки (ссылки/картинки)
Если вы хотите, чтобы кнопка была в каждой строке списка, имитируя колонку кнопок, можно использовать поле динамического списка, которое выглядит как гиперссылка или картинка. Этот подход требует немного больше ручной настройки:
Создайте в запросе вашего динамического списка дополнительное фиктивное поле, которое будет служить "кнопкой". Например, это может быть текстовое поле с фиксированным значением "Подписать" или даже NULL, если мы будем использовать картинку.
ВЫБРАТЬ
Документ.МойДокумент.Ссылка КАК Ссылка,
Документ.МойДокумент.Номер КАК Номер,
Документ.МойДокумент.Дата КАК Дата,
"Подписать" КАК КнопкаПодписать
ИЗ
Документ.МойДокумент КАК МойДокумент
На форме в элементе "Динамический список" добавьте новое поле. Укажите в качестве "Пути к данным" имя созданного фиктивного поля из запроса (в нашем случае КнопкаПодписать).
В свойствах этого нового поля установите вид поля:
Истина.Для обработки нажатия на такое поле используйте событие ПриНажатии или ПриАктивизацииЯчейки для этого поля в динамическом списке. В обработчике, как и в случае с командой формы, вы сможете получить данные текущей строки.
&НаКлиенте
Процедура СписокДокументовКнопкаПодписатьПриНажатии(Элемент, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь; // Предотвращаем стандартное действие, если таковое есть
ТекущиеДанныеСписка = Элементы.СписокДокументов.ТекущиеДанные;
Если ТекущиеДанныеСписка <> Неопределено Тогда
// Получаем ссылку на документ и выполняем действие
ОбработатьДокументНаСервере(ТекущиеДанныеСписка.Ссылка);
КонецЕсли;
КонецПроцедуры
Когда вы добавляете интерактивные элементы в динамический список, очень важно правильно настроить обработку событий, чтобы избежать нежелательного стандартного поведения и реализовать вашу логику.
Стандартное открытие документа и его предотвращение
По умолчанию, при двойном клике или нажатии клавиши Enter на строке динамического списка, связанного с документом, платформа 1С пытается открыть форму этого документа. Если ваша цель — выполнить процедуру, а не открыть документ, это поведение нужно перехватить.
Для этого мы используем обработчики событий элемента формы "Динамический список":
В обработчике соответствующего события (например, СписокДокументовОбработкаВыбора) установите параметр СтандартнаяОбработка в Ложь. Это укажет платформе, что вы берете управление на себя и стандартное действие выполнять не нужно.
&НаКлиенте
Процедура СписокДокументовОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь; // Важно! Отменяем стандартное действие
// Здесь можем вызывать нашу процедуру
ТекущиеДанныеСписка = Элемент.ТекущиеДанные;
Если ТекущиеДанныеСписка <> Неопределено Тогда
ОбработатьДокументНаСервере(ТекущиеДанныеСписка.Ссылка);
КонецЕсли;
КонецПроцедуры
Мы рекомендуем использовать это в ОбработкаВыбора, если вы хотите полностью переопределить действие по двойному клику для всего списка. Если же вам нужно специфическое поведение только для определенной колонки, используйте событие ПриНажатии для этой колонки, как мы рассматривали ранее.
Доступ к данным текущей строки
В любом обработчике события, связанном с динамическим списком (будь то команда формы, контекстное меню или событие колонки), вы всегда можете получить данные текущей (выделенной) строки с помощью свойства Элементы.Список.ТекущиеДанные. Это свойство возвращает объект, содержащий значения всех полей текущей строки, доступных в запросе динамического списка.
Например, чтобы получить ссылку на документ:
ТекущаяСсылка = Элементы.СписокДокументов.ТекущиеДанные.Ссылка;
// Затем можно использовать эту ссылку для получения объекта или открытия формы
Важно всегда проверять ТекущиеДанные на Неопределено, так как пользователь мог ничего не выбрать.
Полный контроль над выбором: удаление "Основной таблицы"
В некоторых сложных сценариях, когда ваш динамический список построен на основе очень сложного запроса, и в нем нет явной "основной таблицы" (или вы специально ее не указываете), платформа может не знать, как себя вести по событию "Выбор". В таких случаях, если вы хотите полностью контролировать открытие документов по ссылке, вам придется реализовывать это вручную. Для этого в запросе ДС обязательно должна присутствовать ссылка на документ.
Вы можете использовать события Выбор, ВыборЗначения или ПриНачалеРедактирования, как мы уже говорили, чтобы перехватить действие и затем самостоятельно открыть форму документа, используя полученную ссылку:
&НаКлиенте
Процедура СписокДокументовВыбор(Элемент, ВыбраннаяСтрока, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Если ВыбраннаяСтрока <> Неопределено Тогда
СсылкаДокумента = ВыбраннаяСтрока.Ссылка; // Предполагаем, что в запросе есть поле Ссылка
Если ТипЗнч(СсылкаДокумента) = Тип("ДокументСсылка.МойДокумент") Тогда
ОткрытьЗначение(СсылкаДокумента); // Открываем стандартную форму документа
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Часто требуется открыть форму списка с уже предустановленным отбором, например, по определенному периоду, контрагенту или статусу документа. Динамические списки в управляемых формах формируются на основе механизма Системы Компоновки Данных (СКД), что позволяет гибко управлять параметрами и отборами.
Принцип работы ДС с параметрами
В запросе вашего динамического списка вы можете использовать параметры. Например, чтобы отобрать документы по конкретной дате или статусу:
ВЫБРАТЬ
Документ.МойДокумент.Ссылка,
Документ.МойДокумент.Номер,
Документ.МойДокумент.Дата,
Документ.МойДокумент.Статус
ИЗ
Документ.МойДокумент КАК МойДокумент
ГДЕ
МойДокумент.Дата >= &НачалоПериода
И МойДокумент.Дата <= &КонецПериода
И МойДокумент.Статус = &ТекущийСтатус
Затем эти параметры нужно установить при открытии или инициализации формы списка.
Метод 1: Передача параметров при открытии формы и их установка
Это основной способ, если вам нужен полный контроль над параметрами запроса или требуется передать сложные значения.
В форме-источнике (откуда открывается список):
Создайте структуру с параметрами и передайте ее в качестве второго аргумента функции ОткрытьФорму():
// Например, в обработчике кнопки на другой форме
&НаКлиенте
Процедура ОткрытьСписокСОтбором(Команда)
СтруктураПараметров = Новый Структура();
СтруктураПараметров.Вставить("НачалоПериода", НачалоДня(ТекущаяДата()));
СтруктураПараметров.Вставить("КонецПериода", КонецДня(ТекущаяДата()));
СтруктураПараметров.Вставить("ТекущийСтатус", Перечисления.СтатусыДокументов.Обработан);
ОткрытьФорму("Документ.МойДокумент.ФормаСписка", СтруктураПараметров);
КонецПроцедуры
В открываемой форме списка (обработчик ПриСозданииНаСервере()):
В этом обработчике формы списка мы получаем переданные параметры через аргумент Параметры и устанавливаем их для динамического списка с помощью метода Список.УстановитьЗначениеПараметра().
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем, были ли переданы параметры
Если Параметры.Свойство("НачалоПериода") Тогда
Список.УстановитьЗначениеПараметра("НачалоПериода", Параметры.НачалоПериода);
КонецЕсли;
Если Параметры.Свойство("КонецПериода") Тогда
Список.УстановитьЗначениеПараметра("КонецПериода", Параметры.КонецПериода);
КонецЕсли;
Если Параметры.Свойство("ТекущийСтатус") Тогда
Список.УстановитьЗначениеПараметра("ТекущийСтатус", Параметры.ТекущийСтатус);
КонецЕсли;
КонецПроцедуры
Метод УстановитьЗначениеПараметра() принимает имя параметра из запроса ДС и его значение. Динамический список сам переформирует запрос с новыми параметрами.
Метод 2: Использование параметра "Отбор" при открытии формы
Если вам нужно установить простой отбор по равенству значений одного или нескольких полей, вы можете использовать специальный параметр Отбор при открытии формы. Этот метод более лаконичен и не требует дополнительного кода в обработчике ПриСозданииНаСервере открываемой формы, так как платформа автоматически применяет этот отбор.
В форме-источнике:
Создайте структуру, где ключи — это имена полей, по которым нужно произвести отбор, а значения — это значения отбора. Затем передайте эту структуру как значение параметра Отбор:
// В форме, которая открывает список
&НаКлиенте
Процедура ОткрытьСписокСАвтоматическимОтбором(Команда)
СтруктураОтбора = Новый Структура();
СтруктураОтбора.Вставить("Ссылка", Объект.Ссылка); // Отбор по ссылке текущего документа
СтруктураОтбора.Вставить("Статус", Перечисления.СтатусыДокументов.ВРаботе); // Отбор по статусу
ПараметрыОткрытия = Новый Структура("Отбор", СтруктураОтбора);
ОткрытьФорму("Документ.МойДокумент.ФормаСписка", ПараметрыОткрытия);
КонецПроцедуры
В открываемой форме списка:
В этом случае, если отбор простой (равенство), вам не нужно писать дополнительный код в ПриСозданииНаСервере() для установки этого отбора. Динамический список сам "понимает" параметр Отбор и применяет его.
Для более сложных отборов (больше, меньше, в списке):
Если вам требуется не просто равенство, а, например, отбор "Больше" или "В списке", тогда метод с параметром Отбор не подойдет напрямую для установки вида сравнения. В этом случае придется использовать программное управление отбором через объект Список.Отбор или Список.КомпоновщикНастроек в обработчике ПриСозданииНаСервере(). Вы можете добавлять элементы отбора, указывая вид сравнения:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("НачалоПериода") Тогда
НовыйЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновщикаНастроек"));
НовыйЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Дата");
НовыйЭлементОтбора.ВидСравнения = ВидСравненияКомпоновщикаНастроек.БольшеИлиРавно;
НовыйЭлементОтбора.ПравоеЗначение = Параметры.НачалоПериода;
НовыйЭлементОтбора.Использование = Истина;
КонецЕсли;
КонецПроцедуры
Программное управление отбором через КомпоновщикНастроек
Динамический список тесно связан с механизмом СКД. Для более тонкой настройки отбора, недоступной через простые параметры, мы можем напрямую взаимодействовать с компоновщиком настроек динамического списка. У него есть несколько свойств, связанных с отбором:
Список.Отбор: Упрощенный доступ к текущему отбору списка.Список.КомпоновщикНастроек.Настройки.Отбор: Основной объект для управления отбором.Список.КомпоновщикНастроек.ПользовательскиеНастройки.Отбор: Отбор, установленный пользователем через форму настроек.Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор: Отбор, который не может быть изменен пользователем. Очень полезен для установки обязательных, неизменяемых условий.Мы рекомендуем использовать ФиксированныеНастройки.Отбор, когда нужно задать отбор, который пользователь не должен отключать или изменять. Это обеспечивает стабильность и корректность отображаемых данных.
При работе с динамическими списками и управляемыми формами мы рекомендуем учитывать несколько важных аспектов, которые помогут вам создавать более эффективные и удобные решения.
Производительность
Избегайте слишком сложных запросов в динамических списках. Платформа 1С оптимизирована для работы с простыми запросами, которые могут получать данные порциями. Чрезмерно сложные запросы, особенно с множеством соединений или вложенными запросами, могут значительно снизить производительность списка, особенно при большом объеме данных. Если вам нужно отобразить вспомогательную информацию, которую сложно или неэффективно получить в основном запросе ДС, рассмотрите использование обработчика ПриПолученииДанныхНаСервере для табличного поля формы. Этот внеконтекстный серверный обработчик позволяет изменять или дополнять данные уже после того, как они были получены из базы данных, но до их отображения на клиенте. Таким образом, вы можете выполнять дополнительные вычисления или обращения к базе данных для каждой строки без утяжеления основного запроса ДС.
Программное добавление колонок
Колонки в динамический список могут быть добавлены не только через конфигуратор, но и программно. Это бывает полезно, когда состав колонок зависит от настроек пользователя или определенных условий. Добавление колонок программно выполняется в обработчике ПриСозданииНаСервере формы. Важно убедиться, что добавляемое поле существует в запросе динамического списка или является вычислимым полем, которое вы заполняете в ПриПолученииДанныхНаСервере. Для решения подобных задач можно использовать практические методы доработки динамических списков и добавления полей.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
НоваяКолонка = Элементы.СписокДокументов.Колонки.Добавить("МояДополнительнаяКолонка");
НоваяКолонка.Заголовок = "Доп. инфо";
НоваяКолонка.ПутьКДанным = "МоеПолеИзЗапроса"; // Или вычислимое поле
НоваяКолонка.Вид = ВидПоляФормы.ПолеНадписи;
// Другие свойства, например, ширина, видимость
КонецПроцедуры
Условное оформление
Для улучшения читаемости и визуализации данных в динамическом списке мы можем применять условное оформление. Это может быть изменение цвета текста или фона строки/ячейки в зависимости от значения поля. Как и в случае с дополнительной информацией, это удобно делать в обработчике ПриПолученииДанныхНаСервере. В этом обработчике мы имеем доступ к данным каждой строки и можем применять к ним различные параметры оформления:
ЦветФонаЦветТекстаШрифт (жирный, курсив и т.д.)Видимость (скрыть или показать элемент)Доступность (запретить или разрешить взаимодействие)Отображать (скрыть или показать значение)Текст (изменить отображаемый текст)Формат (применить форматирование числа, даты и т.д.)Используйте эти возможности для создания наглядных и информативных списков, например, выделяя красным цветом просроченные документы или зеленым — обработанные.
Взаимодействие с локальным ПО (для подписания документов)
В вашем случае, когда стоит задача подписывать документы с использованием локального софта через веб-клиент, это является достаточно сложной задачей. Стандартный веб-клиент 1С имеет ограничения по доступу к локальным ресурсам пользователя из соображений безопасности. Для реализации такой функциональности обычно требуется использование:
Итак, мы рассмотрели различные способы добавления интерактивных элементов в динамический список управляемой формы 1С, научились обрабатывать события, перехватывать стандартное поведение и передавать параметры для отбора данных. Эти знания дадут вам гибкость в разработке удобных и функциональных интерфейсов для ваших пользователей.