Управляемые формы 1С требуют иного мышления, чем обычные: нет модальности, данные живут то на клиенте, то на сервере, а результат из открытой формы возвращается через оповещение. Ниже собрал четыре приёма, которые закрывают типовые задачи: своё представление объекта в полях и списках, ввод значений без создания отдельной формы, сообщения пользователю, которые не теряются при закрытии окна, и оповещение о закрытии, которое не срабатывает, если форма закрывается в ПриОткрытии.
Каждый приём самостоятельный, код можно переносить в расширение конфигурации, не меняя типовые модули.
Своё представление объекта в 1С
По умолчанию справочник показывается наименованием, документ — «Название № номер от даты». Если хочется видеть в поле ввода и в списках, например, сумму и валюту, представление переопределяется в модуле менеджера двумя обработчиками.
// Состав полей, которые платформа прочитает для построения представления.
Процедура ОбработкаПолученияПолейПредставления(Поля, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Поля.Добавить("Номер");
Поля.Добавить("Дата");
Поля.Добавить("СуммаДокумента");
Поля.Добавить("Валюта");
КонецПроцедуры
// Формирование строки представления из прочитанных полей.
Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Представление = СтрШаблон(НСтр("ru = 'Счет № %1 от %2 на %3 %4'"),
Данные.Номер,
Формат(Данные.Дата, "ДЛФ=D"),
Формат(Данные.СуммаДокумента, "ЧДЦ=2; ЧН=0"),
Данные.Валюта);
КонецПроцедурыКак это работает: платформа сначала спрашивает, какие поля нужны (Поля), читает их одним запросом и передаёт в Данные. Поэтому в ОбработкаПолученияПредставления нельзя обращаться к реквизитам, которых нет в Поля, и не стоит делать запросы — обработчик вызывается очень часто: в каждом поле, в каждой строке списка.
Рекомендации из практики:
- держите представление коротким — оно же выводится в заголовках форм и сообщениях;
- не меняйте представление «под один отчёт»: оно глобально для всей базы;
- в типовой конфигурации делайте это в расширении, в модуле менеджера объекта расширения.
Ввод значений без отдельной формы: всплывающая группа
Задача: по кнопке показать пользователю несколько полей или табличную часть для заполнения, как будто открылось отдельное окно, но без новой формы и без описания передачи данных туда и обратно.
Классический путь — отдельная форма с реквизитами, параметрами открытия и возвратом результата через Закрыть(Результат). Альтернатива — обычная группа на текущей форме с поведением «Всплывающая». В неё кладутся нужные поля и кнопка «Готово», а сама группа по умолчанию скрыта (Видимость = Ложь).
&НаКлиенте
Процедура ОткрытьВводЗначений(Команда)
Элементы.ГруппаВводЗначений.Видимость = Истина;
// Сразу после установки видимости Показать() не срабатывает - откладываем
ПодключитьОбработчикОжидания("ПоказатьГруппуВвода", 0.1, Истина);
// Следим за закрытием «крестиком», чтобы снова скрыть группу
ПодключитьОбработчикОжидания("ПроверитьЗакрытиеГруппыВвода", 1);
КонецПроцедуры
&НаКлиенте
Процедура ПоказатьГруппуВвода()
Элементы.ГруппаВводЗначений.Показать();
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьЗакрытиеГруппыВвода()
Если Элементы.ГруппаВводЗначений.Скрыта() Тогда
Элементы.ГруппаВводЗначений.Видимость = Ложь;
ОтключитьОбработчикОжидания("ПроверитьЗакрытиеГруппыВвода");
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ЗавершитьВводЗначений(Команда)
Элементы.ГруппаВводЗначений.Скрыть();
Элементы.ГруппаВводЗначений.Видимость = Ложь;
ОтключитьОбработчикОжидания("ПроверитьЗакрытиеГруппыВвода");
КонецПроцедурыПлюсы: поля привязаны прямо к Объект, ничего не нужно передавать и возвращать. Минусы: окно нельзя масштабировать и выбрать режим открытия, логику открытия-закрытия приходится имитировать обработчиками ожидания. Я применяю этот приём для двух-трёх полей «быстрого ввода»; если полей больше или нужна проверка заполнения — делаю нормальную форму.
Сообщения пользователю, которые не пропадают после закрытия формы
Типичная жалоба: при «Провести и закрыть» сервер выводит предупреждение, но пользователь его не видит. Причина в том, что сообщения с сервера (СообщениеПользователю.Сообщить() или ОбщегоНазначения.СообщитьПользователю() из БСП) не выводятся сразу, а копятся и показываются в окне формы при возврате на клиент. Форма тут же закрывается — и сообщения вместе с ней.
Решение: на сервере, в последнем вызове перед возвратом, забрать сообщения функцией ПолучитьСообщенияПользователю(), сохранить их в реквизите формы и заново вывести в клиентском ПриЗакрытии. В момент ПриЗакрытии форма уже закрыта, и сообщения попадут в активное окно или в нижнюю панель приложения.

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

Ещё лучше — если условие можно проверить до открытия: тогда вызывающий код вообще не открывает форму. Приём со ВыполнитьОбработкуОповещения нужен, когда решение принимает именно открываемая форма.
Какой приём когда применять
| Ситуация | Приём | На что обратить внимание |
|---|---|---|
| Ссылка в полях и списках выглядит неинформативно | Своё представление в модуле менеджера | Действует на всю базу, без запросов внутри |
| Нужно ввести 2–3 значения по кнопке | Всплывающая группа | Для сложного ввода лучше отдельная форма |
| Предупреждения сервера теряются при закрытии | ПолучитьСообщенияПользователю + ПриЗакрытии | Параметр Ложь, чтобы не было дублей |
| Форма должна закрыться сразу при открытии и вернуть результат | Отказ + ВыполнитьОбработкуОповещения | Лучше вообще не открывать форму, если условие известно заранее |
Все четыре приёма хорошо ложатся в расширение: обработчики модуля менеджера, события формы и новые реквизиты формы добавляются без изменения типовой конфигурации. Если в типовом обработчике формы уже есть код, используйте аннотацию &После для событий формы, чтобы не перекрывать типовую логику.
Типичные ошибки
- Запросы в
ОбработкаПолученияПредставления. Каждая строка списка превращается в отдельный запрос, список начинает тормозить. - Поле не перечислено в
Поля. Обращение кДанные.Реквизитдаст ошибку. ПолучитьСообщенияПользователю(Истина)без вывода. Сообщения удалены и никуда не выведены.- Неэкспортный обработчик оповещения. Платформа не сможет его вызвать.
- Закрытие в
ПриОткрытиичерезЗакрыть(). Результат теряется — используйтеОткази ручной вызов оповещения.
Большинство «странностей» управляемых форм объясняется тем, где и когда выполняется код: на клиенте или на сервере, до открытия окна или после.
Такие доработки форм в типовых конфигурациях делаю через расширения 1С, чтобы обновления проходили без конфликтов; более крупные изменения интерфейса — в рамках доработки 1С.
Итог
- Своё представление объекта задаётся в модуле менеджера:
ОбработкаПолученияПолейПредставления+ОбработкаПолученияПредставления. - Для пары полей быстрого ввода хватает всплывающей группы на текущей форме.
- Серверные сообщения при закрытии формы сохраняйте через
ПолучитьСообщенияПользователю(Ложь)и выводите вПриЗакрытии. - Если форма должна закрыться сразу при открытии, ставьте
Отказ = Истинаи вызывайтеВыполнитьОбработкуОповещения(ОписаниеОповещенияОЗакрытии, Результат).




