При разработке интерфейсов на платформе «1С:Предприятие 8» программисты часто сталкиваются с необходимостью программно сбросить или обнулить значение в поле ввода на форме. Интуитивное желание использовать метод Очистить() для обычного ссылочного поля или реквизита примитивного типа приводит к возникновению неприятной ошибки: «Метод объекта не обнаружен (Очистить)». В этой статье мы подробно разберем, почему возникает эта ошибка, как устроена работа со значениями различных типов в платформе «1С» и какие существуют лучшие практики для очистки полей формы как на клиенте, так и на сервере.
Для начала проанализируем архитектуру платформы. В «1С:Предприятие 8» метод Очистить() зарезервирован исключительно для коллекций значений и некоторых сложных объектов. Мы можем успешно применить этот метод к следующим объектам:
Объект.Товары.Очистить(). Этот вызов мгновенно удаляет все строки из табличной части.СписокВыбора.Очистить(), что стирает все элементы из выпадающего списка.ТабличныйДокумент.Очистить() полностью очищает ячейки, форматирование и рисунки на поле отчета или печатной формы.Обычное поле ввода на форме всегда связано с конкретным реквизитом (числом, строкой, датой, булевым значением или ссылкой на справочник/документ). У этих типов данных в платформе попросту не существует встроенного метода Очистить(). Чтобы «очистить» такое поле, нам нужно не вызывать метод удаления, а присвоить связанному реквизиту корректное пустое значение, соответствующее его типу данных.
Самый простой и быстрый способ очистить реквизит практически любого типа на клиенте без вызова сервера — это присвоение ему значения Неопределено. Рассмотрим пример кода:
&НаКлиенте
Процедура ОчиститьПолеКонтактноеЛицо(Команда)
Объект.КонтактноеЛицо = Неопределено;
КонецПроцедуры
Этот способ крайне популярен благодаря своей универсальности. Он отлично работает в клиентском коде и не требует никаких серверных вызовов, что положительно сказывается на производительности интерфейса. Однако при работе с Неопределено важно учитывать два критически важных нюанса:
СправочникСсылка.КонтактныеЛица), то при записи объекта в базу данных платформа автоматически преобразует значение Неопределено в типизированную пустую ссылку данного справочника. Но до момента записи в оперативной памяти формы тип значения будет отличаться, что может привести к ошибкам в логике проверок, если вы жестко проверяете тип реквизита.СправочникСсылка.ФизическиеЛица или СправочникСсылка.Контрагенты), присвоение Неопределено полностью сбросит и выбранный тип данных. На форме появится кнопка выбора типа (буква «Т»), вынуждая пользователя заново выбирать категорию данных при последующем заполнении.Для сохранения чистоты типов и избежания неожиданного поведения при записи объекта рекомендуется присваивать реквизитам пустые значения их явных типов. Проанализируем, какие пустые значения соответствуют различным типам данных в системе:
"".0.'00010101000000' (или пустые одинарные кавычки '00010101').Ложь.Рассмотрим, как правильно получить и присвоить пустую ссылку на сервере:
&НаСервере
Процедура ОчиститьПолеНаСервере()
Объект.КонтактноеЛицо = Справочники.КонтактныеЛица.ПустаяСсылка();
КонецПроцедуры
Этот код абсолютно безопасен и типизирован. Но что делать, если нам необходимо выполнить эту операцию на клиенте без контекстного вызова сервера? Для этого мы можем использовать глобальную функцию ПредопределенноеЗначение(). Посмотрим на пример реализации:
&НаКлиенте
Процедура ОчиститьПолеНаКлиенте()
Объект.КонтактноеЛицо = ПредопределенноеЗначение("Справочник.КонтактныеЛица.ПустаяСсылка");
КонецПроцедуры
Важное замечание по производительности: Существует миф, что функция ПредопределенноеЗначение() при каждом вызове совершает медленное обращение к серверу. На самом деле платформа выполняет серверный запрос только при самом первом обращении к конкретному значению в сеансе работы пользователя. После этого результат кэшируется на клиенте, и повторные обращения происходят мгновенно, не нагружая сетевой трафик и сервер приложений.
Если ваша конфигурация разработана на базе БСП (что справедливо для подавляющего большинства современных прикладных решений 1С), мы можем использовать готовые функции общих модулей. Разберем два наиболее полезных метода. Для быстрого поиска аналогичных полезных функций библиотеки и примеров их работы подойдёт справочник по методам БСП с примерами кода.
Во-первых, функция получения пустого значения по типу данных: ОбщегоНазначенияБПКлиентСервер.ПустоеЗначениеТипа(ЗаданныйТип). Эта функция избавляет нас от необходимости писать громоздкие конструкции Если...ИначеЕсли при динамической очистке реквизитов формы. Ее внутреннее устройство выглядит следующим образом:
Функция ПустоеЗначениеТипа(ЗаданныйТип) Экспорт
Если ЗаданныйТип = Тип("Число") Тогда
Возврат 0;
ИначеЕсли ЗаданныйТип = Тип("Строка") Тогда
Возврат "";
ИначеЕсли ЗаданныйТип = Тип("Дата") Тогда
Возврат '00010101000000';
ИначеЕсли ЗаданныйТип = Тип("Булево") Тогда
Возврат Ложь;
Иначе
Возврат Новый (ЗаданныйТип);
КонецЕсли;
КонецФункции
Во-вторых, для безопасного получения предопределенных значений или пустых ссылок на клиенте в БСП предусмотрена функция ОбщегоНазначенияКлиент.ПредопределенныйЭлемент(). В отличие от стандартного платформенного метода, она не вызывает критического сбоя приложения (исключения), если предопределенный элемент или тип данных отсутствует в текущей базе данных, а возвращает безопасное значение Неопределено.
Очень часто программная очистка должна происходить не по нажатию отдельной кнопки, а в момент, когда сам пользователь интерактивно очищает поле ввода на форме (например, нажимая крестик очистки в поле или горячие клавиши Shift + F4). Для управления этим поведением мы можем использовать стандартное событие элемента формы Очистка.
Разберем по шагам, как правильно настроить этот механизм:
Очистка и нажмем на кнопку создания обработчика на клиенте.Посмотрим на пример практической реализации, где при очистке контрагента автоматически должны очищаться связанные с ним договор и контактное лицо:
&НаКлиенте
Процедура КонтрагентОчистка(Элемент, СтандартнаяОбработка)
// Отменяем стандартное поведение платформы, чтобы взять управление в свои руки
СтандартнаяОбработка = Ложь;
// Очищаем основное поле ввода
Объект.Контрагент = ПредопределенноеЗначение("Справочник.Контрагенты.ПустаяСсылка");
// Очищаем зависимые реквизиты, чтобы не допустить некорректных данных на форме
Объект.ДоговорКонтрагента = ПредопределенноеЗначение("Справочник.ДоговорыКонтрагентов.ПустаяСсылка");
Объект.КонтактноеЛицо = ПредопределенноеЗначение("Справочник.КонтактныеЛица.ПустаяСсылка");
КонецПроцедуры
Установка параметра СтандартнаяОбработка = Ложь чрезвычайно важна. Она блокирует базовый механизм платформы и гарантирует, что наши кастомные алгоритмы очистки зависимых полей отработают строго в заданной последовательности без конфликтов с внутренними механизмами отображения данных на управляемой форме.
Подводя итоги, отметим: выбор конкретного метода очистки всегда зависит от архитектурной задачи. Для простых реквизитов одиночного типа на форме смело используйте присвоение Неопределено или ПредопределенноеЗначение(). Если же вы работаете со сложными составными типами или завязаны на строгие проверки типов в процедурах перед записью объекта — всегда отдавайте предпочтение явным пустой ссылке или пустому значению примитивного типа.