Размещение таблицы значений с помощью доп реквизита и расширения конфигурации 1С
И действительно, как сделать такую задачу не усложняя дальнейшее обновление конфигурации? И вроде есть доп. реквизиты и доп. сведения, но почему же они не могут принимать тип таблицы значений?
В итоге чаще всего используется 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;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Комментарии (5)
25 сентября 2016 в 11:26
0↑
↓
Как то мне25 сентября 2016 в 11:29
0↑
↓
Как то мне нужно было настроить обмен с базой 1с с самописной конфой, так там все реквизиты справочников были сделаны таким образом. Жесть была еще та25 сентября 2016 в 11:54
0↑
↓
Каким методом? доп реквизитами или как? Не совсем понимаю как в «самописной конфе» можно что то страшное натворить…
25 сентября 2016 в 11:49
0↑
↓
Добавляется объект с таблицей значений и реквизитом содержащий объект родитель
Ого, а как же ссылочная целостность?
Вообще это конечно прелесно, что 1С за почти 20 лет разработки своей платформы так и не осилила упростить процесс поддержки доработанных конфигураций, введя хоть какое то подобие ООП. Хотя бы в виде «пользовательских» файлов, автоматически сливамых с основной конфигурацией + перезагрузка функций. Это же элементарно сделать
Такое впечатление, что 1С специально усложняет поддержку, чтобы обеспечивать работой своих многочисленных франчайзи25 сентября 2016 в 11:52
0↑
↓
Ого, а как же ссылочная целостность?
Я имел ввиду «реквизит с ссылкой на объект родитель», изменил в статье.
Может картинками дополню для наглядности…