При переводе сильно доработанных баз на типовую поддержку или при проектировании новой функциональности разработчики сталкиваются с задачей: необходимо добавить в типовые документы новые табличные части, но при этом сохранить возможность максимально простого обновления конфигурации. Рассмотрим подробно, почему для этого нельзя использовать исключительно подписки на события, а также разберем несколько проверенных вариантов реализации задачи.
Проанализируем вопрос о том, можно ли создать табличную часть или вывести ее на экран с помощью подписок на события. Подписки на события работают исключительно в объектной модели на стороне сервера (например, при записи, проведении или проверке заполнения объектов ДокументОбъект, СправочникОбъект). Они не перехватывают клиентские события и не имеют доступа к контексту управляемой формы. Соответственно, создать элементы интерфейса или перехватить открытие формы документа через подписку на событие технически невозможно.
Тем не менее, серверную логику проведения и записи движений по нетиповым регистрам действительно рекомендуется выносить в подписки на события (например, ОбработкаПроведения), чтобы не менять типовой модуль объекта.
Разберем современный способ доработки функциональности без изменения основной конфигурации. Начиная с версии платформы 8.3.12, расширения поддерживают добавление собственных реквизитов и табличных частей в заимствованные объекты метаданных.
Порядок реализации решения:
&После, &Перед или &Вместо.Преимущества: основная конфигурация остается полностью типовой и находится на замке, что обеспечивает автоматическое обновление.
Важные риски: данные, добавленные через расширение, хранятся в отдельных таблицах базы данных. При случайном удалении расширения, некорректной смене режима совместимости или ошибках применения расширения существует риск потери данных, хранящихся в его метаданных. При использовании данного варианта требуется строгий регламент создания резервных копий.
Рассмотрим вариант, при котором метаданные создаются в основной конфигурации, но код не внедряется в типовые модули. Добавление новых объектов и реквизитов в основную конфигурацию минимально усложняет обновление, если соблюдать правила именования.
Префикс_СоставОборудования). Использование уникального префикса гарантирует, что имя вашей табличной части никогда не пересечется с новыми реквизитами из обновлений от поставщика.ОбработкаПроведения.В результате в самой конфигурации отсутствуют изменения в типовом коде, а новые метаданные при обновлении через сравнение и объединение не вызывают конфликтов.
Если требуется оставить основную конфигурацию на замке и при этом исключить хранение важных данных в расширениях, проанализируем архитектуру с использованием подчиненного регистра сведений.
Документ (тип ДокументСсылка) и измерением НомерСтроки для фиксации порядка записей.ТаблицаЗначений.Посмотрим на пример чтения и записи набора записей в регистр сведений:
НаборЗаписей = РегистрыСведений.Префикс_ДополнительныеСтроки.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаДокумент);
Для Каждого Стр Из ТаблицаДанных Цикл
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Регистратор = СсылкаНаДокумент;
НоваяЗапись.Период = СсылкаНаДокумент.Дата;
НоваяЗапись.Номенклатура = Стр.Номенклатура;
НоваяЗапись.Количество = Стр.Количество;
КонецЦикла;
НаборЗаписей.Записать();
Разберем случай, когда расширения не используются, а внесение изменений в типовые модули форм нужно свести к одной строке. В модуле формы в обработчике ПриСозданииНаСервере вызывается внешняя процедура общего модуля, которая динамически создает реквизиты и элементы формы.
Посмотрим на пример добавления реквизита типа ТаблицаЗначений и элементов интерфейса:
// Создаем реквизит формы программно
МассивДобавляемыхРеквизитов = Новый Массив;
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы("ДополнительнаяТЧ", Новый ОписаниеТипов("ТаблицаЗначений"), , "Дополнительная ТЧ"));
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы("Товар", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"), "ДополнительнаяТЧ", "Товар"));
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 3)), "ДополнительнаяТЧ", "Количество"));
ЭтаФорма.ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
// Добавляем таблицу и колонки на форму
ТаблицаФормы = Элементы.Добавить("ДополнительнаяТЧ", Тип("ТаблицаФормы"), ЭтаФорма);
ТаблицаФормы.ПутьКДанным = "ДополнительнаяТЧ";
ПолеТовар = Элементы.Добавить("ДополнительнаяТЧТовар", Тип("ПолеФормы"), ТаблицаФормы);
ПолеТовар.Вид = ВидПоляФормы.ПолеВвода;
ПолеТовар.ПутьКДанным = "ДополнительнаяТЧ.Товар";
ПолеКоличество = Элементы.Добавить("ДополнительнаяТЧКоличество", Тип("ПолеФормы"), ТаблицаФормы);
ПолеКоличество.Вид = ВидПоляФормы.ПолеВвода;
ПолеКоличество.ПутьКДанным = "ДополнительнаяТЧ.Количество";
Выбор конкретного решения зависит от требований к отказоустойчивости базы данных: для типовых конфигураций на свежих версиях платформы оптимальным является использование расширений конфигурации либо сочетание префиксных метаданных с подписками на события.