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