В процессе разработки в среде 1С:Предприятие 8 часто возникает задача предоставить пользователю механизм быстрой очистки всех заполненных данных на форме. Это особенно актуально для сложных справочников с большим количеством числовых показателей или расчетных параметров. Вместо того чтобы прописывать очистку каждого поля вручную, мы разберем универсальные способы, которые позволят автоматизировать этот процесс, минимизировать количество кода и сделать решение устойчивым к изменениям структуры метаданных.
Самый логичный и эффективный способ очистки — это использование коллекции метаданных объекта. Вместо создания массива имен реквизитов вручную, мы можем программно получить список всех атрибутов справочника. Рассмотрим, как это реализовать на стороне сервера. Мы обратимся к метаданным конкретного справочника и в цикле установим значения в 0 (так как в исходном вопросе речь шла о числовых полях).
Проанализируем пример кода, который выполняет эту задачу:
&НаСервере
Процедура ОчиститьПоляНаСервере()
// Получаем метаданные нашего объекта (справочника)
МетаданныеОбъекта = Объект.Ссылка.Метаданные();
// Перебираем все реквизиты, описанные в конфигураторе
Для Каждого Реквизит Из МетаданныеОбъекта.Реквизиты Цикл
// Используем обращение через квадратные скобки по имени реквизита
Объект[Реквизит.Имя] = 0;
КонецЦикла;
КонецПроцедуры
В данном примере мы используем конструкцию Объект[Реквизит.Имя]. Это наиболее правильный способ обращения к данным, когда имя поля известно в виде строки. Важно понимать, что этот код изменит значения только тех реквизитов, которые принадлежат самому справочнику, но не затронет стандартные реквизиты (такие как Код или Наименование).
Часто на форме присутствуют реквизиты разных типов: строки, даты, числа и ссылки. Если мы просто присвоим всем полям 0, это приведет к ошибке типов для нечисловых полей. Выясним, как сделать очистку выборочной, проверяя тип каждого реквизита перед его изменением.
Рассмотрим ситуацию, когда нам нужно обнулить только числовые показатели, не затрагивая текстовые комментарии или даты:
&НаСервере
Процедура ОчиститьТолькоЧислаНаСервере()
Для Каждого Реквизит Из Объект.Метаданные().Реквизиты Цикл
// Проверяем, содержит ли описание типов реквизита тип "Число"
Если Реквизит.Тип.СодержитТип(Тип("Число")) Тогда
Объект[Реквизит.Имя] = 0;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Использование метода СодержитТип() позволяет корректно обрабатывать даже составные типы данных. Если поле может содержать и число, и ссылку, условие сработает, и мы сможем установить начальное значение.
Если задача стоит шире — очистить абсолютно все поля, приведя их к "пустому" состоянию (для строки — пустая строка, для даты — пустая дата, для числа — ноль), — лучше всего использовать метод ПривестиЗначение(). Это избавит нас от написания множества условий Если...Тогда.
Разберем этот системный подход:
&НаСервере
Процедура ПолнаяОчисткаВсехТиповНаСервере()
Для Каждого Реквизит Из Объект.Метаданные().Реквизиты Цикл
// Метод ПривестиЗначение без параметров возвращает пустое значение данного типа
Объект[Реквизит.Имя] = Реквизит.Тип.ПривестиЗначение();
КонецЦикла;
// Не забываем про табличные части, если они есть
Для Каждого ТЧ Из Объект.Метаданные().ТабличныеЧасти Цикл
Объект[ТЧ.Имя].Очистить();
КонецДля;
КонецПроцедуры
Этот метод является наиболее профессиональным, так как он автоматически подстраивается под структуру данных 1С. Мы также добавили очистку табличных частей, что часто требуется при полной "перезагрузке" формы пользователем.
Как отмечалось в обсуждении, иногда простая очистка в 0 недопустима, так как у реквизитов есть минимально возможные значения (например, коэффициент не может быть меньше 1). В таких случаях у нас есть два пути:
Реквизит.ЗначениеЗаполнения.Посмотрим на пример совмещения этих подходов:
&НаСервере
Процедура ОчиститьСУчетомМинимумов()
// Массовая очистка
Для Каждого Реквизит Из Объект.Метаданные().Реквизиты Цикл
Объект[Реквизит.Имя] = 0;
КонецЦикла;
// Индивидуальная настройка исключений
Объект.МинимальнаяДистанция = 5;
Объект.КоэффициентТранспортировки = 1.2;
// Сообщим форме, что данные изменились
ЭтаФорма.Модифицированность = Истина;
КонецПроцедуры
При реализации кнопки очистки стоит обратить внимание на следующие технические моменты, которые помогут избежать ошибок в интерфейсе и логике программы:
1. Отказ от функции Выполнить(). В некоторых примерах на форумах встречается использование команды Выполнить("Объект." + Имя + " = 0"). Мы настоятельно рекомендуем не использовать этот подход. Он работает медленнее, его сложно отлаживать, и он может вызвать проблемы с безопасностью. Прямое обращение через Объект[Имя] работает быстрее и стабильнее.
2. Обновление отображения. После того как вы программно изменили десятки полей на сервере, клиентское приложение должно корректно отобразить эти изменения. Обычно управляемые формы справляются с этим автоматически при возврате с сервера, но в сложных случаях может потребоваться вызов ЭтаФорма.ОбновитьОтображениеДанных() на клиенте.
3. Реквизиты формы vs Реквизиты объекта. Помните, что Объект.Метаданные().Реквизиты содержит только те поля, которые сохраняются в базу данных. Если на вашей форме есть вспомогательные флажки или переменные, созданные непосредственно в редакторе формы (не в справочнике), их нужно очищать отдельно, используя метод ЭтаФорма.ПолучитьРеквизиты().
4. Обработка ошибок. Если вы работаете с расширениями или динамически изменяемыми формами, полезно оборачивать присвоение значения в блок Попытка...Исключение, чтобы один недоступный для записи реквизит не прерывал работу всей процедуры очистки.
Проанализировав ситуацию, мы видим, что наиболее сбалансированным решением является сочетание автоматического обхода метаданных с последующей ручной корректировкой специфических полей. Это гарантирует, что даже при добавлении новых полей в справочник в будущем, ваша кнопка очистки продолжит работать без необходимости вносить правки в программный код.