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