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