В типовых конфигурациях 1С, таких как 1С:Документооборот, часто используется встроенный конструктор видов документов. Он позволяет гибко настраивать реквизиты, права, нумерацию и поведение для каждого отдельного вида документа прямо в пользовательском режиме. Однако у этого механизма есть существенное ограничение — стандартными средствами невозможно добавить новую табличную часть (ТЧ) для конкретного вида документа. Пользователю доступны только предопределенные ТЧ, которых часто бывает недостаточно для специфических бизнес-требований (например, для ведения спецификаций договоров, графиков поставок или детальной аналитики по статьям).
В этой статье мы подробно проанализируем различные подходы к решению этой задачи: от классического добавления метаданных в конфигураторе до создания гибких динамических подсистем на базе БСП (Библиотеки стандартных подсистем).
Это наиболее прагматичный, надежный и простой в поддержке способ решения проблемы. Суть метода заключается в том, что все потенциально необходимые табличные части добавляются непосредственно к объекту метаданных (например, к документу ВнутреннийДокумент в 1С:ДО) в Конфигураторе. На форму документа выводятся все созданные ТЧ, но их видимость динамически управляется в зависимости от выбранного вида документа.
Выясним преимущества этого подхода:
Рассмотрим по шагам программную реализацию управления видимостью на форме документа. В модуле формы в процедуре ПриСозданииНаСервере или специализированной процедуре обновления формы добавим следующий код:
&НаСервере
Процедура УправлениеВидимостьюТабличныхЧастей()
// Получаем текущий вид документа
ТекущийВидДокумента = Объект.ВидДокумента;
// Проверяем соответствие вида документа и настраиваем видимость элементов формы
Если ТекущийВидДокумента = Справочники.ВидыВнутреннихДокументов.НайтиПоНаименованию("Договор Поставки") Тогда
Элементы.ГруппаСпецификацияДоговора.Видимость = Истина;
Элементы.ГруппаГрафикПлатежей.Видимость = Ложь;
ИначеЕсли ТекущийВидДокумента = Справочники.ВидыВнутреннихДокументов.НайтиПоНаименованию("Заявка На Расход") Тогда
Элементы.ГруппаСпецификацияДоговора.Видимость = Ложь;
Элементы.ГруппаГрафикПлатежей.Видимость = Истина;
Иначе
// Скрываем все дополнительные табличные части для остальных видов
Элементы.ГруппаСпецификацияДоговора.Видимость = Ложь;
Элементы.ГруппаГрафикПлатежей.Видимость = Ложь;
КонецЕсли;
КонецПроцедуры
При таком подходе база данных остается в третьей нормальной форме, а выгрузка и загрузка данных через XML или EnterpriseData не потребует написания сложных трансляторов.
Если вы стремитесь сохранить конфигурацию на полной поддержке поставщика, отличным решением станет использование механизма расширений конфигурации. Начиная с версии платформы 8.3.11, расширения позволяют добавлять собственные структуры хранения данных в базу данных.
Проанализируем этот процесс:
ВнутреннийДокумент) в расширение.Важное ограничение метода: Помните, что реквизиты табличных частей, добавленные через расширения, имеют некоторые платформенные ограничения (например, на использование определенных типов данных или неограниченной длины строк в некоторых СУБД). Также при масштабном обновлении типовой конфигурации необходимо внимательно следить за тем, чтобы структура заимствованных объектов не изменилась критически.
Для крупных проектов, где конфигурацию категорически нельзя изменять (или снимать с поддержки), а количество видов документов и разнообразие их табличных частей постоянно растет, можно спроектировать универсальную независимую подсистему хранения двумерных данных.
С архитектурной точки зрения мы построим решение по схеме Entity-Attribute-Value (EAV):
ДополнительныеТабличныеЧасти). Измерениями регистра будут: ОбъектСсылка (документ-владелец), ИмяТаблицы (строка), ИндексСтроки (число), Колонка (ПланВидовХарактеристикСсылка). Ресурсом будет выступать универсальный тип данных Значение (Характеристика.Колонка).Посмотрим на пример кода, который выполняет программное конструирование колонок таблицы на форме на основании настроек:
&НаСервере
Процедура СоздатьДинамическуюТабличнуюЧастьНаФорме(ИмяТаблицы)
// 1. Описываем и добавляем реквизит формы типа "ТаблицаЗначений"
МассивРеквизитов = Новый Массив;
МассивРеквизитов.Добавить(Новый РеквизитФормы(ИмяТаблицы, Новый ОписаниеТипов("ТаблицаЗначений")));
// Получаем список колонок из настроек (например, из нашего справочника или ПВХ)
СписокКолонок = ПолучитьНастройкиКолонокДляТаблицы(ИмяТаблицы);
Для Каждого ТекущаяКолонка Из СписокКолонок Цикл
МассивРеквизитов.Добавить(Новый РеквизитФормы(ТекущаяКолонка.Имя, ТекущаяКолонка.ТипДанных, ИмяТаблицы));
КонецЦикла;
ИзменитьРеквизиты(МассивРеквизитов);
// 2. Создаем элементы управления на форме (визуализацию таблицы)
ТаблицаФормы = Элементы.Добавить(ИмяТаблицы, Тип("ТаблицаФормы"));
ТаблицаФормы.ПутьКДанным = ИмяТаблицы;
Для Каждого ТекущаяКолонка Из СписокКолонок Цикл
НоваяКолонка = Элементы.Добавить(ИмяТаблицы + "_" + ТекущаяКолонка.Имя, Тип("ПолеФормы"), ТаблицаФормы);
НоваяКолонка.ПутьКДанным = ИмяТаблицы + "." + ТекущаяКолонка.Имя;
НоваяКолонка.Вид = ВидПоляФормы.ПолеВвода;
КонецЦикла;
КонецПроцедуры
Этот метод чрезвычайно гибок: он позволяет пользователям в режиме «1С:Предприятие» самостоятельно конструировать новые табличные части с любым набором колонок без участия программиста. Однако его разработка требует высокой квалификации и написания значительного объема программного кода для синхронизации данных.
Если в вашей конфигурации активно используется БСП и функционал "Свойства" (дополнительные реквизиты и сведения), можно применить изящный гибридный метод. Вместо физического изменения структуры БД мы можем эмулировать таблицу.
Каждая ячейка виртуальной таблицы регистрируется как отдельный дополнительный реквизит со специальным кодированием имени (например, ИмяКолонки_НомерСтроки). На форме документа специальный программный модуль перехватывает массив таких реквизитов и преобразует их в удобную плоскую таблицу. При сохранении документа данные снова раскладываются по отдельным доп. реквизитам. Данный подход гарантирует абсолютную безопасность при обновлениях системы, так как использует стандартный, предусмотренный разработчиками БСП функционал хранения данных.