Сброс значения поля выбора в управляемой форме 1С 8.3

· 9 мин

Содержание

Очистить поле выбора в 1С пользователь может сочетанием Shift+F4 или крестиком справа в поле. Программно поле очищают через данные: реквизиту присваивают пустое значение его типа, например ПредопределенноеЗначение("Справочник.Контрагенты.ПустаяСсылка"). У самого элемента формы метода «очистить» нет. Вы работаете с реквизитом, к которому поле привязано.

Всё ниже относится к платформе 8.3 и управляемым формам («Такси»). Приёмы общие для любой конфигурации: БП 3.0, ЗУП 3.1, УТ 11 и самописных баз. Отдельно разобраны список выбора, параметры выбора, поля составного типа и события, которые срабатывают при очистке.

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

Сначала определите, что именно нужно очистить. От этого зависит способ:

Что очищаемЧем
Значение в полеПустое значение типа в реквизите
Варианты в выпадающем спискеСписокВыбора.Очистить()
Ограничения формы выбораНовый пустой ПараметрыВыбора
Фильтр списка по полюОтбор.Элементы динамического списка
Строки таблицыОчистить() табличной части

Для пользователя есть два способа:

  • ⌨️ Shift+F4, когда курсор стоит в поле. Работает в любом поле ввода, даже без видимого крестика.
  • ❌ Кнопка очистки (крестик) справа в поле. Она видна, только если у элемента включено свойство.

Включить крестик может разработчик:

  1. Откройте форму в конфигураторе или расширении.
  2. Выделите поле на вкладке «Элементы».
  3. В палитре свойств найдите «Кнопка очистки» (КнопкаОчистки) и включите её.

То же из кода, например в ПриСозданииНаСервере:

Элементы.Контрагент.КнопкаОчистки = Истина;

Если поле в режиме «Только просмотр» или недоступно, очистить его не получится ни крестиком, ни Shift+F4. Сначала проверьте эти свойства, а потом ищите ошибку в коде.

В типовой конфигурации форму на поддержке не правьте. Кнопку очистки и обработчики удобнее добавлять расширением: обновление релиза их не затрёт.

Пустое значение реквизита: чем очищать поле в коде

Поле формы показывает значение реквизита. Очистить поле значит записать в реквизит «пустоту» его типа. Для каждого типа она своя.

Тип реквизитаПустое значениеПроверка
Строка""ПустаяСтрока(Значение)
Число0Значение = 0
Дата'00010101' или Дата(1, 1, 1)Не ЗначениеЗаполнено(Значение)
БулевоЛожьНе Значение
Ссылка на справочник или документПустаяСсылка() менеджераЗначение.Пустая()
ПеречислениеПустаяСсылка() менеджера перечисленияНе ЗначениеЗаполнено(Значение)
Составной типНеопределено (тип тоже сбрасывается)Не ЗначениеЗаполнено(Значение)

Функция ЗначениеЗаполнено() подходит для проверки любого из этих типов. Пишите её в условиях вместо сравнения с конкретной пустой ссылкой.

На сервере и на клиенте пустую ссылку получают по-разному

Менеджеры объектов (Справочники, Документы, Перечисления) на клиенте недоступны. Поэтому:

&НаСервере
Процедура ОчиститьСкладНаСервере()
	Объект.Склад = Справочники.Склады.ПустаяСсылка();
КонецПроцедуры

&НаКлиенте
Процедура ОчиститьСклад(Команда)
	// без вызова сервера
	Объект.Склад = ПредопределенноеЗначение("Справочник.Склады.ПустаяСсылка");
КонецПроцедуры

Клиентский вариант лучше: нет лишнего серверного вызова, и форма сразу показывает пустое поле.

Если тип реквизита заранее не известен (универсальная обработка), пустое значение даёт описание типов:

&НаСервере
Процедура ОчиститьРеквизитПоИмени(ИмяРеквизита)
	ОписаниеТипа = РеквизитФормыВЗначение("Объект").Метаданные().Реквизиты[ИмяРеквизита].Тип;
	Объект[ИмяРеквизита] = ОписаниеТипа.ПривестиЗначение(Неопределено);
КонецПроцедуры

Для реквизита одного типа ПривестиЗначение(Неопределено) вернёт пустое значение этого типа: пустую ссылку, 0 или пустую строку.

Очистка через реквизит формы, объект и табличную часть

Где лежат данные поля, там их и очищают. Типовых мест три.

Реквизит объекта (поле привязано к Объект.Контрагент):

Объект.Контрагент = ПредопределенноеЗначение("Справочник.Контрагенты.ПустаяСсылка");

Собственный реквизит формы (обработка, отчёт, поле отбора в шапке списка):

ОтборСклад = ПредопределенноеЗначение("Справочник.Склады.ПустаяСсылка");

Колонка табличной части — обходим строки:

Для Каждого Строка Из Объект.Товары Цикл
	Строка.Склад = ПредопределенноеЗначение("Справочник.Склады.ПустаяСсылка");
КонецЦикла;

Поле в текущей строке таблицы. Частая задача: в строке сменили номенклатуру — характеристика должна очиститься. Строку берут через ТекущиеДанные элемента таблицы:

&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)
	ТекСтрока = Элементы.Товары.ТекущиеДанные;
	Если ТекСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	ТекСтрока.Характеристика = ПредопределенноеЗначение("Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка");
КонецПроцедуры

Имя справочника характеристик в разных конфигурациях своё. Подставьте то, что указано в типе реквизита строки. Пользователь в ячейке таблицы очищает значение тем же Shift+F4.

Если нужно убрать не колонку, а все строки, у табличной части есть метод Очистить(): Объект.Товары.Очистить().

Очистка в форме меняет только данные формы. В базе значение исчезнет после записи объекта. Если форма закрыта без записи, реквизит останется прежним.

Ещё одна деталь — флаг изменений формы. Если после очистки из кода форма должна спросить «Сохранить изменения?» при закрытии, выставьте Модифицированность = Истина сами. Так вы не будете зависеть от того, как платформа отметит программное изменение.

Отдельный случай — серверный код, который берёт объект через РеквизитФормыВЗначение("Объект"). Очистили реквизит у полученного объекта — верните его в форму вызовом ЗначениеВРеквизитФормы(ДокОбъект, "Объект"). Иначе изменение потеряется и поле останется заполненным.

Как очистить список выбора и параметры выбора поля

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

Список выбора

СписокВыбора — фиксированный перечень значений в выпадающем списке. Это СписокЗначений, и у него есть метод Очистить():

&НаКлиенте
Процедура ВидОплатыПриИзменении(Элемент)
	Список = Элементы.СпособДоставки.СписокВыбора;
	Список.Очистить();
	Если Объект.ВидОплаты = "Наличные" Тогда
		Список.Добавить("Самовывоз");
	Иначе
		Список.Добавить("Курьер");
		Список.Добавить("Транспортная компания");
	КонецЕсли;
	Объект.СпособДоставки = "";
КонецПроцедуры

Последняя строка важна. Очистка списка значение в реквизите не трогает. Без неё в поле останется вариант, которого в новом списке уже нет.

Параметры выбора

ПараметрыВыбора ограничивают форму выбора: например, показывать только договоры выбранного контрагента. Свойство имеет тип ФиксированныйМассив, поэтому изменить его на месте нельзя. Его заменяют целиком:

// снять все ограничения
Элементы.Договор.ПараметрыВыбора = Новый ФиксированныйМассив(Новый Массив);

// поставить новое
Параметры = Новый Массив;
Параметры.Добавить(Новый ПараметрВыбора("Отбор.Владелец", Объект.Контрагент));
Элементы.Договор.ПараметрыВыбора = Новый ФиксированныйМассив(Параметры);

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

Поля составного типа: что считать пустым

У реквизита составного типа (например, субконто, где возможен и контрагент, и номенклатура) есть две «пустоты»:

  • 🔹 Неопределено — нет ни значения, ни типа. Пользователю при выборе предложат сначала выбрать тип.
  • 🔹 Пустая ссылка конкретного типа — тип выбран, значение пустое.

Обе проверяет ЗначениеЗаполнено() — она вернёт Ложь. Но для кода разница большая: ТипЗнч(Неопределено) не совпадёт ни с одним ссылочным типом. Проверки вида Если ТипЗнч(Объект.Субконто) = Тип("СправочникСсылка.Контрагенты") после сброса в Неопределено перестанут срабатывать.

Сбросить значение и оставить тип:

&НаКлиенте
Процедура ОчиститьСохранивТип()
	Если Объект.Субконто = Неопределено Тогда
		Возврат;
	КонецЕсли;
	Типы = Новый Массив;
	Типы.Добавить(ТипЗнч(Объект.Субконто));
	Объект.Субконто = Новый ОписаниеТипов(Типы).ПривестиЗначение(Неопределено);
КонецПроцедуры

Сбросить полностью, вместе с типом:

Объект.Субконто = Неопределено;

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

Ограничить набор типов в конкретном поле можно свойством поля ОграничениеТипа. Будет ли пользователь видеть окно выбора типа, определяет свойство ВыбиратьТип.

События при очистке поля: Очистка, ПриИзменении и связи параметров

Событие «Очистка»

Когда пользователь жмёт крестик или Shift+F4, у поля срабатывает событие Очистка. В обработчике очистку можно запретить:

&НаКлиенте
Процедура ДоговорОчистка(Элемент, СтандартнаяОбработка)
	Если Объект.Товары.Количество() > 0 Тогда
		СтандартнаяОбработка = Ложь;
		ПоказатьПредупреждение(, "Договор нельзя очистить, пока в документе есть товары.");
	КонецЕсли;
КонецПроцедуры

Обработчик назначают в палитре свойств поля, группа «События», строка «Очистка».

«ПриИзменении» и программная очистка

После интерактивной очистки срабатывает ещё и ПриИзменении. Там обычно пересчитывают зависимые поля.

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

Объект.Контрагент = ПредопределенноеЗначение("Справочник.Контрагенты.ПустаяСсылка");
КонтрагентПриИзменении(Элементы.Контрагент);

«ОбработкаВыбора»: не пустить неподходящее значение

Иногда проще не очищать поле потом, а не дать ему заполниться. Событие ОбработкаВыбора срабатывает, когда пользователь выбрал значение в форме выбора. До того как оно попадёт в реквизит:

&НаКлиенте
Процедура СкладОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	Если ВыбранноеЗначение = Объект.СкладПолучатель Тогда
		СтандартнаяОбработка = Ложь;
		ПоказатьПредупреждение(, "Склад-отправитель совпадает со складом-получателем.");
	КонецЕсли;
КонецПроцедуры

В поле остаётся прежнее значение, а пользователь сразу видит причину.

Автоочистка зависимого поля

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

Этот механизм работает при интерактивной смене значения. При заполнении из кода зависимое поле тоже очищайте кодом.

Красное подчёркивание после очистки

Если у поля включена «Автоотметка незаполненного» (АвтоОтметкаНезаполненного), после очистки оно подчёркивается красным. Это подсказка, а не ошибка. Запрет записи с пустым значением задаёт другое свойство — «Проверка заполнения» у реквизита. Когда поле законно может быть пустым, отключите оба: иначе пользователи будут считать, что что-то сломалось.

Сброс отбора в списке и сброс выборки запроса

Ещё два значения слова «очистить», которые встречаются рядом с полем выбора.

Отбор динамического списка. Поле выбора в шапке формы списка часто работает как фильтр. При очистке поля отбор надо снять, иначе список останется отфильтрованным:

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

Список.Отбор.Элементы.Очистить() убирает все элементы отбора, заданные кодом. Если отборов несколько, удалите только свой элемент, найдя его по полю ЛевоеЗначение.

Выборка из результата запроса. Когда выборку нужно пройти ещё раз (например, чтобы заполнить второй список выбора), не выполняйте запрос повторно. Есть метод Сбросить():

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
	// первый проход
КонецЦикла;
Выборка.Сбросить();
Пока Выборка.Следующий() Цикл
	// второй проход с начала
КонецЦикла;

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

Диагностика: выберите симптом

Частые вопросы

Можно ли запретить очистку поля только части пользователей?
Да. В обработчике Очистка проверьте роль через РольДоступна("ИмяРоли") на сервере, передайте результат на клиент при создании формы и в нужном случае ставьте СтандартнаяОбработка = Ложь.
Чем `Неопределено` хуже пустой ссылки для поля одного типа?
Для реквизита объекта одного ссылочного типа платформа сама приведёт Неопределено к пустой ссылке. Но в реквизите формы произвольного типа или в переменной Неопределено сохранится как есть, и проверки через ТипЗнч сломаются.
Как очистить сразу все поля шапки формы обработки?
Обойдите реквизиты формы по списку имён и присвойте каждому пустое значение его типа. Для реквизитов объекта удобно взять типы из метаданных и использовать ПривестиЗначение(Неопределено).
Срабатывает ли событие «Очистка» при программном сбросе?
Нет. Оно вызывается только при действии пользователя: крестик или Shift+F4. Код, который очищает реквизит, должен сам выполнять нужные проверки.
Почему крестик в поле не появился, хотя свойство включено?
Проверьте, не стоит ли у поля «Только просмотр» и доступно ли оно. В расширении проверьте, что изменённая форма захвачена и свойство меняется именно в ней, а не в основной конфигурации.