Меня очень часто спрашивают, как добавить таблицу к документу или справочнику?
И действительно, как сделать такую задачу не усложняя дальнейшее обновление конфигурации? И вроде есть доп. реквизиты и доп. сведения, но почему же они не могут принимать тип таблицы значений?
В итоге чаще всего используется 2 варианта:
Есть, конечно, еще другие варианты к примеру с хранилищем, но статья не об этом…
Статья, о том, как все-таки хранить таблицу значений в доп. реквизитах, ну или в доп. сведениях.
Уже более полугода держу в голове этот способ, но ни разу его не применял. Вот, наконец, добрались руки. Я не утверждаю, что никто не придумывал данный способ, но на подобное решение я не натыкался. Заранее скажу, вариант не идеален, и сгодится только под определенные задачи.
Самый главный минус это то, что будет использоваться строка неограниченной длины а, следовательно, с поиском в ней будут определенные сложности. Самый главный плюс, объекты в конфигурации не правятся.
Пример продемонстрирую на конфигурации Документооборот 2.1.6.8. Буду использовать дополнительный реквизит, но можно использовать дополнительные сведения. Весь код будет написан в Расширении конфигурации.
Задача:
Сразу говорю задачка больше шуточная для демонстрации метода. Например, нам понадобилось добавить табличную часть «Адекватность контактных лиц», она должна присутствовать в справочнике Контрагенты и содержать колонки: Контактное лицо, Совет (некая рекомендация по общению с контактным лицом), Тип контакта.
1 Добавляем доп. реквизит и называем его к примеру «ТЗ_АдекватностьКонтактныхЛиц».
Я этот реквизит делаю общим для всех видов контрагентов. Тип его будет строка неограниченной длины.

2 Создаем Расширение конфигурации и Дорабатываем форму Контрагентов.
Добавляем реквизиты формы:
— «ДопТЗ» тип ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения
— ТЗ_АдекватностьКонтактныхЛиц тип ТаблицаЗначений:
КонтактноеЛицо тип СправочникСсылка.КонтактныеЛица
ТипКонтакта тип Строка
Совет тип Строка

Добавляем на форму страницу «ГруппаАдекватностьКонтактныхЛиц» и снимаем видимость.
В данную группу выводим «ТЗ_АдекватностьКонтактныхЛиц»

3 Пишем код.
ПриСозданииНаСервере. Необходимо считать сам доп реквизит напомню мы его обозвали «ТЗ_АдекватностьКонтактныхЛиц», далее прочитать его значение и построить по его значению таблицу значений.
Значение доп реквизита я предлагаю хранить в формате JSON, у кого более старая платформа можно использовать XML.
ПриОткрытии. Программно прячем доп. реквизит. Он хранит JSON, поэтому пользователю особо неинтересен.
ПередЗаписьюНаСервере. Если ТЗ изменилась сохраняем ее в виде строки JSON в доп. реквизит.

И действительно, как сделать такую задачу не усложняя дальнейшее обновление конфигурации? И вроде есть доп. реквизиты и доп. сведения, но почему же они не могут принимать тип таблицы значений?
В итоге чаще всего используется 2 варианта:
1. Простой способ. Прямо в объекте добавляется таблица, а затем либо программно либо жестко(вручную) выводится на форму.
Минусы. Обновление конфигурации будет требовать соблюдения изменений и повышенной внимательности, чтобы не потерять эти изменения.
Плюсы. Самый простой вариант для разработки, к таблице значений можно обращаться без танцев с бубном, например через запросы.
2. Нормальный вариант, но тоже с доработкой конфигурации.
Добавляется объект с таблицей значений и реквизитом с ссылкой на объект родитель, данная таблица значений выводится, к примеру, через расширение конфигурации на форму основного объекта.
![]()
Плюсы. Простое обновление, к таблице значений можно обращаться, например через запросы.
Минусы. Требуется больше предусмотреть различные ограничения на созданный объект а, следовательно, требует определенных знаний. Возможно, потребуется добавление роли\ей и настройки профилей пользователей.
Есть, конечно, еще другие варианты к примеру с хранилищем, но статья не об этом…
Статья, о том, как все-таки хранить таблицу значений в доп. реквизитах, ну или в доп. сведениях.
Уже более полугода держу в голове этот способ, но ни разу его не применял. Вот, наконец, добрались руки. Я не утверждаю, что никто не придумывал данный способ, но на подобное решение я не натыкался. Заранее скажу, вариант не идеален, и сгодится только под определенные задачи.
Самый главный минус это то, что будет использоваться строка неограниченной длины а, следовательно, с поиском в ней будут определенные сложности. Самый главный плюс, объекты в конфигурации не правятся.
Пример продемонстрирую на конфигурации Документооборот 2.1.6.8. Буду использовать дополнительный реквизит, но можно использовать дополнительные сведения. Весь код будет написан в Расширении конфигурации.
Задача:
Сразу говорю задачка больше шуточная для демонстрации метода. Например, нам понадобилось добавить табличную часть «Адекватность контактных лиц», она должна присутствовать в справочнике Контрагенты и содержать колонки: Контактное лицо, Совет (некая рекомендация по общению с контактным лицом), Тип контакта.
1 Добавляем доп. реквизит и называем его к примеру «ТЗ_АдекватностьКонтактныхЛиц».
Я этот реквизит делаю общим для всех видов контрагентов. Тип его будет строка неограниченной длины.
2 Создаем Расширение конфигурации и Дорабатываем форму Контрагентов.
Добавляем реквизиты формы:
— «ДопТЗ» тип ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения
— ТЗ_АдекватностьКонтактныхЛиц тип ТаблицаЗначений:
КонтактноеЛицо тип СправочникСсылка.КонтактныеЛица
ТипКонтакта тип Строка
Совет тип Строка

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

