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