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