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