К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как заполнить форму на сервере в 1С

Как заполнить форму на сервере в 1С: причины, методы, типовой код, ошибки и проверка результата. Практическое руководство для разработчиков управляемых форм.

В управляемых формах 1С данные и интерфейс разделены: форма на клиенте отображает реквизиты, а основная бизнес-логика выполняется на сервере. Поэтому типовая задача — заполнить реквизиты формы, табличную часть или дерево значений именно в серверной процедуре, а затем вернуть результат клиенту. Такой подход снижает сетевые вызовы, ускоряет работу и позволяет использовать серверные возможности: запросы, менеджеры объектов, привилегированный режим.

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

Ключевой момент, который часто упускают начинающие разработчики: на сервере нельзя обращаться к элементам формы напрямую и нельзя выполнять интерактивные действия (вопросы пользователю, предупреждения). Серверная процедура работает только с данными формы — реквизитами, таблицами значений, объектом.

Как устроен вызов сервера из управляемой формы

Управляемая форма существует в двух контекстах: клиентском (тонкий клиент, веб-клиент) и серверном. Директивы компиляции определяют, где выполняется код. Процедура с директивой &НаСервере выполняется на сервере и имеет доступ к данным формы, но не к элементам интерфейса и не к модальным вызовам. Процедура &НаКлиенте работает с интерфейсом, но не имеет прямого доступа к базе данных.

При вызове серверной процедуры из клиентской платформа сериализует данные формы, передаёт их на сервер, выполняет код и возвращает изменённое состояние обратно. Это один серверный вызов — важно не делать таких вызовов в цикле, иначе производительность резко упадёт. Правильный подход: собрать все параметры на клиенте, сделать один вызов, обработать всё на сервере.

Существует также директива &НаСервереБезКонтекста. Такая процедура не имеет доступа к данным формы и работает быстрее, но для заполнения формы она подходит только через передачу параметров и возврат значений — например, вернуть готовую таблицу значений, которую клиент потом загрузит в реквизит формы.

Заполнение реквизитов и табличных частей объекта

Если форма построена на основном реквизите типа «ДокументОбъект» или «СправочникОбъект», на сервере доступен приём через РеквизитФормыВЗначение("Объект"). Эта функция преобразует данные формы в прикладной объект, с которым удобно работать: обращаться к табличным частям, использовать методы объекта, вызывать запросы. После изменений объект возвращается в форму методом ЗначениеВРеквизитФормы.

bsl
&НаКлиенте
Процедура ЗаполнитьПоОстаткам(Команда)
	ЗаполнитьПоОстаткамНаСервере();
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьПоОстаткамНаСервере()
	ДокументОбъект = РеквизитФормыВЗначение("Объект");
	ДокументОбъект.Товары.Очистить();
	
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ Номенклатура, КоличествоОстаток ИЗ РегистрНакопления.ОстаткиТоваров.Остатки(, Склад = &Склад)";
	Запрос.УстановитьПараметр("Склад", ДокументОбъект.Склад);
	
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		Строка = ДокументОбъект.Товары.Добавить();
		Строка.Номенклатура = Выборка.Номенклатура;
		Строка.Количество = Выборка.КоличествоОстаток;
	КонецЦикла;
	
	ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");
КонецПроцедуры

Обратите внимание: если реквизит формы имеет тип «ДанныеФормыСтруктура» (а не объект), преобразование не требуется — можно обращаться к реквизитам напрямую через Объект.Товары и методы коллекции данных формы. Но для сложных алгоритмов работа через объект обычно удобнее и быстрее, поскольку не тратятся ресурсы на поддержку механизмов формы при каждом обращении.

После вызова ЗначениеВРеквизитФормы форма автоматически обновит отображение. Дополнительно «дёргать» элементы формы не нужно — платформа сама синхронизирует интерфейс при возврате управления на клиент.

Заполнение таблицы значений и динамического списка на форме

Когда форма содержит дополнительный реквизит типа «ТаблицаЗначений», серверная процедура заполняет её напрямую: очистка, добавление строк, присвоение значений колонкам. На сервере таблица данных формы ведёт себя почти как обычная таблица значений, доступны методы Добавить(), Очистить(), НайтиСтроки().

Если таблица большая (тысячи строк), эффективнее сформировать обычную таблицу значений запросом, а затем загрузить её в реквизит формы через ЗначениеВРеквизитФормы(ТаблицаРезультат, "ИмяРеквизита"). Это сокращает число обращений к данным формы и заметно ускоряет заполнение.

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

Передача параметров между клиентом и сервером

Серверная процедура может принимать параметры. Клиент передаёт, например, выбранный склад, период, ссылку на документ-основание — а сервер использует их в запросе. Передавать следует только простые типы и ссылки: сериализация сложных структур с большими данными замедляет вызов.

Обратная передача работает через возвращаемое значение. Процедура &НаСервереБезКонтекста может вернуть структуру с результатами, которую клиент обработает: покажет сообщение, установит признак модифицированности, обновит связанные поля. Для процедуры &НаСервере возвращать данные обычно не нужно — изменения данных формы доезжают до клиента автоматически.

Типичная ошибка — передавать на сервер данные формы целиком «на всякий случай». Это лишний трафик. Передавайте только то, что реально нужно алгоритму: ссылки, даты, флаги.

Порядок действий
  1. 1
    Создайте клиентскую процедуру-обработчик команды с директивой &НаКлиенте
  2. 2
    В ней вызовите серверную процедуру с директивой &НаСервере, передав нужные параметры
  3. 3
    На сервере получите объект через РеквизитФормыВЗначение или работайте с реквизитами формы напрямую
  4. 4
    Выполните запрос и заполните табличную часть или реквизиты
  5. 5
    Верните объект в форму через ЗначениеВРеквизитФормы
  6. 6
    Проверьте на клиенте, что данные отобразились и форма помечена как изменённая

Типичные ошибки и ограничения серверного контекста

Самая частая ошибка — попытка вызвать на сервере интерактивные методы: Вопрос(), Предупреждение(), ОткрытьФорму(). На сервере они недоступны, код завершится ошибкой. Все интерактивные действия выполняются на клиенте до или после серверного вызова.

Вторая группа ошибок связана с контекстом: обращение к элементам формы (Элементы.Товары) в процедуре &НаСервереБезКонтекста или попытка использовать несуществующие в серверном контексте свойства. Проверяйте директиву компиляции и доступность объектов в синтакс-помощнике с учётом контекста.

Также помните о правах: серверная процедура выполняется под правами текущего пользователя. Если заполнение требует данных, к которым у пользователя нет доступа, используйте УстановитьПривилегированныйРежим(Истина) — но осознанно, поскольку это обход ограничений безопасности.

Типичные ошибки
01
Вызов серверной процедуры в цикле по строкам — каждый вызов это обращение к серверу, форма «зависает»; решение: один вызов, обработка всей таблицы на сервере
02
Попытка показать вопрос или предупреждение на сервере — ошибка выполнения; интерактив только на клиенте
03
Забытый вызов ЗначениеВРеквизитФормы после изменения объекта — данные изменены, но форма показывает старые значения
04
Передача на сервер больших структур данных вместо ссылок и простых параметров — лишний трафик и замедление

Как проверить результат и отладить серверное заполнение

После реализации проверьте три вещи: данные появились в форме после вызова, форма получила признак модифицированности (звёздочка в заголовке), при записи объекта данные сохраняются корректно. Если данные заполнились, но не сохраняются — скорее всего, изменения внесены не в тот реквизит или потеряны при обратном преобразовании.

Для отладки серверного кода включите в конфигураторе отладку на сервере (в клиент-серверном варианте — отладку на сервере 1С:Предприятия). Точки останова в серверных процедурах сработают только при корректно настроенной отладке сервера. Альтернатива для быстрой диагностики — запись в журнал регистрации через ЗаписьЖурналаРегистрации.

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

Контрольные точки

Как проверить результат

Отображение данных
Норма

После нажатия команды табличная часть заполнена строками

Тревожный признак

Таблица пустая — проверьте ЗначениеВРеквизитФормы и отбор запроса

Модифицированность формы
Норма

В заголовке формы появился признак изменения

Тревожный признак

Форма считает себя неизменённой — данные записаны мимо основного реквизита

Сохранение
Норма

После записи объекта данные остаются на месте

Тревожный признак

После записи строки пропадают — ошибка в переносе данных формы

Ответы на частые вопросы

Можно ли заполнить форму на сервере без вызова с клиента?

Да, если заполнение происходит при создании формы: в обработчике ПриСозданииНаСервере данные заполняются до первого отображения формы. Для реакции на действия пользователя без клиентского вызова не обойтись — именно клиент инициирует обращение к серверу.

Чем отличается &НаСервере от &НаСервереБезКонтекста при заполнении формы?

Процедура &НаСервере имеет доступ к данным формы и может менять реквизиты напрямую. &НаСервереБезКонтекста контекста формы не имеет — она может только вернуть результат (например, таблицу значений), который клиент или серверная процедура с контекстом загрузит в реквизиты формы.

Почему после заполнения на сервере форма показывает старые данные?

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

Как заполнить форму на сервере, если нужно спросить пользователя о параметрах?

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

Замедлит ли работу большое количество строк при серверном заполнении?

Само заполнение на сервере быстрое даже для тысяч строк. Узкое место — передача данных формы между клиентом и сервером и отрисовка большой таблицы в интерфейсе. Для очень больших объёмов используйте динамический список или порционную загрузку вместо таблицы значений.

Нужно ли записывать объект после заполнения на сервере?

Нет, заполнение меняет только данные формы в памяти. Объект записывается в базу только при явном вызове записи — пользователем или программно. Это безопасно: пользователь может проверить результат и отказаться от сохранения.

Итог

Что важно запомнить

Заполнение формы на сервере строится по схеме: клиент вызывает процедуру &НаСервере, та изменяет данные формы (напрямую или через РеквизитФормыВЗначение/ЗначениеВРеквизитФормы), результат отображается автоматически. Один вызов вместо цикла, никакого интерактива на сервере, проверка отображения и сохранения — основа надёжного решения.