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