Разработка и Конфигурация · 13 мин
Что такое контекст формы в 1С и как с ним работать
Контекст формы 1С — что это, какие свойства и методы доступны, чем отличаются контексты формы, объекта и модуля. Примеры кода и типичные ошибки.
Контекст формы в 1С — это набор свойств, методов и данных, доступных внутри модуля конкретной формы в момент её выполнения. Говоря проще, это «окружение», из которого код формы обращается к реквизитам, элементам управления, данным объекта и стандартным командам платформы. Когда разработчик пишет обработчик события «ПриОткрытии» или «ПриНажатииКнопки», он работает именно в контексте формы.
Понимание контекста критично, потому что одна и та же конструкция ведёт себя по-разному в разных контекстах. Переменная, объявленная в модуле формы, недоступна из модуля объекта; реквизит формы нельзя прочитать напрямую на сервере без специальных приёмов; а обращение к несуществующему в данном контексте свойству завершится ошибкой «Поле объекта не обнаружено». Большинство ошибок начинающих разработчиков 1С связаны именно с непониманием, «где» выполняется код.
Материал рассчитан на начинающих разработчиков и внедренцев, работающих с управляемыми формами (УправляемоеПриложение), но отдельные разделы затрагивают и обычные формы. Примеры кода приведены на встроенном языке 1С и применимы к типовым конфигурациям на платформе 8.3.
Из чего состоит контекст формы
Контекст формы складывается из нескольких слоёв. Первый — стандартные свойства и методы самой формы: ЭтаФорма (или ЭтотОбъект в обычных формах), методы Закрыть(), Прочитать(), Записать(), ОбновитьОтображениеДанных(). Второй слой — реквизиты формы, которые разработчик добавляет в конфигураторе или программно. Третий — элементы формы: поля, кнопки, таблицы, доступные через коллекцию Элементы.
Четвёртый слой — данные основного реквизита формы. Для формы документа это объект типа ДанныеФормыСтруктура, содержащий данные документа. Обращение к нему обычно выглядит как Объект.Номенклатура, где «Объект» — имя основного реквизита формы. Важно понимать: на клиенте это не сам объект базы данных, а его представление в виде данных формы.
Наконец, контекст включает параметры формы (коллекция Параметры, заполненная при открытии), командный интерфейс и стандартные свойства вроде ТолькоПросмотр, Модифицированность, КлючУникальности. Совокупность всего этого и есть то «окружение», в котором выполняется любой обработчик формы.
Клиентский и серверный контекст: директивы компиляции
Ключевая особенность управляемых форм — разделение кода на клиентскую и серверную части. Директива &НаКлиенте означает, что процедура выполняется на компьютере пользователя (в тонком, толстом или веб-клиенте). Директива &НаСервере — что код выполняется на сервере 1С:Предприятия, где доступны запросы к базе данных, менеджеры объектов и всё серверное окружение.
Контексты клиента и сервера принципиально различаются. На клиенте нельзя выполнить запрос к базе, использовать Документы.РеализацияТоваровУслуг.СоздатьДокумент() или обратиться к функции из серверного общего модуля. На сервере недоступны интерактивные действия: нельзя показать предупреждение пользователю, открыть диалог выбора файла или получить ввод данных. Попытка нарушить эти границы приводит к ошибкам компиляции или выполнения.
Существуют также директивы &НаСервереБезКонтекста и &НаКлиентеНаСервереБезКонтекста. Режим «без контекста» означает, что процедура выполняется на сервере, но данные формы ей не передаются — это ускоряет вызов, так как не тратится время на сериализацию и передачу данных формы между клиентом и сервером. Такие процедуры получают нужные значения через параметры.
Сравнение директив
Для работы с элементами формы, интерактива, вызова серверных процедур. Нет доступа к запросам и объектам базы.
Полный доступ к данным формы и базе. Медленнее вызова «без контекста» из-за передачи данных формы.
Быстрый серверный вызов без данных формы. Все нужные значения передаются параметрами.
Универсальные вспомогательные функции без привязки к данным формы, например расчёт суммы строки.
Как обратиться к данным и элементам из контекста формы
Типовые обращения в модуле формы выглядят так. Реквизит формы: просто по имени — КомментарийМенеджера = "Проверено". Данные основного объекта: Объект.СуммаДокумента. Элемент формы: Элементы.ТаблицаТовары.ТекущиеДанные. Свойства самой формы: ЭтаФорма.ТолькоПросмотр = Истина или просто Модифицированность = Истина.
Частая задача — передать данные формы на сервер для обработки. Для этого используется пара методов РеквизитФормыВЗначение() и ЗначениеВРеквизитФормы(). Первый преобразует данные формы в прикладной объект (например, в ДокументОбъект), с которым можно работать запросами и методами объекта; второй возвращает результат обратно в форму.
&НаСервере
Процедура ПересчитатьИтогиНаСервере()
ДокументОбъект = РеквизитФормыВЗначение("Объект");
ИтоговаяСумма = 0;
Для Каждого Строка Из ДокументОбъект.Товары Цикл
ИтоговаяСумма = ИтоговаяСумма + Строка.Сумма;
КонецЦикла;
ДокументОбъект.СуммаДокумента = ИтоговаяСумма;
ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");
КонецПроцедурыОбратите внимание: преобразование РеквизитФормыВЗначение — ресурсоёмкая операция. Если нужно только прочитать одно поле, дешевле получить его напрямую из Объект на сервере с контекстом или передать значение параметром в процедуру без контекста. Массовые вызовы серверных процедур с контекстом в цикле — типичная причина «тормозящих» форм.
Передача данных между формами через контекст
Формы в 1С редко существуют изолированно. При открытии формы ей передаются параметры через структуру, а внутри открываемой формы они доступны в обработчике ПриСозданииНаСервере через коллекцию Параметры. Например, форма выбора получает параметр «Отбор», форма документа — «Ключ» (ссылку на редактируемый объект), «ЗначениеКопирования» или «Основание» для ввода на основании.
Для обратной связи используются два механизма. Первый — оповещения: открывающая форма передаёт описание оповещения (ОписаниеОповещения), а открываемая форма при закрытии вызывает его и передаёт результат, например выбранное значение. Второй — метод Оповестить(), который рассылает событие всем формам, подписавшимся на него в обработчике ОбработкаОповещения.
- 1В форме-источнике создайте ОписаниеОповещения с именем процедуры-обработчика результата.
- 2Вызовите ОткрытьФорму() с параметрами, владельцем и описанием оповещения.
- 3В открываемой форме при выборе значения вызовите Закрыть(ВыбранноеЗначение) или ОповеститьОВыборе().
- 4В обработчике оповещения проверьте результат на Неопределено и обработайте значение.
- 5Убедитесь, что процедура-обработчик объявлена с директивой &НаКлиенте и ключевым словом Экспорт.
Ещё один канал связи — свойство ВладелецФормы и уникальность формы. Если открыть форму с указанием владельца и ключа уникальности, платформа не даст открыть дубликат, а из открываемой формы можно обратиться к владельцу. Это удобно для подбора товаров в документ, когда форма подбора должна знать, какому документу она принадлежит.
Отличие контекста формы от контекста модуля объекта
Модуль объекта (например, модуль документа) и модуль формы — разные контексты с разным назначением. Модуль объекта выполняется всегда на сервере и работает с самим объектом: его обработчики ОбработкаПроведения, ПередЗаписью, ПриЗаписи срабатывают при любой записи объекта — и из формы, и из обмена данными, и из фонового задания. Модуль формы существует только пока открыта форма и отвечает за интерфейсную логику.
Практическое правило: бизнес-логику (проверки, расчёты проводок, контроль остатков) размещайте в модуле объекта или в общих модулях, а в модуле формы оставляйте только то, что касается отображения и интерактива. Если проверку сделать только в форме, она будет обойдена при записи документа через обмен или программно — это классическая причина «дыр» в учёте.
Как проверить, что код работает в нужном контексте
Самый надёжный способ — отладчик. Поставьте точку останова в обработчике и посмотрите, в каком процессе она сработала: конфигуратор показывает, выполняется код на клиенте или на сервере. В табло (Shift+F9) можно вычислить любое свойство контекста — например, проверить, чему равен Объект.Ссылка или существует ли элемент Элементы.Найти("Товары").
Признаки проблем с контекстом обычно очевидны. Ошибка «Переменная не определена» означает, что вы обратились к чему-то, чего нет в текущем контексте — например, к реквизиту формы из процедуры без контекста. Ошибка «Метод объекта не обнаружен» возникает при вызове клиентского метода на сервере или наоборот. Молчаливое невыполнение кода часто означает, что обработчик назначен не тому событию или не экспортирован.
Как проверить результат
Директива соответствует операциям: запросы — на сервере, интерактив — на клиенте
Компиляция падает или в отладчике виден вызов недоступного метода
Значения передаются параметрами или через реквизиты формы один раз за операцию
Серверные вызовы с контекстом выполняются в цикле
Проверки срабатывают и при записи из формы, и при программной записи
Проверка работает только при интерактивной записи из формы
Оповещение срабатывает, результат проверяется на Неопределено
После закрытия формы ничего не происходит, обработчик не вызывается
Полезно также включить в конфигураторе проверку модулей (Конфигурация → Проверка конфигурации) с флагом проверки серверных и клиентских контекстов — она выявит обращения к недоступным в данном контексте методам ещё до запуска.
Ограничения и особенности тонкого и веб-клиента
Контекст формы зависит не только от директив, но и от клиентского приложения. В тонком клиенте и веб-клиенте недоступны многие возможности толстого клиента: нет прямой работы с COM-объектами (в веб-клиенте — только через расширения), ограничена работа с файловой системой, недоступны некоторые типы данных. Поэтому код формы, написанный и проверенный в толстом клиенте, может не скомпилироваться в тонком.
Чтобы избежать сюрпризов, проверяйте конфигурацию во всех режимах, в которых реально работают пользователи. Если функциональность нужна только в толстом клиенте, оборачивайте код в конструкции #Если ТолстыйКлиентОбычноеПриложение Тогда ... #КонецЕсли — они убирают недоступный код из компиляции для других клиентов.
Отдельно стоит упомянуть безопасный режим: если форма открывается из внешней обработки или расширения, часть операций может быть заблокирована. Код, работающий в конфигураторе, в безопасном режиме откажется выполнять операции с файловой системой или COM-объектами. Тестируйте внешние формы в том же режиме, в котором они будут эксплуатироваться.
Частые вопросы о контексте формы 1С
Чем контекст формы отличается от контекста модуля?
Контекст модуля — более широкое понятие: это окружение любого модуля (общего, объекта, формы). Контекст формы — частный случай, включающий специфические для формы сущности: элементы управления, реквизиты формы, данные основного реквизита, параметры открытия. Код модуля формы выполняется ещё и в двух средах — на клиенте и на сервере, чего нет, например, у модуля объекта, который всегда серверный.
Почему на сервере не виден реквизит формы в процедуре «без контекста»?
Потому что процедуры с директивой &НаСервереБезКонтекста выполняются без передачи данных формы — это сделано ради скорости. Передайте нужное значение параметром или измените директиву на &НаСервере, если требуется полный доступ к реквизитам и элементам формы.
Как из модуля объекта обратиться к форме?
Напрямую — никак, и это осознанное ограничение платформы: объект может записываться вообще без формы. Если форме нужно отреагировать на события объекта, используйте обработчики формы ПередЗаписью, ПослеЗаписи, либо передавайте данные из формы в объект через реквизит «Объект», а не наоборот.
Что делать с ошибкой «Поле объекта не обнаружено» в модуле формы?
Проверьте три вещи: существует ли реквизит или элемент с таким именем в редакторе формы, не опечатка ли в имени (платформа чувствительна к точному написанию), и в том ли контексте выполняется код — например, обращение к Объект.Поле в форме обработки без основного реквизита-объекта даст именно эту ошибку.
Можно ли вызвать клиентскую процедуру с сервера?
Нет, прямой вызов невозможен — сервер не управляет интерфейсом пользователя. Обратная связь реализуется иначе: серверная процедура возвращает значение, а клиентская процедура, которая её вызвала, продолжает работу с результатом. Для длительных операций используются фоновые задания с оповещением клиента о завершении.
Где посмотреть полный список свойств и методов контекста формы?
В синтакс-помощнике конфигуратора: раздел «Интерфейс (управляемый)» → «Управляемая форма». Там перечислены все свойства, методы и события расширения формы для каждого типа основного реквизита. В отладчике тот же состав виден через вычисление выражения ЭтаФорма.
Что важно запомнить
Контекст формы — это окружение модуля формы: реквизиты, элементы, данные объекта и стандартные методы. Код формы делится директивами на клиентский и серверный, и у каждого контекста свои возможности и ограничения. Бизнес-логику держите в модуле объекта и общих модулях, в форме оставляйте интерфейс, а серверные вызовы с контекстом не используйте в циклах.