Как реализовать проставление галочки в динамическом списке по клику и обеспечить обновление данных

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

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

Почему прямое изменение ТекущиеДанные не работает?

Проанализируем ситуацию: динамический список — это не таблица в оперативной памяти, а окно в базу данных. Когда мы обращаемся к Элементы.Список.ТекущиеДанные, мы получаем копию строки, которую платформа считала из БД для отображения. Пытаясь выполнить код ТекущиеДанные.Метка = 1, мы меняем значение в локальном кэше этой строки на клиенте. Однако динамический список постоянно обновляется, подгружая данные порциями. Как только происходит скроллинг или любое обновление формы, платформа заново запрашивает данные из источника, и ваша локальная "правка" бесследно исчезает.

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

Способ 1: Использование вычисляемого поля и параметров запроса

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

Шаг 1. Настройка запроса динамического списка. Откроем настройки динамического списка и в тексте запроса добавим поле выбора:


ВЫБОР
    КОГДА Ссылка В (&СписокОтмеченных)
        ТОГДА 1
    ИНАЧЕ 0
КОНЕЦ КАК Метка

Шаг 2. Создание реквизита формы. Создадим на форме реквизит СписокОтмеченных с типом СписокЗначений или Массив.

Шаг 3. Обработка нажатия. Вместо события Выбор, которое требует двойного клика, лучше использовать свойство колонки ГиперссылкаЯчейки. Если установить его в значение Истина, событие Нажатие будет срабатывать от одного клика, что гораздо удобнее для пользователя. Рассмотрим пример кода обработки:


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

Обновление отображения: важные нюансы

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

  1. ЭтаФорма.ОбновитьОтображениеДанных() — самый легкий метод. Он просто перерисовывает элементы формы на клиенте. Часто этого достаточно, если данные в списке уже "знают" о своем изменении.
  2. Элементы.Список.Обновить() — тяжелая артиллерия. Заставляет динамический список полностью перезапросить данные с сервера. Это гарантирует результат, но на больших списках может вызвать кратковременное замирание интерфейса.
  3. ОповеститьОбИзменении(Ссылка) — очень элегантный метод. Платформа сама понимает, что данные по этой ссылке изменились, и обновляет только нужные строки во всех открытых списках.

Способ 2: Работа с большими объемами данных (Актуализация)

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


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

Оптимизация производительности

Посмотрим на ситуацию со стороны производительности. Оператор В (&Массив) в SQL-запросе работает быстро, пока массив содержит до 1000–2000 элементов. Если предполагается, что пользователь может отметить 10 000 или 50 000 строк (например, для массовой печати или обработки), производительность динамического списка резко упадет.

Рекомендация для высоконагруженных систем: вместо параметра-массива используйте временные таблицы в запросе динамического списка. При клике на "галочку" записывайте ссылку во временную таблицу в менеджере временных таблиц, связанном с этим списком. Это потребует более сложной программной настройки, но обеспечит мгновенную работу на любых объемах данных.

Проанализировав все способы, мы видим, что ключом к решению является понимание природы динамического списка. Никогда не пытайтесь менять данные в ТекущиеДанные напрямую. Всегда меняйте источник (базу данных или параметры запроса) и оповещайте форму об изменениях — это залог стабильной работы вашего интерфейса в 1С.

← На главную