Как при открытии формы очистить реквизиты в 1С:Предприятии 8?

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

При разработке управляемых форм в 1С часто возникает задача привести форму в «исходное» состояние при её открытии — то есть полностью очистить все поля ввода и реквизиты. Однако начинающие разработчики часто сталкиваются с неприятным поведением платформы: код очистки пишется в событии ПриСозданииНаСервере, но после открытия формы поля всё равно оказываются заполненными старыми значениями. В рамках этой статьи мы подробно разберем, почему так происходит, изучим жизненный цикл управляемой формы и рассмотрим правильные, надежные способы циклической очистки реквизитов.

Выясняем причину: почему очистка в «ПриСозданииНаСервере» не работает

Для того чтобы понять суть проблемы, нам необходимо детально проанализировать порядок инициализации управляемой формы платформой «1С:Предприятие 8». Когда пользователь открывает форму, система последовательно выполняет несколько ключевых этапов:

  1. Вызов обработчика ПриСозданииНаСервере. Здесь выполняется ваш первоначальный код инициализации, в том числе попытки программной очистки полей.
  2. Автоматическое восстановление настроек пользователя. Это критически важный шаг. Если у формы или её отдельных элементов включено свойство автоматического сохранения параметров, платформа обращается к системному хранилищу настроек, извлекает сохраненные пользователем значения и записывает их в реквизиты формы. Этот процесс происходит после выполнения процедуры ПриСозданииНаСервере. Таким образом, любые очищенные вами данные перезаписываются старыми значениями.
  3. Вызов обработчика ПриЗагрузкеДанныхИзНастроекНаСервере. В этой процедуре платформа непосредственно применяет восстановленные настройки к форме.
  4. Вызов обработчика ПриОткрытии на клиенте. Форма окончательно отрисовывается и выводится на экран пользователю.

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

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

Решение 1. Управление механизмом сохранения настроек формы

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

Разберем по шагам, как это сделать:

  1. Откройте нужную управляемую форму в конфигураторе.
  2. Перейдите в палитру свойств самой формы (выделив корневой элемент в дереве элементов формы).
  3. Найдите группу свойств «Сохранение данных».
  4. Снимите флажок (или установите значение в «Не использовать») у свойств «Сохранение данных в настройках» и «Автоматическое сохранение параметров».
  5. Дополнительно проверьте свойства конкретных полей ввода на форме — у них также может быть индивидуально включено свойство сохранения данных.

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

Посмотрим на пример кода, который блокирует стандартное заполнение полей сохраненными настройками:


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

Установив параметр СтандартнаяОбработка в значение Ложь, мы сообщаем платформе, что брать данные из системного хранилища настроек и заполнять ими реквизиты формы при её открытии не нужно.

Решение 2. Циклический обход и очистка собственных реквизитов формы

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

Давайте подробно разберем готовый шаблон процедуры, выполняющей циклическую очистку собственных реквизитов формы:


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

Решение 3. Очистка реквизитов и табличных частей основного объекта

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

Проанализируем программное решение для полной очистки шапки и табличных частей объекта:


&НаСервере
Процедура ОчиститьРеквизитыОбъектаНаСервере()
    
    // 1. Очищаем простые реквизиты шапки объекта (документа или справочника)
    Для Каждого Реквизит Из Объект.Метаданные().Реквизиты Цикл
        
        // Приводим реквизит к пустому значению по умолчанию в соответствии с его типом
        Объект[Реквизит.Имя] = Реквизит.Тип.ПривестиЗначение(Неопределено);
        
    КонецЦикла;
    
    // 2. Очищаем все имеющиеся табличные части объекта
    Для Каждого ТабличнаяЧасть Из Объект.Метаданные().ТабличныеЧасти Цикл
        
        Объект[ТабличнаяЧасть.Имя].Очистить();
        
    КонецЦикла;
    
КонецПроцедуры

Этот способ позволяет гарантированно «обнулить» новый объект на сервере, приведя все его реквизиты к значениям по умолчанию, а также полностью опустошить все табличные части.

Важное правило: почему нельзя использовать простое «Неопределено»

Среди разработчиков популярна грубая ошибка — присваивать всем очищаемым реквизитам значение Неопределено (например, ЭтаФорма.МойРеквизит = Неопределено;). Рассмотрим подробнее, почему так делать не стоит.

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

Придерживайтесь правил корректного приведения типов:

Использование конструкции ПривестиЗначение(Неопределено) у объекта описания типов (ОписаниеТипов) является наиболее универсальным и безопасным системным методом в среде «1С:Предприятие 8». Он автоматически определяет тип реквизита и возвращает корректное пустое значение этого типа.

← На главную