Как сохранить и восстановить отмеченные флажки в таблице обработки 1С

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

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

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

Рассмотрим стандартную ошибку при использовании методов СохранитьЗначение() и ВосстановитьЗначение(). Часто программисты пытаются сохранить данные в цикле, используя одно и то же имя ключа для всех строк:


Процедура ПриЗакрытии()
    Для Каждого Строка Из ТаблицаСтатуса Цикл
        СохранитьЗначение("ФлагВернул", Строка.Вернул); 
    КонецЦикла;
КонецПроцедуры

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

Решение №1: Использование уникальных ключей (UID документа + индекс)

Чтобы система понимала, к какой именно строке и какому документу относится флажок, необходимо формировать уникальное имя ключа. Выясним причину, почему это важно: обработка может открываться для разных маршрутных заданий. Если использовать просто индекс строки, то флажки из одного задания «всплывут» в другом.

Рассмотрим пример кода для сохранения данных с использованием Уникального Идентификатора (УИД) ведущего документа:


Процедура ПриЗакрытии()
    Если НЕ ЗначениеЗаполнено(ВыборМЗ) Тогда
        Возврат;
    КонецЕсли;

    УИД_МЗ = Строка(ВыборМЗ.Ссылка.УникальныйИдентификатор());
    инд = 0;
    
    // Сохраняем количество строк, чтобы знать, сколько восстанавливать
    СохранитьЗначение("Кол_Строк_" + УИД_МЗ, ТаблицаСтатуса.Количество());
    
    Для Каждого ТекущаяСтрока Из ТаблицаСтатуса Цикл
        // Формируем уникальные ключи для каждой ячейки
        СохранитьЗначение("Вернул_" + УИД_МЗ + инд, ТекущаяСтрока.Вернул);
        СохранитьЗначение("Закрыта_" + УИД_МЗ + инд, ТекущаяСтрока.НакладнаяЗакрыта);
        инд = инд + 1;
    КонецЦикла;
КонецПроцедуры

Теперь разберем по шагам процесс восстановления этих данных при выборе документа в обработке (например, в событии ПриИзменении поля выбора или при открытии):


Процедура ВосстановитьФлажки()
    Если НЕ ЗначениеЗаполнено(ВыборМЗ) Тогда
        Возврат;
    КонецЕсли;

    УИД_МЗ = Строка(ВыборМЗ.Ссылка.УникальныйИдентификатор());
    инд = 0;
    
    Для Каждого ТекущаяСтрока Из ТаблицаСтатуса Цикл
        ЗначениеВернул = ВосстановитьЗначение("Вернул_" + УИД_МЗ + инд);
        Если ЗначениеВернул <> Неопределено Тогда
            ТекущаяСтрока.Вернул = ЗначениеВернул;
        КонецЕсли;
        
        ЗначениеЗакрыта = ВосстановитьЗначение("Закрыта_" + УИД_МЗ + инд);
        Если ЗначениеЗакрыта <> Неопределено Тогда
            ТекущаяСтрока.НакладнаяЗакрыта = ЗначениеЗакрыта;
        КонецЕсли;
        
        инд = инд + 1;
    КонецЦикла;
КонецПроцедуры

Решение №2: Сохранение всей Таблицы Значений целиком

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

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


// Сохранение
СохранитьЗначение("ДанныеТаблицы_" + Строка(ВыборМЗ.УникальныйИдентификатор()), ТаблицаСтатуса);

// Восстановление
ЗагруженныеДанные = ВосстановитьЗначение("ДанныеТаблицы_" + Строка(ВыборМЗ.УникальныйИдентификатор()));
Если ТипЗнч(ЗагруженныеДанные) = Тип("ТаблицаЗначений") Тогда
    ТаблицаСтатуса = ЗагруженныеДанные.Скопировать();
КонецЕсли;

Важный нюанс: этот метод подходит для Обычных форм. При работе с этим способом убедитесь, что состав колонок сохраняемой таблицы совпадает с составом колонок на форме. В Управляемых формах напрямую работать с ТаблицейЗначений нельзя, там используются механизмы ДанныеФормыКоллекция.

Решение №3: Профессиональный подход — Регистр сведений

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

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

  1. Создаем регистр СтатусыНакладныхВМаршрутах.
  2. Добавляем измерения: МаршрутноеЗадание (Тип: ДокументСсылка.МаршрутноеЗадание) и Накладная (Тип: ДокументСсылка.РеализацияТоваровУслуг).
  3. Добавляем ресурсы: ваши флажки (Вернул, Закрыта и т.д., тип: Булево).

Теперь при изменении флажка в строке мы можем сразу записывать данные в базу данных:


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

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

Оптимизация производительности (Событие ПриПолученииДанных)

Если в вашем маршрутном задании сотни или тысячи накладных, восстановление значений циклом при открытии может «подвесить» форму. Проанализируем ситуацию: пользователю не нужно видеть все тысячи строк сразу, он видит только те, что помещаются на экране.

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

Используйте метод СохранитьЗначение только для временных, не критически важных настроек интерфейса. Для бизнес-логики (статусы документов, отметки о проверке) всегда выбирайте Регистры сведений.

← На главную