Как сделать доступным свойство «Использование текущей строки» и изменить булево значение в динамическом списке 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке интерфейсов на управляемых формах в платформе «1С:Предприятие 8.3» разработчики часто сталкиваются с неочевидным поведением элементов управления. Типичный сценарий: на форму добавляется таблица (например, динамический список), создается команда формы и соответствующая кнопка, но свойство команды «Использование текущей строки» оказывается заблокированным и отображается серым цветом. Попытки изменить это свойство программно также не приносят результата.

В рамках этой статьи мы подробно разберем, почему возникает данная проблема, как сделать свойство доступным в конфигураторе, а также рассмотрим механизмы изменения булевых значений (флажков) непосредственно в строках динамического списка с помощью кнопки и интерактивных кликов.

Часть 1. Почему заблокировано свойство «Использование текущей строки» и как его включить

Для начала выясним причину такого поведения платформы. Свойство Использование текущей строки (в коде известное как CurrentRowUse) отвечает за то, будет ли команда формы автоматически получать контекст выделенной строки таблицы при ее вызове. Однако команда формы сама по себе является универсальным объектом и изначально «не знает», к какому именно элементу интерфейса (табличной части, таблице значений или динамическому списку) она будет привязана.

Чтобы сделать это свойство доступным для редактирования, выполним следующие шаги в конфигураторе:

  1. Откроем управляемую форму, в которой создана наша команда.
  2. Перейдем на вкладку «Команды» и выделим нужную команду формы.
  3. В панели свойств команды найдем поле «Используемая таблица» (в англоязычной локализации — Associated Table).
  4. В выпадающем списке выберем имя элемента формы, представляющего собой таблицу (например, Список или Элементы.Список).
  5. Как только связь с таблицей установлена, платформа автоматически разблокирует свойство «Использование текущей строки». Теперь мы можем переключить его в значение «Использует».

После выполнения этих действий кнопка, связанная с данной командой, сможет корректно считывать данные текущей активной строки таблицы.

Часть 2. Специфика изменения данных в Динамическом списке

Теперь проанализируем следующую задачу, которую пытался решить разработчик: изменение булевого значения (флажка) в строке динамического списка по нажатию кнопки.

Здесь крайне важно понимать фундаментальное архитектурное ограничение платформы «1С:Предприятие»: динамический список предназначен исключительно для считывания и отображения данных из базы данных. В отличие от объектных табличных частей документов или таблиц значений, находящихся в оперативной памяти, напрямую отредактировать ячейку динамического списка на клиенте невозможно. Данные физически хранятся в таблицах СУБД, и чтобы изменить состояние флажка, нам необходимо перезаписать сам объект в базе данных (или запись регистра), после чего динамический список автоматически обновит свое отображение.

Рассмотрим подробнее классический алгоритм реализации этого процесса по шагам.

Шаг 1. Получение ссылки на текущую строку на клиенте

В обработчике команды формы нам нужно определить, на какой именно строке в данный момент позиционирован пользователь. Для этого мы обращаемся к свойству таблицы формы ТекущаяСтрока.

Шаг 2. Вызов серверной процедуры

Поскольку изменение данных в БД возможно только на стороне сервера, мы должны передать полученный идентификатор строки (как правило, это ссылка на элемент справочника, документ или ключ записи регистра) на сервер. Для оптимизации производительности настоятельно рекомендуется использовать директиву компиляции &НаСервереБезКонтекста, чтобы не передавать весь контекст тяжелой управляемой формы туда и обратно.

Шаг 3. Изменение данных в базе данных и запись объекта

На сервере мы получаем объект по ссылке, инвертируем булево значение реквизита и записываем объект обратно в базу данных.

Посмотрим на пример программной реализации этого алгоритма:


&НаКлиенте
Процедура ИзменитьФлагВСтроке(Команда)
    
    // Получаем элемент таблицы формы
    ТаблицаСписка = Элементы.Список;
    
    // Проверяем, выбрана ли строка
    Если ТаблицаСписка.ТекущаяСтрока = Неопределено Тогда
        ПоказатьПредупреждение(, "Пожалуйста, выберите строку в списке!");
        Возврат;
    КонецЕсли;
    
    // Вызываем серверную процедуру для изменения данных в БД
    ИзменитьФлагНаСервере(ТаблицаСписка.ТекущаяСтрока);
    
    // Принудительно обновляем отображение динамического списка
    ТаблицаСписка.Обновить();
    
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ИзменитьФлагНаСервере(СсылкаНаОбъект)
    
    // Проверяем тип ссылки и получаем объект для редактирования
    // Предположим, что список отображает Справочник.Номенклатура
    Если Справочники.Номенклатура.ТипСсылки().СодержитТип(ТипЗнч(СсылкаНаОбъект)) Тогда
        
        Блокировка = Новый БлокировкаДанных;
        ЭлементБлокировки = Блокировка.Добавить("Справочник.Номенклатура");
        ЭлементБлокировки.УстановитьЗначение("Ссылка", СсылкаНаОбъект);
        
        НачатьТранзакцию();
        Попытка
            Блокировка.Заблокировать();
            
            ОбъектБД = СсылкаНаОбъект.ПолучитьОбъект();
            Если ОбъектБД <> Неопределено Тогда
                // Инвертируем булев реквизит (например, "Активен")
                ОбъектБД.Активен = Не ОбъектБД.Активен;
                ОбъектБД.Записать();
            КонецЕсли;
            
            ЗафиксироватьТранзакцию();
        Исключение
            ОтменитьТранзакцию();
            ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
        КонецПопытки;
        
    КонецЕсли;
    
КонецПроцедуры

Часть 3. Интерактивные флажки без отдельной кнопки (по двойному клику)

Для повышения эргономики интерфейса часто требуется сделать так, чтобы пользователь мог изменять булево значение в строке динамического списка без нажатия дополнительных кнопок на командной панели — например, по двойному клику мыши на ячейке или при одиночном клике на флажок.

Давайте разберем, как реализовать этот сценарий:

  1. В свойствах таблицы динамического списка на форме находим событие Выбор (Selection) и создаем для него обработчик на клиенте.
  2. В свойствах конкретной колонки, отображающей булев реквизит, устанавливаем режим редактирования, чтобы колонка визуально выглядела как интерактивное поле ввода.
  3. Внутри обработчика события Выбор перехватываем стандартное поведение системы, чтобы платформа не пыталась открыть стандартную карточку элемента справочника или документа.

Проанализируем пример кода для обработчика события выбор:


&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    
    // Если пользователь кликнул именно по колонке с булевым значением
    Если Поле.Имя = "СписокАктивен" Тогда
        
        // Отменяем стандартное открытие карточки объекта
        СтандартнаяОбработка = Ложь;
        
        // Запускаем процедуру изменения флага на сервере
        ИзменитьФлагНаСервере(ВыбраннаяСтрока);
        
        // Обновляем элемент формы для визуализации изменений
        Элемент.Обновить();
        
    КонецЕсли;
    
КонецПроцедуры

Часть 4. Множественный выбор строк «галочками» без изменения данных в БД

Существует еще один популярный сценарий: когда флажки в динамическом списке нужны пользователю временно — например, для того, чтобы отметить несколько строк для последующей групповой обработки (печать, проведение, удаление), но при этом сами объекты в базе данных изменять и перезаписывать не нужно.

Для решения этой задачи используется элегантный прием с виртуальным вычисляемым полем динамического списка и клиентским кэшем выбранных ссылок.

Разберем реализацию этого механизма по шагам:

Шаг 1. Модификация текста запроса динамического списка

В настройках динамического списка включим «Произвольный запрос» и добавим виртуальное поле, значение которого будет вычисляться на основе переданного параметра-массива:


ВЫБРАТЬ
    СправочникНоменклатура.Ссылка КАК Ссылка,
    СправочникНоменклатура.Код КАК Код,
    СправочникНоменклатура.Наименование КАК Наименование,
    ВЫБОР
        КОГДА СправочникНоменклатура.Ссылка В (&ВыбранныеЭлементы)
            ТОГДА ИСТИНА
        ИНАЧЕ ЛОЖЬ
    КОНЕЦ КАК Пометка
ИЗ
    Справочник.Номенклатура КАК СправочникНоменклатура

Шаг 2. Настройка визуального отображения колонки

Добавим поле Пометка на форму. В свойствах этого поля установим путь к данным и укажем вид поля — Поле картинки. В качестве картинки значений выберем стандартную системную коллекцию картинок БиблиотекаКартинок.Флажок (или аналогичную пользовательскую коллекцию), где первому индексу соответствует снятый флажок, а второму — установленный.

Шаг 3. Инициализация параметров при создании формы

В модуле формы объявим переменную для хранения выбранных ссылок и инициализируем параметр динамического списка:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартноеОформление)
    
    // Создаем пустой массив для хранения выбранных ссылок
    ВыбранныеЭлементыМассив = Новый Массив;
    
    // Инициализируем параметр запроса динамического списка пустым массивом
    Список.Параметры.УстановитьЗначениеПараметра("ВыбранныеЭлементы", ВыбранныеЭлементыМассив);
    
    // Сохраняем массив во временное хранилище или реквизит формы для доступа на клиенте
    АдресВыбранныхЭлементов = ПоместитьВоВременноеХранилище(ВыбранныеЭлементыМассив, УникальныйИдентификатор);
    
КонецПроцедуры

Шаг 4. Обработка клика по виртуальному флажку

При клике на строку мы будем добавлять ссылку в наш массив (если ее там нет) или удалять (если она уже была выбрана), а затем обновлять параметр динамического списка.


&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    
    Если Поле.Имя = "СписокПометка" Тогда
        
        СтандартнаяОбработка = Ложь;
        
        // Получаем текущий массив выбранных элементов с сервера
        ВыбранныеЭлементыМассив = ПолучитьМассивИзХранилища(АдресВыбранныхЭлементов);
        
        Индекс = ВыбранныеЭлементыМассив.Найти(ВыбраннаяСтрока);
        Если Индекс = Неопределено Тогда
            // Если элемента нет в списке - добавляем его (ставим галочку)
            ВыбранныеЭлементыМассив.Добавить(ВыбраннаяСтрока);
        Иначе
            // Если элемент уже был - удаляем его (снимаем галочку)
            ВыбранныеЭлементыМассив.Удалить(Индекс);
        КонецЕсли;
        
        // Сохраняем измененный массив обратно в хранилище
        ОбновитьМассивВХранилище(АдресВыбранныхЭлементов, ВыбранныеЭлементыМассив);
        
        // Обновляем параметр динамического списка, чтобы платформа перерисовала интерфейс
        Список.Параметры.УстановитьЗначениеПараметра("ВыбранныеЭлементы", ВыбранныеЭлементыМассив);
        
    КонецЕсли;
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьМассивИзХранилища(Адрес)
    Возврат ПолучитьИзВременногоХранилища(Адрес);
КонецФункции

&НаСервереБезКонтекста
Процедура ОбновитьМассивВХранилище(Адрес, Массив)
    ПоместитьВоВременноеХранилище(Массив, Адрес);
КонецПроцедуры

Благодаря этому подходу мы получаем чрезвычайно быстрое, интерактивное управление флажками без единой транзакции записи в базу данных. Это решение идеально подходит для различных форм подбора товаров, группового изменения реквизитов или пакетной печати документов.

Резюмируя все вышесказанное: всегда соотносите задачу с архитектурой платформы. Если вам нужно изменить состояние реального реквизита объекта — используйте транзакционную запись через контекстный или внеконтекстный серверный вызов. Если же галочки нужны временно для удобства работы пользователя — используйте механизм параметров динамического списка и вычисляемых полей.

← На главную