Files
SSL/SSL/src/CommonModules/УправлениеСвойствами/Module.bsl
T
2022-11-09 12:16:00 +03:00

2147 lines
153 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2022, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////
#Область ПрограммныйИнтерфейс
////////////////////////////////////////////////////////////////////////////////
// Процедуры и функции для стандартной обработки дополнительных реквизитов.
// Создает основные реквизиты и поля формы, необходимые для работы.
// Заполняет дополнительные реквизиты, если используются.
// Вызывается из обработчика ПриСозданииНаСервере формы объекта со свойствами.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - в которой будут отображаться дополнительные реквизиты со свойствами:
// * Объект - ДанныеФормыСтруктура - по типу объекта, со свойствами:
// ** Ссылка - ЛюбаяСсылка - ссылка на объект, к которому подключаются свойства.
//
// ДополнительныеПараметры - Неопределено - все дополнительные параметры имеют значения по умолчанию.
// Ранее реквизит назывался "Объект" и имел смысл,
// как одноименное свойство структуры, указанной ниже.
// - Структура - с необязательными свойствами:
//
// * Объект - ДанныеФормыСтруктура - по типу объекта, содержит свойства:
// ** Ссылка - ЛюбаяСсылка - ссылка на объект, к которому подключаются свойства.
//
// * ИмяЭлементаДляРазмещения - Строка - имя группы формы, в которой будут размещены свойства.
//
// * ПроизвольныйОбъект - Булево - если Истина, тогда в форме создается таблица описания дополнительных
// реквизитов, параметр Объект игнорируется, дополнительные реквизиты не создаются и не заполняются.
//
// Это востребовано при последовательном использовании одной формы для просмотра или редактирования
// дополнительных реквизитов разных объектов (в том числе разных типов).
//
// После выполнения ПриСозданииНаСервере следует вызывать ЗаполнитьДополнительныеРеквизитыВФорме()
// для добавления и заполнения дополнительных реквизитов.
// Чтобы сохранить изменения, следует вызвать ПеренестиЗначенияИзРеквизитовФормыВОбъект(),
// а для обновления состава реквизитов вызвать ОбновитьЭлементыДополнительныхРеквизитов().
//
// * ИмяЭлементаКоманднойПанели - Строка - имя группы формы, в которую будет добавлена кнопка.
// РедактироватьСоставДополнительныхРеквизитов. Если имя элемента не указано,
// используется стандартная группа "Форма.КоманднаяПанель".
//
// * СкрытьУдаленные - Булево - установить/отключить режим скрытия удаленных.
// Если параметр не указан, а параметр Объект указан и свойство Ссылка не заполнено,
// тогда начальное значение устанавливается Истина, иначе Ложь.
// При вызове процедуры ПередЗаписьюНаСервере в режиме скрытия удаленных удаленные значения
// очищаются (не переносятся обратно в объект), а режим СкрытьУдаленные устанавливается Ложь.
//
Процедура ПриСозданииНаСервере(Форма, ДополнительныеПараметры = Неопределено) Экспорт
Если Не ИспользуютсяСвойства(Форма, ДополнительныеПараметры) Тогда
Возврат;
КонецЕсли;
Контекст = Новый Структура;
Контекст.Вставить("Объект", Неопределено);
Контекст.Вставить("ИмяЭлементаДляРазмещения", "");
Контекст.Вставить("ОтложеннаяИнициализация", Ложь);
Контекст.Вставить("ПроизвольныйОбъект", Ложь);
Контекст.Вставить("ИмяЭлементаКоманднойПанели", "");
Контекст.Вставить("СкрытьУдаленные", Неопределено);
Если ТипЗнч(ДополнительныеПараметры) = Тип("Структура") Тогда
ЗаполнитьЗначенияСвойств(Контекст, ДополнительныеПараметры);
КонецЕсли;
Если Контекст.ПроизвольныйОбъект Тогда
СоздатьОписаниеДополнительныхРеквизитов = Истина;
Иначе
Если Контекст.Объект = Неопределено Тогда
ОписаниеОбъекта = Форма.Объект;
Иначе
ОписаниеОбъекта = Контекст.Объект;
КонецЕсли;
СоздатьОписаниеДополнительныхРеквизитов = ИспользоватьДопРеквизиты(ОписаниеОбъекта.Ссылка);
Если Не ЗначениеЗаполнено(ОписаниеОбъекта.Ссылка) И Контекст.СкрытьУдаленные = Неопределено Тогда
Контекст.СкрытьУдаленные = Истина;
КонецЕсли;
КонецЕсли;
СоздатьОсновныеОбъектыФормы(Форма, Контекст, СоздатьОписаниеДополнительныхРеквизитов);
Если Контекст.ОтложеннаяИнициализация Тогда
Если НЕ Форма.Свойства_ИспользоватьСвойства
ИЛИ НЕ Форма.Свойства_ИспользоватьДопРеквизиты Тогда
Возврат;
КонецЕсли;
КлючНазначения = Неопределено;
НаборыСвойствОбъекта = УправлениеСвойствамиСлужебный.ПолучитьНаборыСвойствОбъекта(
ОписаниеОбъекта, КлючНазначения);
УправлениеСвойствамиСлужебный.ЗаполнитьНаборыСДополнительнымиРеквизитами(
НаборыСвойствОбъекта,
Форма.Свойства_НаборыДополнительныхРеквизитовОбъекта);
ОтображатьЗакладку = УправлениеСвойствамиСлужебный.ОтображатьЗакладкуДополнительно(
ОписаниеОбъекта.Ссылка, Форма.Свойства_НаборыДополнительныхРеквизитовОбъекта);
Если Форма.ПараметрыСвойств.Свойство("ДобавленаПустаяДекорация") Тогда
Для Каждого ИмяДекорации Из Форма.ПараметрыСвойств.КоллекцияДекораций Цикл
Форма.Элементы[ИмяДекорации].Видимость = ОтображатьЗакладку;
КонецЦикла;
КонецЕсли;
ОбновитьКлючНазначенияФормы(Форма, КлючНазначения);
КонецЕсли;
Если Не Контекст.ПроизвольныйОбъект
И Не Контекст.ОтложеннаяИнициализация Тогда
ЗаполнитьДополнительныеРеквизитыВФорме(Форма, ОписаниеОбъекта, , Контекст.СкрытьУдаленные);
КонецЕсли;
КонецПроцедуры
// Заполняет объект из реквизитов, созданных в форме.
// Вызывается из обработчика ПередЗаписьюНаСервере формы объекта со свойствами.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
// ТекущийОбъект - СправочникОбъектИмяСправочника
// - ДокументОбъектИмяДокумента
// - ПланВидовХарактеристикОбъектИмяПланаВидовХарактеристик
// - БизнесПроцессОбъектИмяБизнесПроцесса
// - ЗадачаОбъектИмяЗадачи
// - ПланВидовРасчетаОбъектИмяПланаВидовРасчета
// - ПланСчетовОбъектИмяПланаСчетов
//
Процедура ПриЧтенииНаСервере(Форма, ТекущийОбъект) Экспорт
Структура = Новый Структура("Свойства_ИспользоватьСвойства");
ЗаполнитьЗначенияСвойств(Структура, Форма);
Если ТипЗнч(Структура.Свойства_ИспользоватьСвойства) = Тип("Булево")
И Структура.Свойства_ИспользоватьСвойства Тогда
Если Форма.ПараметрыСвойств.Свойство("ВыполненаОтложеннаяИнициализация")
И Не Форма.ПараметрыСвойств.ВыполненаОтложеннаяИнициализация Тогда
Возврат;
КонецЕсли;
ЗаполнитьДополнительныеРеквизитыВФорме(Форма, ТекущийОбъект);
КонецЕсли;
КонецПроцедуры
// Заполняет объект из реквизитов, созданных в форме.
// Вызывается из обработчика ПередЗаписьюНаСервере формы объекта со свойствами.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
// ТекущийОбъект - СправочникОбъектИмяСправочника
// - ДокументОбъектИмяДокумента
// - ПланВидовХарактеристикОбъектИмяПланаВидовХарактеристик
// - БизнесПроцессОбъектИмяБизнесПроцесса
// - ЗадачаОбъектИмяЗадачи
// - ПланВидовРасчетаОбъектИмяПланаВидовРасчета
// - ПланСчетовОбъектИмяПланаСчетов
//
Процедура ПередЗаписьюНаСервере(Форма, ТекущийОбъект) Экспорт
УправлениеСвойствамиСлужебный.ПеренестиЗначенияИзРеквизитовФормыВОбъект(Форма, ТекущийОбъект, Истина);
КонецПроцедуры
// Проверяет заполненность реквизитов, обязательных для заполнения.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере со свойствами:
// * Свойства_ОписаниеДополнительныхРеквизитов - ТаблицаЗначений:
// ** ИмяРеквизитаЗначение - Строка
// ** Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения
// ** ВладелецДополнительныхЗначений - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения
// ** ТипЗначения - ОписаниеТипов
// ** МногострочноеПолеВвода - Число
// ** Удалено - Булево
// ** ЗаполнятьОбязательно - Булево
// ** Доступен - Булево
// ** Виден - Булево
// ** Наименование - Строка
// ** ЭлементФормыДобавлен - Булево
// ** ВыводитьВВидеГиперссылки - Булево
// ** СтрокаСсылочногоТипа - Булево
// Отказ - Булево - параметр обработчика ОбработкаПроверкиЗаполненияНаСервере.
// ПроверяемыеРеквизиты - Массив - параметр обработчика ОбработкаПроверкиЗаполненияНаСервере.
// Объект - СправочникОбъектИмяСправочника
// - ДокументОбъектИмяДокумента
// - ПланВидовХарактеристикОбъектИмяПланаВидовХарактеристик
// - БизнесПроцессОбъектИмяБизнесПроцесса
// - ЗадачаОбъектИмяЗадачи
// - ПланВидовРасчетаОбъектИмяПланаВидовРасчета
// - ПланСчетовОбъектИмяПланаСчетов
// - Неопределено - если свойство не указано или Неопределено,
// объект берется из реквизита формы "Объект".
//
Процедура ОбработкаПроверкиЗаполнения(Форма, Отказ, ПроверяемыеРеквизиты, Объект = Неопределено) Экспорт
ПараметрыСеанса.ИнтерактивнаяПроверкаЗаполненияСвойств = Истина;
Если НЕ Форма.Свойства_ИспользоватьСвойства
ИЛИ НЕ Форма.Свойства_ИспользоватьДопРеквизиты Тогда
Возврат;
КонецЕсли;
Приемник = Новый Структура;
Приемник.Вставить("ПараметрыСвойств", Неопределено);
ЗаполнитьЗначенияСвойств(Приемник, Форма);
Если ТипЗнч(Приемник.ПараметрыСвойств) = Тип("Структура")
И Приемник.ПараметрыСвойств.Свойство("ВыполненаОтложеннаяИнициализация")
И Не Приемник.ПараметрыСвойств.ВыполненаОтложеннаяИнициализация Тогда
ЗаполнитьДополнительныеРеквизитыВФорме(Форма, Объект);
КонецЕсли;
Для каждого Строка Из Форма.Свойства_ОписаниеДополнительныхРеквизитов Цикл
Если Строка.ЗаполнятьОбязательно И НЕ Строка.Удалено Тогда
Если Не РеквизитДоступенПоФункциональнымОпциям(Строка) Тогда
Продолжить;
КонецЕсли;
Результат = Истина;
Если Объект = Неопределено Тогда
ОписаниеОбъекта = Форма.Объект;
Иначе
ОписаниеОбъекта = Объект;
КонецЕсли;
Для Каждого ЗависимыйРеквизит Из Форма.Свойства_ОписаниеЗависимыхДополнительныхРеквизитов Цикл
Если ЗависимыйРеквизит.ИмяРеквизитаЗначение = Строка.ИмяРеквизитаЗначение
И ЗависимыйРеквизит.УсловиеОбязательностиЗаполнения <> Неопределено Тогда
Параметры = Новый Структура;
Параметры.Вставить("ЗначенияПараметров", ЗависимыйРеквизит.УсловиеОбязательностиЗаполнения.ЗначенияПараметров);
Параметры.Вставить("Форма", Форма);
Параметры.Вставить("ОписаниеОбъекта", ОписаниеОбъекта);
Результат = ОбщегоНазначения.ВычислитьВБезопасномРежиме(ЗависимыйРеквизит.УсловиеОбязательностиЗаполнения.КодУсловия, Параметры);
Прервать;
КонецЕсли;
КонецЦикла;
Если Не Результат Тогда
Продолжить;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(Форма[Строка.ИмяРеквизитаЗначение]) Тогда
ОбщегоНазначения.СообщитьПользователю(
СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Поле ""%1"" не заполнено.'"), Строка.Наименование),
,
Строка.ИмяРеквизитаЗначение,
,
Отказ);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Обновляет наборы дополнительных реквизитов и сведений для вида объектов со свойствами.
// Используется при записи элементов справочников, которые являются видами объектов со свойствами.
// Например, если есть справочник Номенклатура, к которому применяется подсистема Свойства, для него создан
// справочник ВидыНоменклатуры, то при записи элемента ВидНоменклатуры необходимо вызывать эту процедуру.
//
// Параметры:
// ВидОбъекта - СправочникОбъектИмяСправочника - например вид номенклатуры перед записью.
// ИмяОбъектаСоСвойствами - Строка - например "Номенклатура".
// ИмяРеквизитаНабораСвойств - Строка - используется, когда наборов свойств несколько или
// используется имя реквизита основного набора, отличное от "НаборСвойств".
//
Процедура ПередЗаписьюВидаОбъекта(ВидОбъекта,
ИмяОбъектаСоСвойствами,
ИмяРеквизитаНабораСвойств = "НаборСвойств") Экспорт
УстановитьПривилегированныйРежим(Истина);
НаборСвойств = ВидОбъекта[ИмяРеквизитаНабораСвойств];
РодительНабора = НаборСвойствПоИмени(ИмяОбъектаСоСвойствами);
Если РодительНабора = Неопределено Тогда
РодительНабора = Справочники.НаборыДополнительныхРеквизитовИСведений[ИмяОбъектаСоСвойствами];
КонецЕсли;
Если ЗначениеЗаполнено(НаборСвойств) Тогда
СтарыеСвойстваНабора = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(
НаборСвойств, "Наименование, Родитель, ПометкаУдаления");
Если СтарыеСвойстваНабора.Наименование = ВидОбъекта.Наименование
И СтарыеСвойстваНабора.ПометкаУдаления = ВидОбъекта.ПометкаУдаления
И СтарыеСвойстваНабора.Родитель = РодительНабора Тогда
Возврат;
КонецЕсли;
Если СтарыеСвойстваНабора.Родитель = РодительНабора Тогда
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Справочник.НаборыДополнительныхРеквизитовИСведений");
ЭлементБлокировки.УстановитьЗначение("Ссылка", НаборСвойств);
Блокировка.Заблокировать();
ЗаблокироватьДанныеДляРедактирования(НаборСвойств);
НаборСвойствОбъект = НаборСвойств.ПолучитьОбъект();
Иначе
НаборСвойствОбъект = НаборСвойств.Скопировать();
КонецЕсли;
Иначе
НаборСвойствОбъект = Справочники.НаборыДополнительныхРеквизитовИСведений.СоздатьЭлемент();
НаборСвойствОбъект.Используется = Истина;
КонецЕсли;
НаборСвойствОбъект.Наименование = ВидОбъекта.Наименование;
НаборСвойствОбъект.ПометкаУдаления = ВидОбъекта.ПометкаУдаления;
НаборСвойствОбъект.Родитель = РодительНабора;
НаборСвойствОбъект.Записать();
ВидОбъекта[ИмяРеквизитаНабораСвойств] = НаборСвойствОбъект.Ссылка;
КонецПроцедуры
// Обновляет отображаемые данные на форме объекта со свойствами.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
//
// Объект - Неопределено - взять объект из реквизита формы "Объект".
// - СправочникОбъектИмяСправочника
// - ДокументОбъектИмяДокумента
// - ПланВидовХарактеристикОбъектИмяПланаВидовХарактеристик
// - БизнесПроцессОбъектИмяБизнесПроцесса
// - ЗадачаОбъектИмяЗадачи
// - ПланВидовРасчетаОбъектИмяПланаВидовРасчета
// - ПланСчетовОбъектИмяПланаСчетов
// - ДанныеФормыСтруктура
//
// СкрытьУдаленные - Неопределено - не менять текущий режим скрытия удаленных, установленный ранее.
// - Булево - установить/отключить режим скрытия удаленных.
// При вызове процедуры ПередЗаписьюНаСервере в режиме скрытия удаленных удаленные значения
// очищаются (не переносятся обратно в объект), а режим СкрытьУдаленные устанавливается Ложь.
//
Процедура ОбновитьЭлементыДополнительныхРеквизитов(Форма, Объект = Неопределено, СкрытьУдаленные = Неопределено) Экспорт
УправлениеСвойствамиСлужебный.ПеренестиЗначенияИзРеквизитовФормыВОбъект(Форма, Объект);
ЗаполнитьДополнительныеРеквизитыВФорме(Форма, Объект, , СкрытьУдаленные);
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// Процедуры и функции для нестандартной обработки дополнительных свойств.
// Возвращает ссылку на предопределенный набор свойств по имени набора.
// Предназначена для наборов, указанных в процедуре
// УправлениеСвойствамиПереопределяемый.ПриПолученииПредопределенныхНаборовСвойств.
//
// Параметры:
// ИмяНабора - Строка - имя получаемого набора свойств.
//
// Возвращаемое значение:
// СправочникСсылка.НаборыДополнительныхРеквизитовИСведений - ссылка на набор свойств.
// Неопределено - если предопределенный набор не существует.
//
// Пример:
// Ссылка = УправлениеСвойствами.НаборСвойствПоИмени("Справочник_Пользователи");
//
Функция НаборСвойствПоИмени(ИмяНабора) Экспорт
ПредопределенныеНаборыСвойств = УправлениеСвойствамиПовтИсп.ПредопределенныеНаборыСвойств();
Набор = ПредопределенныеНаборыСвойств.Получить(ИмяНабора); // см. Справочники.НаборыДополнительныхРеквизитовИСведений.СвойстваНабора
Если Набор = Неопределено Тогда
Возврат Неопределено;
Иначе
Возврат Набор.Ссылка;
КонецЕсли;
КонецФункции
// Создает/пересоздает дополнительные реквизиты и элементы в форме владельца свойств.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
//
// Объект - Неопределено - взять объект из реквизита формы "Объект".
// - СправочникОбъектИмяСправочника
// - ДокументОбъектИмяДокумента
// - ПланВидовХарактеристикОбъектИмяПланаВидовХарактеристик
// - БизнесПроцессОбъектИмяБизнесПроцесса
// - ЗадачаОбъектИмяЗадачи
// - ПланВидовРасчетаОбъектИмяПланаВидовРасчета
// - ПланСчетовОбъектИмяПланаСчетов
// - ДанныеФормыСтруктура
//
// ПоляНадписей - Булево - если указать Истина, то вместо полей ввода на форме будут созданы поля надписей.
//
// СкрытьУдаленные - Неопределено - не менять текущий режим скрытия удаленных, установленный ранее.
// - Булево - установить/отключить режим скрытия удаленных.
// При вызове процедуры ПередЗаписьюНаСервере в режиме скрытия удаленных, удаленные значения
// очищаются (не переносятся обратно в объект), а режим СкрытьУдаленные устанавливается Ложь.
//
Процедура ЗаполнитьДополнительныеРеквизитыВФорме(Форма, Объект = Неопределено, ПоляНадписей = Ложь, СкрытьУдаленные = Неопределено) Экспорт
Если НЕ Форма.Свойства_ИспользоватьСвойства
ИЛИ НЕ Форма.Свойства_ИспользоватьДопРеквизиты Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(СкрытьУдаленные) = Тип("Булево") Тогда
Форма.Свойства_СкрытьУдаленные = СкрытьУдаленные;
КонецЕсли;
Если Объект = Неопределено Тогда
ОписаниеОбъекта = Форма.Объект;
Иначе
ОписаниеОбъекта = Объект;
КонецЕсли;
Форма.Свойства_НаборыДополнительныхРеквизитовОбъекта = Новый СписокЗначений;
КлючНазначения = Неопределено;
НаборыСвойствОбъекта = УправлениеСвойствамиСлужебный.ПолучитьНаборыСвойствОбъекта(
ОписаниеОбъекта, КлючНазначения);
УправлениеСвойствамиСлужебный.ЗаполнитьНаборыСДополнительнымиРеквизитами(
НаборыСвойствОбъекта,
Форма.Свойства_НаборыДополнительныхРеквизитовОбъекта);
ОбновитьКлючНазначенияФормы(Форма, КлючНазначения);
ОписаниеСвойств = УправлениеСвойствамиСлужебный.ЗначенияСвойств(
ОписаниеОбъекта.ДополнительныеРеквизиты.Выгрузить(),
Форма.Свойства_НаборыДополнительныхРеквизитовОбъекта,
Ложь);
ОписаниеСвойств.Колонки.Добавить("ИмяРеквизитаЗначение");
ОписаниеСвойств.Колонки.Добавить("СтрокаСсылочногоТипа");
ОписаниеСвойств.Колонки.Добавить("ИмяСсылочногоРеквизитаЗначение");
ОписаниеСвойств.Колонки.Добавить("ИмяУникальнаяЧасть");
ОписаниеСвойств.Колонки.Добавить("ДополнительноеЗначение");
ОписаниеСвойств.Колонки.Добавить("Булево");
УдалитьСтарыеРеквизитыИЭлементы(Форма);
// Создание реквизитов.
ДобавляемыеРеквизиты = Новый Массив();
Для каждого ОписаниеСвойства Из ОписаниеСвойств Цикл
ТипЗначенияСвойства = ОписаниеСвойства.ТипЗначения;
СписокТипов = ТипЗначенияСвойства.Типы();
СтроковыйРеквизит = (СписокТипов.Количество() = 1) И (СписокТипов[0] = Тип("Строка"));
// Поддержка строк неограниченной длины.
ИспользоватьНеограниченнуюСтроку = УправлениеСвойствамиСлужебный.ИспользоватьНеограниченнуюСтроку(
ТипЗначенияСвойства, ОписаниеСвойства.МногострочноеПолеВвода);
Если ИспользоватьНеограниченнуюСтроку Тогда
ТипЗначенияСвойства = Новый ОписаниеТипов("Строка");
ИначеЕсли ТипЗначенияСвойства.СодержитТип(Тип("Строка"))
И ТипЗначенияСвойства.КвалификаторыСтроки.Длина = 0 Тогда
// Если нельзя использовать неограниченную строку, а в свойствах реквизита она неограниченная,
// то устанавливаем ограничение в 1024 символа.
ТипЗначенияСвойства = Новый ОписаниеТипов(ОписаниеСвойства.ТипЗначения,
,,, Новый КвалификаторыСтроки(1024));
КонецЕсли;
ОписаниеСвойства.ИмяУникальнаяЧасть =
СтрЗаменить(ВРег(Строка(ОписаниеСвойства.Набор.УникальныйИдентификатор())), "-", "x")
+ "_"
+ СтрЗаменить(ВРег(Строка(ОписаниеСвойства.Свойство.УникальныйИдентификатор())), "-", "x");
ОписаниеСвойства.ИмяРеквизитаЗначение =
"ДополнительныйРеквизитЗначение_" + ОписаниеСвойства.ИмяУникальнаяЧасть;
ОписаниеСвойства.СтрокаСсылочногоТипа = Ложь;
Если СтроковыйРеквизит
И Не ИспользоватьНеограниченнуюСтроку
И ОписаниеСвойства.ВыводитьВВидеГиперссылки Тогда
ФорматированнаяСтрока = Новый ОписаниеТипов("ФорматированнаяСтрока");
ОписаниеСвойства.СтрокаСсылочногоТипа = Истина;
ОписаниеСвойства.ИмяСсылочногоРеквизитаЗначение = "СсылочныйДополнительныйРеквизитЗначение_" + ОписаниеСвойства.ИмяУникальнаяЧасть;
Реквизит = Новый РеквизитФормы(ОписаниеСвойства.ИмяСсылочногоРеквизитаЗначение, ФорматированнаяСтрока, , ОписаниеСвойства.Наименование, Истина);
ДобавляемыеРеквизиты.Добавить(Реквизит);
КонецЕсли;
Если ОписаниеСвойства.Удалено Тогда
ТипЗначенияСвойства = Новый ОписаниеТипов("Строка");
КонецЕсли;
Реквизит = Новый РеквизитФормы(ОписаниеСвойства.ИмяРеквизитаЗначение, ТипЗначенияСвойства, , ОписаниеСвойства.Наименование, Истина);
ДобавляемыеРеквизиты.Добавить(Реквизит);
ОписаниеСвойства.ДополнительноеЗначение =
УправлениеСвойствамиСлужебный.ТипЗначенияСодержитЗначенияСвойств(ТипЗначенияСвойства);
ОписаниеСвойства.Булево = ОбщегоНазначения.ОписаниеТипаСостоитИзТипа(ТипЗначенияСвойства, Тип("Булево"));
КонецЦикла;
Форма.ИзменитьРеквизиты(ДобавляемыеРеквизиты);
// Создание элементов формы.
Для Каждого ОписаниеСвойства Из ОписаниеСвойств Цикл
ИмяЭлементаДляРазмещения = Форма.Свойства_ИмяЭлементаДляРазмещения;
Если ТипЗнч(ИмяЭлементаДляРазмещения) <> Тип("СписокЗначений") Тогда
Если ИмяЭлементаДляРазмещения = Неопределено Тогда
ИмяЭлементаДляРазмещения = "";
КонецЕсли;
ЭлементРазмещения = ?(ИмяЭлементаДляРазмещения = "", Неопределено, Форма.Элементы[ИмяЭлементаДляРазмещения]);
Иначе
РазделыДляРазмещения = Форма.Свойства_ИмяЭлементаДляРазмещения;
РазмещениеНабора = РазделыДляРазмещения.НайтиПоЗначению(ОписаниеСвойства.Набор);
Если РазмещениеНабора = Неопределено Тогда
РазмещениеНабора = РазделыДляРазмещения.НайтиПоЗначению("ВсеОстальные");
КонецЕсли;
ЭлементРазмещения = Форма.Элементы[РазмещениеНабора.Представление];
КонецЕсли;
ФормаОписаниеСвойства = Форма.Свойства_ОписаниеДополнительныхРеквизитов.Добавить();
ЗаполнитьЗначенияСвойств(ФормаОписаниеСвойства, ОписаниеСвойства);
// Заполнение таблицы зависимых дополнительных реквизитов.
Если ОписаниеСвойства.ЗависимостиДополнительныхРеквизитов.Количество() > 0
И Не ОписаниеСвойства.Удалено Тогда
ОписаниеЗависимогоРеквизита = Форма.Свойства_ОписаниеЗависимыхДополнительныхРеквизитов.Добавить();
ЗаполнитьЗначенияСвойств(ОписаниеЗависимогоРеквизита, ОписаниеСвойства);
КонецЕсли;
ОтборСтрок = Новый Структура;
ОтборСтрок.Вставить("НаборСвойств", ОписаниеСвойства.Набор);
ЗависимостиДанногоНабора = ОписаниеСвойства.ЗависимостиДополнительныхРеквизитов.НайтиСтроки(ОтборСтрок);
Для Каждого СтрокаТаблицы Из ЗависимостиДанногоНабора Цикл
Если СтрокаТаблицы.ЗависимоеСвойство = "ЗаполнятьОбязательно"
И ОписаниеСвойства.ТипЗначения = Новый ОписаниеТипов("Булево") Тогда
Продолжить;
КонецЕсли;
Если ОписаниеСвойства.Удалено Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(СтрокаТаблицы.Реквизит) = Тип("Строка") Тогда
ПутьКРеквизиту = "Параметры.ОписаниеОбъекта." + СтрокаТаблицы.Реквизит;
Иначе
ОписаниеДополнительногоРеквизита = ОписаниеСвойств.Найти(СтрокаТаблицы.Реквизит, "Свойство");
Если ОписаниеДополнительногоРеквизита = Неопределено Тогда
Продолжить; // Дополнительный реквизит не существует, условие игнорируется.
КонецЕсли;
ПутьКРеквизиту = "Параметры.Форма." + ОписаниеДополнительногоРеквизита.ИмяРеквизитаЗначение;
КонецЕсли;
УправлениеСвойствамиСлужебный.ПостроитьУсловияЗависимостей(ОписаниеЗависимогоРеквизита, ПутьКРеквизиту, СтрокаТаблицы);
КонецЦикла;
Если ОписаниеСвойства.СтрокаСсылочногоТипа Тогда
Если ЗначениеЗаполнено(ОписаниеСвойства.Значение) Тогда
Значение = ОписаниеСвойства.ТипЗначения.ПривестиЗначение(ОписаниеСвойства.Значение);
СтрокаЗначение = СтроковыеФункции.ФорматированнаяСтрока(Значение);
Иначе
Значение = НСтр("ru = 'не задано'");
СсылкаРедактирования = "НеЗадано";
СтрокаЗначение = Новый ФорматированнаяСтрока(Значение,, ЦветаСтиля.ЦветПустойГиперссылки,, СсылкаРедактирования);
КонецЕсли;
Форма[ОписаниеСвойства.ИмяСсылочногоРеквизитаЗначение] = СтрокаЗначение;
КонецЕсли;
Форма[ОписаниеСвойства.ИмяРеквизитаЗначение] = ОписаниеСвойства.Значение;
Если ОписаниеСвойства.Удалено И Форма.Свойства_СкрытьУдаленные Тогда
Продолжить;
КонецЕсли;
Если НаборыСвойствОбъекта.Количество() > 1 Тогда
ЭлементСписка = Форма.Свойства_ЭлементыГруппДополнительныхРеквизитов.НайтиПоЗначению(
ОписаниеСвойства.Набор);
Если ЭлементСписка <> Неопределено Тогда
Родитель = Форма.Элементы[ЭлементСписка.Представление];
Иначе
ОписаниеНабора = НаборыСвойствОбъекта.Найти(ОписаниеСвойства.Набор, "Набор");
Если ОписаниеНабора = Неопределено Тогда
ОписаниеНабора = НаборыСвойствОбъекта.Добавить();
ОписаниеНабора.Набор = ОписаниеСвойства.Набор;
ОписаниеНабора.Заголовок = НСтр("ru = 'Удаленные реквизиты'")
КонецЕсли;
Если НЕ ЗначениеЗаполнено(ОписаниеНабора.Заголовок) Тогда
ОписаниеНабора.Заголовок = Строка(ОписаниеСвойства.Набор);
КонецЕсли;
ИмяЭлементаНабора = "НаборДополнительныхРеквизитов" + ОписаниеСвойства.ИмяУникальнаяЧасть;
Родитель = Форма.Элементы.Добавить(ИмяЭлементаНабора, Тип("ГруппаФормы"), ЭлементРазмещения);
Форма.Свойства_ЭлементыГруппДополнительныхРеквизитов.Добавить(
ОписаниеСвойства.Набор, Родитель.Имя);
Если ТипЗнч(ЭлементРазмещения) = Тип("ГруппаФормы")
И ЭлементРазмещения.Вид = ВидГруппыФормы.Страницы Тогда
Родитель.Вид = ВидГруппыФормы.Страница;
Иначе
Родитель.Вид = ВидГруппыФормы.ОбычнаяГруппа;
Родитель.Отображение = ОтображениеОбычнойГруппы.Нет;
КонецЕсли;
Родитель.ОтображатьЗаголовок = Ложь;
Родитель.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Вертикальная;
ЗаполненныеСвойстваГруппы = Новый Структура;
Для каждого Колонка Из НаборыСвойствОбъекта.Колонки Цикл
Если ОписаниеНабора[Колонка.Имя] <> Неопределено Тогда
ЗаполненныеСвойстваГруппы.Вставить(Колонка.Имя, ОписаниеНабора[Колонка.Имя]);
КонецЕсли;
КонецЦикла;
ЗаполнитьЗначенияСвойств(Родитель, ЗаполненныеСвойстваГруппы);
КонецЕсли;
Иначе
Родитель = ЭлементРазмещения;
КонецЕсли;
Если ОписаниеСвойства.ВыводитьВВидеГиперссылки Тогда
ИмяГруппыГиперссылки = "Группа_" + ОписаниеСвойства.ИмяУникальнаяЧасть;
ГруппаГиперссылки = Форма.Элементы.Добавить(ИмяГруппыГиперссылки, Тип("ГруппаФормы"), Родитель);
ГруппаГиперссылки.Вид = ВидГруппыФормы.ОбычнаяГруппа;
ГруппаГиперссылки.Отображение = ОтображениеОбычнойГруппы.Нет;
ГруппаГиперссылки.ОтображатьЗаголовок = Ложь;
ГруппаГиперссылки.Группировка = ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяВсегда;
ГруппаГиперссылки.Заголовок = ОписаниеСвойства.Наименование;
Элемент = Форма.Элементы.Добавить(ОписаниеСвойства.ИмяРеквизитаЗначение, Тип("ПолеФормы"), ГруппаГиперссылки); // РасширениеПоляФормыДляПоляНадписи, РасширениеПоляФормыДляПоляВвода
РеквизитДоступен = РеквизитДоступенПоФункциональнымОпциям(ОписаниеСвойства);
Если РеквизитДоступен И Не ПоляНадписей Тогда
ИмяКнопки = "Кнопка_" + ОписаниеСвойства.ИмяУникальнаяЧасть;
Кнопка = Форма.Элементы.Добавить(
ИмяКнопки,
Тип("КнопкаФормы"),
ГруппаГиперссылки);
ЗаголовокКнопки = НСтр("ru = 'Начать/закончить редактирование реквизита %1'");
Кнопка.Заголовок = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ЗаголовокКнопки, ОписаниеСвойства.Наименование);
Кнопка.ТолькоВоВсехДействиях = Истина;
Кнопка.ИмяКоманды = "РедактироватьГиперссылкуРеквизита";
Кнопка.ОтображениеФигуры = ОтображениеФигурыКнопки.ПриАктивности;
КонецЕсли;
Если Не ОписаниеСвойства.СтрокаСсылочногоТипа И ЗначениеЗаполнено(ОписаниеСвойства.Значение) Тогда
Элемент.Гиперссылка = Истина;
КонецЕсли;
Иначе
Элемент = Форма.Элементы.Добавить(ОписаниеСвойства.ИмяРеквизитаЗначение, Тип("ПолеФормы"), Родитель); // РасширениеПоляФормыДляПоляНадписи, РасширениеПоляФормыДляПоляВвода
КонецЕсли;
ФормаОписаниеСвойства.ЭлементФормыДобавлен = Истина;
Если ОписаниеСвойства.Булево И ПустаяСтрока(ОписаниеСвойства.ФорматСвойства) Тогда
Элемент.Вид = ВидПоляФормы.ПолеФлажка;
Элемент.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Право;
Иначе
Если ПоляНадписей Тогда
Элемент.Вид = ВидПоляФормы.ПолеВвода;
ИначеЕсли ОписаниеСвойства.ВыводитьВВидеГиперссылки
И (ОписаниеСвойства.СтрокаСсылочногоТипа
Или ЗначениеЗаполнено(ОписаниеСвойства.Значение))Тогда
Элемент.Вид = ВидПоляФормы.ПолеНадписи;
Иначе
Элемент.Вид = ВидПоляФормы.ПолеВвода;
Элемент.АвтоОтметкаНезаполненного = ОписаниеСвойства.ЗаполнятьОбязательно И НЕ ОписаниеСвойства.Удалено;
КонецЕсли;
Элемент.РастягиватьПоВертикали = Ложь;
Элемент.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Лево;
КонецЕсли;
Если ОписаниеСвойства.СтрокаСсылочногоТипа Тогда
Элемент.ПутьКДанным = ОписаниеСвойства.ИмяСсылочногоРеквизитаЗначение;
Элемент.УстановитьДействие("ОбработкаНавигационнойСсылки", "Подключаемый_СвойстваВыполнитьКоманду");
Иначе
Элемент.ПутьКДанным = ОписаниеСвойства.ИмяРеквизитаЗначение;
КонецЕсли;
Элемент.Подсказка = ОписаниеСвойства.Подсказка;
Элемент.УстановитьДействие("ПриИзменении", "Подключаемый_ПриИзмененииДополнительногоРеквизита");
Если Элемент.Вид = ВидПоляФормы.ПолеВвода
И Не ИспользоватьНеограниченнуюСтроку
И ОписаниеСвойства.ТипЗначения.Типы().Найти(Тип("Строка")) <> Неопределено Тогда
Элемент.СвязьПоТипу = Новый СвязьПоТипу("Свойства_ОписаниеДополнительныхРеквизитов.Свойство",
ОписаниеСвойств.Индекс(ОписаниеСвойства));
КонецЕсли;
Если ОписаниеСвойства.МногострочноеПолеВвода > 0 Тогда
Если НЕ ПоляНадписей Тогда
Элемент.МногострочныйРежим = Истина;
КонецЕсли;
Элемент.Высота = ОписаниеСвойства.МногострочноеПолеВвода;
КонецЕсли;
Если НЕ ПустаяСтрока(ОписаниеСвойства.ФорматСвойства)
И Не ОписаниеСвойства.ВыводитьВВидеГиперссылки Тогда
Если ПоляНадписей Тогда
Элемент.Формат = ОписаниеСвойства.ФорматСвойства;
Иначе
ФорматнаяСтрока = "";
Массив = СтрРазделить(ОписаниеСвойства.ФорматСвойства, ";", Ложь);
Для каждого Подстрока Из Массив Цикл
Если СтрНайти(Подстрока, "ДП=") > 0 ИЛИ СтрНайти(Подстрока, "DE=") > 0 Тогда // @Non-NLS
Продолжить;
КонецЕсли;
Если СтрНайти(Подстрока, "ЧН=") > 0 ИЛИ СтрНайти(Подстрока, "NZ=") > 0 Тогда // @Non-NLS
Продолжить;
КонецЕсли;
Если СтрНайти(Подстрока, "ДФ=") > 0 ИЛИ СтрНайти(Подстрока, "DF=") > 0 Тогда // @Non-NLS
Если СтрНайти(Подстрока, "ддд") > 0 ИЛИ СтрНайти(Подстрока, "ddd") > 0 Тогда // @Non-NLS
Подстрока = СтрЗаменить(Подстрока, "ддд", "дд"); // @Non-NLS-1, @Non-NLS-2
Подстрока = СтрЗаменить(Подстрока, "ddd", "dd");
КонецЕсли;
Если СтрНайти(Подстрока, "дддд") > 0 ИЛИ СтрНайти(Подстрока, "dddd") > 0 Тогда // @Non-NLS
Подстрока = СтрЗаменить(Подстрока, "дддд", "дд"); // @Non-NLS-1, @Non-NLS-2
Подстрока = СтрЗаменить(Подстрока, "dddd", "dd");
КонецЕсли;
Если СтрНайти(Подстрока, "МММ") > 0 ИЛИ СтрНайти(Подстрока, "MMM") > 0 Тогда // @Non-NLS
Подстрока = СтрЗаменить(Подстрока, "МММ", "ММ"); // @Non-NLS-1, @Non-NLS-2
Подстрока = СтрЗаменить(Подстрока, "MMM", "MM");
КонецЕсли;
Если СтрНайти(Подстрока, "ММММ") > 0 ИЛИ СтрНайти(Подстрока, "MMMM") > 0 Тогда // @Non-NLS
Подстрока = СтрЗаменить(Подстрока, "ММММ", "ММ"); // @Non-NLS-1, @Non-NLS-2
Подстрока = СтрЗаменить(Подстрока, "MMMM", "MM");
КонецЕсли;
КонецЕсли;
Если СтрНайти(Подстрока, "ДЛФ=") > 0 ИЛИ СтрНайти(Подстрока, "DLF=") > 0 Тогда // @Non-NLS
Если СтрНайти(Подстрока, "ДД") > 0 ИЛИ СтрНайти(Подстрока, "DD") > 0 Тогда // @Non-NLS
Подстрока = СтрЗаменить(Подстрока, "ДД", "Д"); // @Non-NLS-1, @Non-NLS-2
Подстрока = СтрЗаменить(Подстрока, "DD", "D");
КонецЕсли;
КонецЕсли;
ФорматнаяСтрока = ФорматнаяСтрока + ?(ФорматнаяСтрока = "", "", ";") + Подстрока;
КонецЦикла;
Элемент.Формат = ФорматнаяСтрока;
Элемент.ФорматРедактирования = ФорматнаяСтрока;
КонецЕсли;
КонецЕсли;
Если ОписаниеСвойства.Удалено Тогда
Элемент.ЦветТекстаЗаголовка = ЦветаСтиля.ТекстЗапрещеннойЯчейкиЦвет;
Элемент.ШрифтЗаголовка = ШрифтыСтиля.ЗаголовокУдаленногоРеквизитаШрифт;
Если Элемент.Вид = ВидПоляФормы.ПолеВвода Тогда
Элемент.КнопкаОчистки = Истина;
Элемент.КнопкаВыбора = Ложь;
Элемент.КнопкаОткрытия = Ложь;
Элемент.КнопкаВыпадающегоСписка = Ложь;
Элемент.РедактированиеТекста = Ложь;
КонецЕсли;
КонецЕсли;
Если НЕ ПоляНадписей И Элемент.Вид = ВидПоляФормы.ПолеВвода Тогда
Элемент.ВыборГруппИЭлементов = ГруппыИЭлементы.ГруппыИЭлементы;
КонецЕсли;
Если НЕ ПоляНадписей И ОписаниеСвойства.ДополнительноеЗначение И Элемент.Вид = ВидПоляФормы.ПолеВвода Тогда
ПараметрыВыбора = Новый Массив;
ПараметрыВыбора.Добавить(Новый ПараметрВыбора("Отбор.Владелец",
?(ЗначениеЗаполнено(ОписаниеСвойства.ВладелецДополнительныхЗначений),
ОписаниеСвойства.ВладелецДополнительныхЗначений, ОписаниеСвойства.Свойство)));
Элемент.ПараметрыВыбора = Новый ФиксированныйМассив(ПараметрыВыбора);
КонецЕсли;
КонецЦикла;
// Установка видимости, доступности и обязательности заполнения дополнительных реквизитов.
Для Каждого ОписаниеЗависимогоРеквизита Из Форма.Свойства_ОписаниеЗависимыхДополнительныхРеквизитов Цикл
Если ОписаниеЗависимогоРеквизита.ВыводитьВВидеГиперссылки Тогда
ОбрабатываемыйЭлемент = СтрЗаменить(ОписаниеЗависимогоРеквизита.ИмяРеквизитаЗначение, "ДополнительныйРеквизитЗначение_", "Группа_");
Иначе
ОбрабатываемыйЭлемент = ОписаниеЗависимогоРеквизита.ИмяРеквизитаЗначение;
КонецЕсли;
Если ОписаниеЗависимогоРеквизита.УсловиеДоступности <> Неопределено Тогда
Результат = РезультатВычисленияУсловия(Форма, ОписаниеОбъекта, ОписаниеЗависимогоРеквизита.УсловиеДоступности);
Элемент = Форма.Элементы[ОбрабатываемыйЭлемент]; // ПолеФормы
Если Элемент.Доступность <> Результат Тогда
Элемент.Доступность = Результат;
КонецЕсли;
КонецЕсли;
Если ОписаниеЗависимогоРеквизита.УсловиеВидимости <> Неопределено Тогда
Результат = РезультатВычисленияУсловия(Форма, ОписаниеОбъекта, ОписаниеЗависимогоРеквизита.УсловиеВидимости);
Элемент = Форма.Элементы[ОбрабатываемыйЭлемент];
Если Элемент.Видимость <> Результат Тогда
Элемент.Видимость = Результат;
КонецЕсли;
КонецЕсли;
Если ОписаниеЗависимогоРеквизита.УсловиеОбязательностиЗаполнения <> Неопределено Тогда
Если Не ОписаниеЗависимогоРеквизита.ЗаполнятьОбязательно Тогда
Продолжить;
КонецЕсли;
Результат = РезультатВычисленияУсловия(Форма, ОписаниеОбъекта, ОписаниеЗависимогоРеквизита.УсловиеОбязательностиЗаполнения);
Элемент = Форма.Элементы[ОбрабатываемыйЭлемент];
Если Не ОписаниеЗависимогоРеквизита.ВыводитьВВидеГиперссылки
И Элемент.АвтоОтметкаНезаполненного <> Результат Тогда
Элемент.АвтоОтметкаНезаполненного = Результат;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Структура = Новый Структура("ПараметрыСвойств");
ЗаполнитьЗначенияСвойств(Структура, Форма);
Если ТипЗнч(Структура.ПараметрыСвойств) = Тип("Структура")
И Структура.ПараметрыСвойств.Свойство("ВыполненаОтложеннаяИнициализация") Тогда
Форма.ПараметрыСвойств.ВыполненаОтложеннаяИнициализация = Истина;
// Удаление временной декорации, если она была добавлена.
Если Форма.ПараметрыСвойств.Свойство("ДобавленаПустаяДекорация") Тогда
Для Каждого ИмяДекорации Из Форма.ПараметрыСвойств.КоллекцияДекораций Цикл
Форма.Элементы.Удалить(Форма.Элементы[ИмяДекорации]);
КонецЦикла;
Форма.ПараметрыСвойств.Удалить("ДобавленаПустаяДекорация");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Переносит значения свойств из реквизитов формы в табличную часть объекта.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
// Объект - Неопределено - взять объект из реквизита формы "Объект".
// - СправочникОбъект, ДокументОбъект, ДанныеФормыСтруктура - объект со свойствами или
// реквизит формы, содержащий объект.
//
Процедура ПеренестиЗначенияИзРеквизитовФормыВОбъект(Форма, Объект = Неопределено) Экспорт
УправлениеСвойствамиСлужебный.ПеренестиЗначенияИзРеквизитовФормыВОбъект(Форма, Объект);
КонецПроцедуры
// Удаляет старые реквизиты и элементы формы.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
//
Процедура УдалитьСтарыеРеквизитыИЭлементы(Форма) Экспорт
УдаляемыеРеквизиты = Новый Массив;
Для каждого ОписаниеСвойства Из Форма.Свойства_ОписаниеДополнительныхРеквизитов Цикл
УникальнаяЧасть = СтрЗаменить(ОписаниеСвойства.ИмяРеквизитаЗначение, "ДополнительныйРеквизитЗначение_", "");
УдаляемыеРеквизиты.Добавить(ОписаниеСвойства.ИмяРеквизитаЗначение);
Если ОписаниеСвойства.СтрокаСсылочногоТипа Тогда
УдаляемыеРеквизиты.Добавить("СсылочныйДополнительныйРеквизитЗначение_" + УникальнаяЧасть);
КонецЕсли;
Если ОписаниеСвойства.ЭлементФормыДобавлен Тогда
Если ОписаниеСвойства.ВыводитьВВидеГиперссылки Тогда
Форма.Элементы.Удалить(Форма.Элементы["Группа_" + УникальнаяЧасть]);
Иначе
Форма.Элементы.Удалить(Форма.Элементы[ОписаниеСвойства.ИмяРеквизитаЗначение]);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если УдаляемыеРеквизиты.Количество() > 0 Тогда
Форма.ИзменитьРеквизиты(, УдаляемыеРеквизиты);
КонецЕсли;
Для каждого ЭлементСписка Из Форма.Свойства_ЭлементыГруппДополнительныхРеквизитов Цикл
Форма.Элементы.Удалить(Форма.Элементы[ЭлементСписка.Представление]);
КонецЦикла;
Форма.Свойства_ОписаниеДополнительныхРеквизитов.Очистить();
Форма.Свойства_ЭлементыГруппДополнительныхРеквизитов.Очистить();
Форма.Свойства_ОписаниеЗависимыхДополнительныхРеквизитов.Очистить();
КонецПроцедуры
// Возвращает дополнительные реквизиты и сведения у указанного объекта.
//
// Параметры:
// ВладелецСвойств - ЛюбаяСсылка - например: СправочникСсылка.Номенклатура, ДокументСсылка.ЗаказПокупателя, ...
// - СправочникОбъект, ДокументОбъект - любой объект со свойствами.
// - ДанныеФормыСтруктура - коллекция по типу объекта владельца свойств.
// ПолучатьДопРеквизиты - Булево - в результат включать дополнительные реквизиты.
// ПолучатьДопСведения - Булево - в результат включать дополнительные сведения.
//
// Возвращаемое значение:
// Массив из ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения
//
Функция СвойстваОбъекта(ВладелецСвойств, ПолучатьДопРеквизиты = Истина, ПолучатьДопСведения = Истина) Экспорт
Если НЕ (ПолучатьДопРеквизиты ИЛИ ПолучатьДопСведения) Тогда
Возврат Новый Массив;
КонецЕсли;
ПолучатьДопСведения = ПолучатьДопСведения И ПравоДоступа("Чтение", Метаданные.РегистрыСведений.ДополнительныеСведения);
УстановитьПривилегированныйРежим(Истина);
НаборыСвойствОбъекта = УправлениеСвойствамиСлужебный.ПолучитьНаборыСвойствОбъекта(
ВладелецСвойств);
УстановитьПривилегированныйРежим(Ложь);
МассивНаборовСвойствОбъекта = НаборыСвойствОбъекта.ВыгрузитьКолонку("Набор");
ТекстЗапросаДопРеквизиты =
"ВЫБРАТЬ
| ТаблицаСвойств.Свойство КАК Свойство
|ИЗ
| Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты КАК ТаблицаСвойств
|ГДЕ
| ТаблицаСвойств.Ссылка В (&МассивНаборовСвойствОбъекта)";
ТекстЗапросаДопСведения =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ТаблицаСвойств.Свойство КАК Свойство
|ИЗ
| Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеСведения КАК ТаблицаСвойств
|ГДЕ
| ТаблицаСвойств.Ссылка В (&МассивНаборовСвойствОбъекта)";
Запрос = Новый Запрос;
Если ПолучатьДопРеквизиты И ПолучатьДопСведения Тогда
Запрос.Текст = ТекстЗапросаДопСведения + "
|
| ОБЪЕДИНИТЬ ВСЕ
|" + ТекстЗапросаДопРеквизиты;
ИначеЕсли ПолучатьДопРеквизиты Тогда
Запрос.Текст = ТекстЗапросаДопРеквизиты;
ИначеЕсли ПолучатьДопСведения Тогда
Запрос.Текст = ТекстЗапросаДопСведения;
КонецЕсли;
Запрос.Параметры.Вставить("МассивНаборовСвойствОбъекта", МассивНаборовСвойствОбъекта);
Результат = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Свойство");
Возврат Результат;
КонецФункции
// АПК:142-выкл Проектное решение
// Возвращает значения дополнительных свойств объектов.
//
// Параметры:
// ОбъектыСоСвойствами - Массив - объекты, для которых нужно получить значения дополнительных свойств.
// - ЛюбаяСсылка - ссылка на объект, например, СправочникСсылка.Номенклатура,
// ДокументСсылка.ЗаказПокупателя, ...
// ПолучатьДопРеквизиты - Булево - в результат включать дополнительные реквизиты. По умолчанию Истина.
// ПолучатьДопСведения - Булево - в результат включать дополнительные сведения. По умолчанию Истина.
// Свойства - Массив из ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - значения
// которых следует получить.
// - Массив из Строка - уникальное имя дополнительного свойства.
// - Неопределено - по умолчанию, получить значения всех свойств владельца.
// КодЯзыка - Строка - код языка, на котором будет получено представление значения свойства.
// Если не указано - берется текущий язык.
//
// Возвращаемое значение:
// ТаблицаЗначений:
// * Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - свойство владельца.
// * ИмяСвойства - Строка - уникальное имя свойства владельца.
// * Значение - Произвольный - значения любого типа из описания типов свойства объекта метаданных:
// "Метаданные.ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения.Тип".
// * Представление - Строка - представление значения на указанном языке.
// * ВладелецСвойств - ЛюбаяСсылка - ссылка на объект.
//
Функция ЗначенияСвойств(ОбъектыСоСвойствами,
ПолучатьДопРеквизиты = Истина,
ПолучатьДопСведения = Истина,
Свойства = Неопределено,
КодЯзыка = "") Экспорт
Если Не СвойстваДоступны() Тогда
Возврат Новый ТаблицаЗначений;
КонецЕсли;
ПолучатьДопСведения = ПолучатьДопСведения И ПравоДоступа("Чтение", Метаданные.РегистрыСведений.ДополнительныеСведения);
Если ТипЗнч(ОбъектыСоСвойствами) = Тип("Массив") Тогда
ВладелецСвойств = ОбъектыСоСвойствами[0];
Иначе
ВладелецСвойств = ОбъектыСоСвойствами;
КонецЕсли;
Если ПолучатьДопРеквизиты Тогда
ПолучатьДопРеквизиты = ИспользоватьДопРеквизиты(ВладелецСвойств);
КонецЕсли;
Если ПолучатьДопСведения Тогда
ПолучатьДопСведения = ИспользоватьДопСведения(ВладелецСвойств);
КонецЕсли;
Если Не ПолучатьДопРеквизиты И Не ПолучатьДопСведения Тогда
Возврат Новый ТаблицаЗначений;
КонецЕсли;
Если Свойства = Неопределено Тогда
Свойства = СвойстваОбъекта(ВладелецСвойств, ПолучатьДопРеквизиты, ПолучатьДопСведения);
КонецЕсли;
ИмяОбъектаСоСвойствами = ОбщегоНазначения.ИмяТаблицыПоСсылке(ВладелецСвойств);
ТекстЗапросаДопРеквизиты =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ТаблицаСвойств.Свойство КАК Свойство,
| ТаблицаСвойств.Значение КАК Значение,
| ТаблицаСвойств.ТекстоваяСтрока,
| ТаблицаСвойств.Ссылка КАК ВладелецСвойств,
| ДополнительныеРеквизитыИСведения.Имя КАК ИмяСвойства
|ИЗ
| &ИмяОбъектаСоСвойствами КАК ТаблицаСвойств
| ЛЕВОЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
| ПО ДополнительныеРеквизитыИСведения.Ссылка = ТаблицаСвойств.Свойство
|ГДЕ
| ТаблицаСвойств.Ссылка В (&ОбъектыСоСвойствами)
| И (ДополнительныеРеквизитыИСведения.Ссылка В (&Свойства)
| ИЛИ ДополнительныеРеквизитыИСведения.Имя В (&Свойства))";
ТекстЗапросаДопСведения =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ТаблицаСвойств.Свойство КАК Свойство,
| ТаблицаСвойств.Значение КАК Значение,
| """" КАК ТекстоваяСтрока,
| ТаблицаСвойств.Объект КАК ВладелецСвойств,
| ДополнительныеРеквизитыИСведения.Имя КАК ИмяСвойства
|ИЗ
| РегистрСведений.ДополнительныеСведения КАК ТаблицаСвойств
| ЛЕВОЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
| ПО ДополнительныеРеквизитыИСведения.Ссылка = ТаблицаСвойств.Свойство
|ГДЕ
| ТаблицаСвойств.Объект В (&ОбъектыСоСвойствами)
| И (ДополнительныеРеквизитыИСведения.Ссылка В (&Свойства)
| ИЛИ ДополнительныеРеквизитыИСведения.Имя В (&Свойства))";
Запрос = Новый Запрос;
Если ПолучатьДопРеквизиты И ПолучатьДопСведения Тогда
ТекстЗапроса = ТекстЗапросаДопРеквизиты + "
|
| ОБЪЕДИНИТЬ ВСЕ
|" + СтрЗаменить(ТекстЗапросаДопСведения, "РАЗРЕШЕННЫЕ", ""); // @Query-part-1, @Query-part-2
ИначеЕсли ПолучатьДопРеквизиты Тогда
ТекстЗапроса = ТекстЗапросаДопРеквизиты;
ИначеЕсли ПолучатьДопСведения Тогда
ТекстЗапроса = ТекстЗапросаДопСведения;
КонецЕсли;
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ИмяОбъектаСоСвойствами", ИмяОбъектаСоСвойствами + ".ДополнительныеРеквизиты");
Запрос.Параметры.Вставить("ОбъектыСоСвойствами", ОбъектыСоСвойствами);
Запрос.Параметры.Вставить("Свойства", Свойства);
Запрос.Текст = ТекстЗапроса;
Результат = Запрос.Выполнить().Выгрузить();
Результат.Колонки.Добавить("Представление");
РезультатСТекстовымиСтроками = Неопределено;
ИндексСтроки = 0;
Для каждого ЗначениеСвойства Из Результат Цикл
ЗначениеСвойства.Представление = ПредставлениеЗначения(ЗначениеСвойства.Значение,
КодЯзыка,
ФорматСвойства(ЗначениеСвойства.Свойство));
ТекстоваяСтрока = ЗначениеСвойства.ТекстоваяСтрока;
Если Не ПустаяСтрока(ТекстоваяСтрока) Тогда
Если РезультатСТекстовымиСтроками = Неопределено Тогда
РезультатСТекстовымиСтроками = Результат.Скопировать(,"Свойство, ВладелецСвойств, ИмяСвойства, Представление");
РезультатСТекстовымиСтроками.Колонки.Добавить("Значение");
РезультатСТекстовымиСтроками.ЗагрузитьКолонку(Результат.ВыгрузитьКолонку("Значение"), "Значение");
КонецЕсли;
РезультатСТекстовымиСтроками[ИндексСтроки].Значение = ТекстоваяСтрока;
КонецЕсли;
ИндексСтроки = ИндексСтроки + 1;
КонецЦикла;
Возврат ?(РезультатСТекстовымиСтроками <> Неопределено, РезультатСТекстовымиСтроками, Результат);
КонецФункции
// АПК:142-вкл
// Возвращает значение дополнительного свойства объекта.
//
// Параметры:
// Объект - ЛюбаяСсылка - ссылка на объект, например, СправочникСсылка.Номенклатура,
// ДокументСсылка.ЗаказПокупателя, ...
// Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - ссылка на
// дополнительный реквизит, значение которого нужно получить.
// - Строка - имя дополнительного свойства.
// КодЯзыка - Строка - если указано, то вместо значения дополнительного свойства будет
// возвращено его представление на указанном языке.
//
// Возвращаемое значение:
// Произвольный - любое значение, допустимое для свойства.
//
Функция ЗначениеСвойства(Объект, Свойство, КодЯзыка = "") Экспорт
ПолучатьРеквизиты = УправлениеСвойствамиСлужебный.ЭтоОбъектМетаданныхСДополнительнымиРеквизитами(Объект.Метаданные());
Результат = ЗначенияСвойств(Объект, ПолучатьРеквизиты, Истина, Свойство, КодЯзыка);
Если Результат.Количество() = 1 Тогда
Если ЗначениеЗаполнено(КодЯзыка) Тогда
Возврат Результат[0].Представление;
Иначе
Возврат Результат[0].Значение;
КонецЕсли;
КонецЕсли;
КонецФункции
// Проверяет, есть ли у объекта свойство.
//
// Параметры:
// ВладелецСвойств - ЛюбаяСсылка - например: СправочникСсылка.Номенклатура, ДокументСсылка.ЗаказПокупателя, ...
// Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - проверяемое свойство.
//
// Возвращаемое значение:
// Булево - если Истина, свойство у владельца есть.
//
Функция ПроверитьСвойствоУОбъекта(ВладелецСвойств, Свойство) Экспорт
МассивСвойств = СвойстваОбъекта(ВладелецСвойств);
Если МассивСвойств.Найти(Свойство) = Неопределено Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
КонецФункции
// Записывает дополнительные реквизиты и сведения владельцу свойств.
// Изменения происходят в транзакции.
//
// Параметры:
// ВладелецСвойств - ЛюбаяСсылка - например, СправочникСсылка.Номенклатура, ДокументСсылка.ЗаказПокупателя и т.д.
// ТаблицаСвойствИЗначений - ТаблицаЗначений:
// * Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - свойство владельца.
// * Значение - Произвольный - любое значение, допустимое для свойства (указано в элементе свойства).
//
Процедура ЗаписатьСвойстваУОбъекта(ВладелецСвойств, ТаблицаСвойствИЗначений) Экспорт
ТаблицаДопРеквизитов = Новый ТаблицаЗначений;
ТаблицаДопРеквизитов.Колонки.Добавить("Свойство", Новый ОписаниеТипов("ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения"));
ТаблицаДопРеквизитов.Колонки.Добавить("Значение");
ТаблицаДопРеквизитов.Колонки.Добавить("ТекстоваяСтрока");
ТаблицаДопСведений = ТаблицаДопРеквизитов.СкопироватьКолонки();
Для Каждого СтрокаТаблицыСвойств Из ТаблицаСвойствИЗначений Цикл
Если СтрокаТаблицыСвойств.Свойство.ЭтоДополнительноеСведение Тогда
НоваяСтрока = ТаблицаДопСведений.Добавить();
Иначе
НоваяСтрока = ТаблицаДопРеквизитов.Добавить();
Если ТипЗнч(СтрокаТаблицыСвойств.Значение) = Тип("Строка")
И СтрДлина(СтрокаТаблицыСвойств.Значение) > 1024 Тогда
НоваяСтрока.ТекстоваяСтрока = СтрокаТаблицыСвойств.Значение;
КонецЕсли;
КонецЕсли;
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТаблицыСвойств, "Свойство,Значение");
КонецЦикла;
ЕстьДопРеквизиты = ТаблицаДопРеквизитов.Количество() > 0;
ЕстьДопСведения = ТаблицаДопСведений.Количество() > 0;
МассивСвойств = СвойстваОбъекта(ВладелецСвойств);
МассивДопРеквизитов = Новый Массив;
МассивДопСведений = Новый Массив;
Для Каждого ДопСвойство Из МассивСвойств Цикл
Если ДопСвойство.ЭтоДополнительноеСведение Тогда
МассивДопСведений.Добавить(ДопСвойство);
Иначе
МассивДопРеквизитов.Добавить(ДопСвойство);
КонецЕсли;
КонецЦикла;
НачатьТранзакцию();
Попытка
Если ЕстьДопРеквизиты Тогда
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить(ВладелецСвойств.Метаданные().ПолноеИмя());
ЭлементБлокировки.УстановитьЗначение("Ссылка", ВладелецСвойств);
Блокировка.Заблокировать();
ВладелецСвойствОбъект = ВладелецСвойств.ПолучитьОбъект();
ЗаблокироватьДанныеДляРедактирования(ВладелецСвойствОбъект.Ссылка);
Для Каждого ДопРеквизит Из ТаблицаДопРеквизитов Цикл
Если МассивДопРеквизитов.Найти(ДопРеквизит.Свойство) = Неопределено Тогда
Продолжить;
КонецЕсли;
МассивСтрок = ВладелецСвойствОбъект.ДополнительныеРеквизиты.НайтиСтроки(Новый Структура("Свойство", ДопРеквизит.Свойство));
Если МассивСтрок.Количество() Тогда
СтрокаСвойства = МассивСтрок[0];
Иначе
СтрокаСвойства = ВладелецСвойствОбъект.ДополнительныеРеквизиты.Добавить();
КонецЕсли;
ЗаполнитьЗначенияСвойств(СтрокаСвойства, ДопРеквизит, "Свойство,Значение,ТекстоваяСтрока");
КонецЦикла;
ВладелецСвойствОбъект.Записать();
КонецЕсли;
Если ЕстьДопСведения Тогда
Для Каждого ДопСведение Из ТаблицаДопСведений Цикл
Если МассивДопСведений.Найти(ДопСведение.Свойство) = Неопределено Тогда
Продолжить;
КонецЕсли;
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ДополнительныеСведения");
ЭлементБлокировки.УстановитьЗначение("Объект", ВладелецСвойств);
ЭлементБлокировки.УстановитьЗначение("Свойство", ДопСведение.Свойство);
Блокировка.Заблокировать();
МенеджерЗаписи = РегистрыСведений.ДополнительныеСведения.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Объект = ВладелецСвойств;
МенеджерЗаписи.Свойство = ДопСведение.Свойство;
МенеджерЗаписи.Значение = ДопСведение.Значение;
МенеджерЗаписи.Записать(Истина);
КонецЦикла;
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
// Проверяет, используются ли дополнительные реквизиты с объектом.
//
// Параметры:
// ВладелецСвойств - ЛюбаяСсылка - например, СправочникСсылка.Номенклатура, ДокументСсылка.ЗаказПокупателя, ...
//
// Возвращаемое значение:
// Булево - если Истина, тогда дополнительные реквизиты используются.
//
Функция ИспользоватьДопРеквизиты(ВладелецСвойств) Экспорт
МетаданныеВладельца = ВладелецСвойств.Метаданные();
Возврат МетаданныеВладельца.ТабличныеЧасти.Найти("ДополнительныеРеквизиты") <> Неопределено
И МетаданныеВладельца <> Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений;
КонецФункции
// Проверяет, используются ли дополнительные сведения объектом.
//
// Параметры:
// ВладелецСвойств - ЛюбаяСсылка - например, СправочникСсылка.Номенклатура, ДокументСсылка.ЗаказПокупателя, ...
//
// Возвращаемое значение:
// Булево - если Истина, тогда дополнительные сведения используются.
//
Функция ИспользоватьДопСведения(ВладелецСвойств) Экспорт
Возврат Метаданные.НайтиПоПолномуИмени("ОбщаяКоманда.ДополнительныеСведенияКоманднаяПанель") <> Неопределено
И Метаданные.ОбщиеКоманды.ДополнительныеСведенияКоманднаяПанель.ТипПараметраКоманды.Типы().Найти(ТипЗнч(ВладелецСвойств)) <> Неопределено;
КонецФункции
// Проверяет доступность подсистемы для текущего пользователя.
//
// Возвращаемое значение:
// Булево - Истина, если подсистема доступна.
//
Функция СвойстваДоступны() Экспорт
Возврат ПравоДоступа("Чтение", Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений);
КонецФункции
// Возвращает представление значения дополнительного свойства объекта
// на требуемом языке.
//
// Параметры:
// Объект - ЛюбаяСсылка - ссылка на объект, например, СправочникСсылка.Номенклатура,
// ДокументСсылка.ЗаказПокупателя, ...
// Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - ссылка на
// дополнительный реквизит, значение которого нужно получить.
// - Строка - имя дополнительного свойства.
// КодЯзыка - Строка - код языка, на котором нужно получить представление.
//
// Возвращаемое значение:
// Строка
//
Функция ПредставлениеЗначенияСвойства(Объект, Свойство, КодЯзыка = "") Экспорт
Представление = ЗначениеСвойства(Объект, Свойство, КодЯзыка);
Возврат Представление;
КонецФункции
// Возвращает значения дополнительных свойств объектов.
// Подходит для подстановки параметров при формировании печатных форм.
//
// Параметры:
// ОбъектыСоСвойствами - Массив - объекты, для которых нужно получить значения дополнительных свойств.
// - ЛюбаяСсылка - ссылка на объект, например, СправочникСсылка.Номенклатура,
// ДокументСсылка.ЗаказПокупателя, ...
// КодЯзыка - Строка - код языка, на котором нужно получить представление.
//
// Возвращаемое значение:
// Соответствие из КлючИЗначение:
// * Ключ - ЛюбаяСсылка - ссылка на объект.
// * Значение - Структура:
// * Ключ - Строка - имя свойства.
// * Значение - Строка - представление свойства на переданном языке.
//
Функция ПредставленияЗначенийСвойств(ОбъектыСоСвойствами, КодЯзыка = "") Экспорт
ЗначенияСвойств = ЗначенияСвойств(ОбъектыСоСвойствами, Истина, Истина, Неопределено, КодЯзыка);
Результат = Новый Соответствие;
Для Каждого ЗначениеСвойства Из ЗначенияСвойств Цикл
Если Результат[ЗначениеСвойства.ВладелецСвойств] = Неопределено Тогда
Результат.Вставить(ЗначениеСвойства.ВладелецСвойств, Новый Структура);
КонецЕсли;
ИмяСвойства = ЗначениеСвойства.ИмяСвойства;
ПервыйСимвол = Лев(ЗначениеСвойства.ИмяСвойства, 1);
Если СтрНайти("0123456789", ПервыйСимвол) > 0 Тогда
ИмяСвойства = "_" + ИмяСвойства;
КонецЕсли;
Результат[ЗначениеСвойства.ВладелецСвойств].Вставить(ИмяСвойства, ЗначениеСвойства.Представление);
КонецЦикла;
Если ТипЗнч(ОбъектыСоСвойствами) = Тип("Массив") Тогда
Для Каждого ОбъектСоСвойствами Из ОбъектыСоСвойствами Цикл
Если Результат[ОбъектСоСвойствами] = Неопределено Тогда
Результат[ОбъектСоСвойствами] = Новый Структура;
КонецЕсли;
КонецЦикла;
Иначе
Если Результат[ОбъектСоСвойствами] = Неопределено Тогда
Результат[ОбъектСоСвойствами] = Новый Структура;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// Обновление информационной базы.
// 1. Обновляет наименования предопределенных наборов свойств,
// если они отличаются от текущих представлений соответствующих
// им объектов метаданных со свойствами.
// 2. Обновляет наименования не общих свойств, если у них
// уточнение отличается от наименования их набора.
// 3. Устанавливает пометку удаления у необщих свойств,
// если установлена пометка удаления их наборов.
//
Процедура ОбновитьНаименованияНаборовИСвойств() Экспорт
ЗапросНаборов = Новый Запрос;
ЗапросНаборов.Текст =
"ВЫБРАТЬ
| Наборы.Ссылка КАК Ссылка,
| Наборы.Наименование КАК Наименование
|ИЗ
| Справочник.НаборыДополнительныхРеквизитовИСведений КАК Наборы
|ГДЕ
| Наборы.Предопределенный
| И Наборы.Родитель = ЗНАЧЕНИЕ(Справочник.НаборыДополнительныхРеквизитовИСведений.ПустаяСсылка)";
ВыборкаНаборов = ЗапросНаборов.Выполнить().Выбрать();
Пока ВыборкаНаборов.Следующий() Цикл
НачатьТранзакцию();
Попытка
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Справочник.НаборыДополнительныхРеквизитовИСведений");
ЭлементБлокировки.УстановитьЗначение("Ссылка", ВыборкаНаборов.Ссылка);
Блокировка.Заблокировать();
Наименование = УправлениеСвойствамиСлужебный.НаименованиеПредопределенногоНабора(
ВыборкаНаборов.Ссылка);
Если ВыборкаНаборов.Наименование <> Наименование Тогда
Объект = ВыборкаНаборов.Ссылка.ПолучитьОбъект();
Объект.Наименование = Наименование;
ОбновлениеИнформационнойБазы.ЗаписатьДанные(Объект);
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецЦикла;
ЗапросСвойств = Новый Запрос;
ЗапросСвойств.Текст =
"ВЫБРАТЬ
| Свойства.Ссылка КАК Ссылка,
| Свойства.НаборСвойств.ПометкаУдаления КАК ПометкаУдаленияНабора
|ИЗ
| ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК Свойства
|ГДЕ
| ВЫБОР
| КОГДА Свойства.НаборСвойств = ЗНАЧЕНИЕ(Справочник.НаборыДополнительныхРеквизитовИСведений.ПустаяСсылка)
| ТОГДА ЛОЖЬ
| ИНАЧЕ ВЫБОР
| КОГДА Свойства.Наименование <> Свойства.Заголовок
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ
| КОНЕЦ";
ВыборкаСвойств = ЗапросСвойств.Выполнить().Выбрать();
Пока ВыборкаСвойств.Следующий() Цикл
НачатьТранзакцию();
Попытка
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения");
ЭлементБлокировки.УстановитьЗначение("Ссылка", ВыборкаСвойств.Ссылка);
Блокировка.Заблокировать();
Объект = ВыборкаСвойств.Ссылка.ПолучитьОбъект(); // ПланВидовХарактеристикОбъект.ДополнительныеРеквизитыИСведения
Объект.Наименование = Объект.Заголовок;
Объект.ПометкаУдаления = ВыборкаСвойств.ПометкаУдаленияНабора;
ОбновлениеИнформационнойБазы.ЗаписатьДанные(Объект);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецЦикла;
КонецПроцедуры
// Устанавливает параметры набора свойств.
//
// Параметры:
// ИмяНабораСвойств - Строка - имя предопределенного набора свойств.
// Параметры - см. СтруктураПараметровНабораСвойств
//
Процедура УстановитьПараметрыНабораСвойств(ИмяНабораСвойств, Параметры = Неопределено) Экспорт
Если Параметры = Неопределено Тогда
Параметры = СтруктураПараметровНабораСвойств();
КонецЕсли;
ЗаписатьОбъект = Ложь;
НаборСвойств = НаборСвойствПоИмени(ИмяНабораСвойств);
Если НаборСвойств = Неопределено Тогда
НаборСвойств = Справочники.НаборыДополнительныхРеквизитовИСведений[ИмяНабораСвойств];
КонецЕсли;
НачатьТранзакцию();
Попытка
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Справочник.НаборыДополнительныхРеквизитовИСведений");
ЭлементБлокировки.УстановитьЗначение("Ссылка", НаборСвойств);
Блокировка.Заблокировать();
НаборСвойствОбъект = НаборСвойств.ПолучитьОбъект();
Если НаборСвойствОбъект = Неопределено Тогда
ОтменитьТранзакцию();
Возврат;
КонецЕсли;
Для Каждого Параметр Из Параметры Цикл
Если НаборСвойствОбъект[Параметр.Ключ] = Параметр.Значение Тогда
Продолжить;
КонецЕсли;
ЗаписатьОбъект = Истина;
КонецЦикла;
Если ЗаписатьОбъект Тогда
ЗаполнитьЗначенияСвойств(НаборСвойствОбъект, Параметры);
ОбновлениеИнформационнойБазы.ЗаписатьДанные(НаборСвойствОбъект);
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
// Получает структуру параметров для набора свойств.
//
// Возвращаемое значение:
// Структура:
// * Используется - Булево - признак использования набора свойств.
// Устанавливается в Ложь, например, если
// объект отключен функциональной опцией.
//
Функция СтруктураПараметровНабораСвойств() Экспорт
Параметры = Новый Структура;
Параметры.Вставить("Используется", Истина);
Возврат Параметры;
КонецФункции
// Для использования в обработчиках обновления. Позволяет сохранить настройки форм
// при переходе на описание наборов свойств в процедуре
// УправлениеСвойствамиПереопределяемый.ПриПолученииПредопределенныхНаборовСвойств,
// если до этого они описывались в предопределенных элементах справочника
// НаборыДополнительныхРеквизитовИСведений.
//
Процедура ВосстановитьНастройкиФормСДополнительнымиРеквизитами() Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НаборыДополнительныхРеквизитовИСведений.Ссылка КАК Ссылка
|ИЗ
| Справочник.НаборыДополнительныхРеквизитовИСведений КАК НаборыДополнительныхРеквизитовИСведений
|ГДЕ
| НаборыДополнительныхРеквизитовИСведений.Родитель = &Родитель
| И НаборыДополнительныхРеквизитовИСведений.ИмяПредопределенногоНабора = """"";
// Наборы свойств, помеченные к удалению.
Наборы = Новый Соответствие;
ИменаПредопределенныхНаборов = Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений.ПолучитьИменаПредопределенных();
Для Каждого ИмяПредопределенногоНабора Из ИменаПредопределенныхНаборов Цикл
Если СтрНачинаетсяС(ИмяПредопределенногоНабора, "Удалить") Тогда
Попытка
ПредопределенныйНабор = Справочники.НаборыДополнительныхРеквизитовИСведений[ИмяПредопределенногоНабора];
ЭтоГруппа = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ПредопределенныйНабор, "ЭтоГруппа");
Если ЭтоГруппа Тогда
Продолжить;
КонецЕсли;
ДлинаПрефикса = СтрДлина("Удалить");
ИмяНабора = Сред(ИмяПредопределенногоНабора, ДлинаПрефикса + 1, СтрДлина(ИмяПредопределенногоНабора) - ДлинаПрефикса);
ИдентификаторСсылки = Строка(ПредопределенныйНабор.УникальныйИдентификатор());
Если СтрЗаканчиваетсяНа(ИмяНабора, "_Общие") Тогда
Дочерние = Новый Массив;
ИмяНабора = СтрЗаменить(ИмяНабора, "_Общие", "");
НаборРодитель = НаборСвойствПоИмени(ИмяНабора);
Запрос.УстановитьПараметр("Родитель", НаборРодитель);
ДочерниеНаборы = Запрос.Выполнить().Выгрузить();
Для Каждого ДочернийНабор Из ДочерниеНаборы Цикл
ИдентификаторСсылкиДочернего = Строка(ДочернийНабор.Ссылка.УникальныйИдентификатор());
ИдентификаторПолный = ИдентификаторСсылки + ИдентификаторСсылкиДочернего;
КонтрольнаяСумма = ОбщегоНазначения.КонтрольнаяСуммаСтрокой(СтрЗаменить(ИдентификаторПолный, "-", ""));
Дочерние.Добавить("КлючНаборовСвойств" + КонтрольнаяСумма);
КонецЦикла;
Наборы.Вставить(ИмяНабора, Дочерние);
Иначе
КонтрольнаяСумма = ОбщегоНазначения.КонтрольнаяСуммаСтрокой(СтрЗаменить(ИдентификаторСсылки, "-", ""));
Наборы.Вставить(ИмяНабора, "КлючНаборовСвойств" + КонтрольнаяСумма + "," + ИдентификаторСсылки);
КонецЕсли;
Исключение
// Обработка исключения не требуется, отсутствует предопределенный элемент в данных.
Продолжить;
КонецПопытки;
КонецЕсли;
КонецЦикла;
Настройки = УправлениеСвойствамиСлужебный.ЧтениеНастроекИзХранилища(ХранилищеСистемныхНастроек);
Для Каждого Настройка Из Настройки Цикл
КлючОбъекта = Настройка.КлючОбъекта;
КлючОбъектаЧастями = СтрРазделить(КлючОбъекта, ".", Ложь);
Если КлючОбъектаЧастями.Количество() < 3 Тогда
Продолжить;
КонецЕсли;
ИмяНабора = КлючОбъектаЧастями[0] + "_" + КлючОбъектаЧастями[1];
КлючНазначения = Наборы[ИмяНабора];
Если КлючНазначения = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(КлючНазначения) = Тип("Массив") Тогда
Для Каждого Элемент Из КлючНазначения Цикл
УправлениеСвойствамиСлужебный.ПеренестиНастройку(Настройка, Элемент, ИмяНабора);
КонецЦикла;
Иначе
КлючНазначенияЧастями = СтрРазделить(КлючНазначения, ",");
УправлениеСвойствамиСлужебный.ПеренестиНастройку(Настройка, КлючНазначенияЧастями[0], ИмяНабора, КлючНазначенияЧастями[1]);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
#Область УстаревшиеПроцедурыИФункции
// Устарела. Следует использовать ЗначенияСвойств или ЗначенияСвойства.
// Возвращает значения дополнительных свойств объекта.
//
// Параметры:
// ВладелецСвойств - ЛюбаяСсылка - например, СправочникСсылка.Номенклатура, ДокументСсылка.ЗаказПокупателя, ...
// ПолучатьДопРеквизиты - Булево - в результат включать дополнительные реквизиты.
// ПолучатьДопСведения - Булево - в результат включать дополнительные сведения.
// МассивСвойств - Массив из ПланВидовХарактеристикСсылка - дополнительные реквизиты, значения
// которых следует получить.
// - Неопределено - получить значения всех свойств владельца.
// Возвращаемое значение:
// ТаблицаЗначений:
// * Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - свойство владельца.
// * Значение - Произвольный - значения любого типа из описания типов свойства объекта метаданных:
// "Метаданные.ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения.Тип".
//
Функция ПолучитьЗначенияСвойств(ВладелецСвойств,
ПолучатьДопРеквизиты = Истина,
ПолучатьДопСведения = Истина,
МассивСвойств = Неопределено) Экспорт
Возврат ЗначенияСвойств(ВладелецСвойств, ПолучатьДопРеквизиты, ПолучатьДопСведения, МассивСвойств);
КонецФункции
// Устарела. Следует использовать СвойстваОбъекта.
// Возвращает свойства владельца.
//
// Параметры:
// ВладелецСвойств - ЛюбаяСсылка - например, СправочникСсылка.Номенклатура, ДокументСсылка.ЗаказПокупателя, ...
// ПолучатьДопРеквизиты - Булево - в результат включать дополнительные реквизиты.
// ПолучатьДопСведения - Булево - в результат включать дополнительные сведения.
//
// Возвращаемое значение:
// Массив из ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - если есть.
//
Функция ПолучитьСписокСвойств(ВладелецСвойств, ПолучатьДопРеквизиты = Истина, ПолучатьДопСведения = Истина) Экспорт
Возврат СвойстваОбъекта(ВладелецСвойств, ПолучатьДопРеквизиты, ПолучатьДопСведения);
КонецФункции
// Возвращает перечисляемые значения указанного свойства.
//
// Параметры:
// Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - свойство для
// которого нужно получить перечисляемые значения.
//
// Возвращаемое значение:
// Массив из СправочникСсылка.ЗначенияСвойствОбъектов, СправочникСсылка.ЗначенияСвойствОбъектовИерархия - значения
// свойства, если есть.
//
Функция ПолучитьСписокЗначенийСвойств(Свойство) Экспорт
Возврат УправлениеСвойствамиСлужебный.ДополнительныеЗначенияСвойства(Свойство);
КонецФункции
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
////////////////////////////////////////////////////////////////////////////////
// Вспомогательные процедуры и функции.
// Создает основные реквизиты, команды, элементы в форме владельца свойств.
Процедура СоздатьОсновныеОбъектыФормы(Форма, Контекст, СоздатьОписаниеДополнительныхРеквизитов)
ИмяЭлементаДляРазмещения = Контекст.ИмяЭлементаДляРазмещения;
ИмяЭлементаКоманднойПанели = Контекст.ИмяЭлементаКоманднойПанели;
ОтложеннаяИнициализация = Контекст.ОтложеннаяИнициализация;
Реквизиты = Новый Массив;
// Проверка значения функциональной опции "Использование свойств".
ОпцияИспользоватьСвойства = Форма.ПолучитьФункциональнуюОпциюФормы("ИспользоватьДополнительныеРеквизитыИСведения");
РеквизитИспользоватьСвойства = Новый РеквизитФормы("Свойства_ИспользоватьСвойства", Новый ОписаниеТипов("Булево"));
Реквизиты.Добавить(РеквизитИспользоватьСвойства);
РеквизитСкрытьУдаленные = Новый РеквизитФормы("Свойства_СкрытьУдаленные", Новый ОписаниеТипов("Булево"));
Реквизиты.Добавить(РеквизитСкрытьУдаленные);
// Дополнительные параметры подсистемы свойства.
РеквизитПараметрыСвойств = Новый РеквизитФормы("ПараметрыСвойств", Новый ОписаниеТипов());
Реквизиты.Добавить(РеквизитПараметрыСвойств);
Если ОпцияИспользоватьСвойства Тогда
РеквизитИспользоватьДопРеквизиты = Новый РеквизитФормы("Свойства_ИспользоватьДопРеквизиты", Новый ОписаниеТипов("Булево"));
Реквизиты.Добавить(РеквизитИспользоватьДопРеквизиты);
Если СоздатьОписаниеДополнительныхРеквизитов Тогда
// Добавление реквизита содержащего используемые наборы дополнительных реквизитов.
Реквизиты.Добавить(Новый РеквизитФормы(
"Свойства_НаборыДополнительныхРеквизитовОбъекта", Новый ОписаниеТипов("СписокЗначений")));
// Добавление реквизита описания создаваемых реквизитов и элементов формы.
ИмяОписания = "Свойства_ОписаниеДополнительныхРеквизитов";
Реквизиты.Добавить(Новый РеквизитФормы(
ИмяОписания, Новый ОписаниеТипов("ТаблицаЗначений")));
Реквизиты.Добавить(Новый РеквизитФормы(
"ИмяРеквизитаЗначение", Новый ОписаниеТипов("Строка"), ИмяОписания));
Реквизиты.Добавить(Новый РеквизитФормы(
"Свойство", Новый ОписаниеТипов("ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения"),
ИмяОписания));
Реквизиты.Добавить(Новый РеквизитФормы(
"ВладелецДополнительныхЗначений", Новый ОписаниеТипов("ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения"),
ИмяОписания));
Реквизиты.Добавить(Новый РеквизитФормы(
"ТипЗначения", Новый ОписаниеТипов("ОписаниеТипов"), ИмяОписания));
Реквизиты.Добавить(Новый РеквизитФормы(
"МногострочноеПолеВвода", Новый ОписаниеТипов("Число"), ИмяОписания));
Реквизиты.Добавить(Новый РеквизитФормы(
"Удалено", Новый ОписаниеТипов("Булево"), ИмяОписания));
Реквизиты.Добавить(Новый РеквизитФормы(
"ЗаполнятьОбязательно", Новый ОписаниеТипов("Булево"), ИмяОписания));
Реквизиты.Добавить(Новый РеквизитФормы(
"Доступен", Новый ОписаниеТипов("Булево"), ИмяОписания));
Реквизиты.Добавить(Новый РеквизитФормы(
"Виден", Новый ОписаниеТипов("Булево"), ИмяОписания));
Реквизиты.Добавить(Новый РеквизитФормы(
"Наименование", Новый ОписаниеТипов("Строка"), ИмяОписания));
Реквизиты.Добавить(Новый РеквизитФормы(
"ЭлементФормыДобавлен", Новый ОписаниеТипов("Булево"), ИмяОписания));
Реквизиты.Добавить(Новый РеквизитФормы(
"ВыводитьВВидеГиперссылки", Новый ОписаниеТипов("Булево"), ИмяОписания));
Реквизиты.Добавить(Новый РеквизитФормы(
"СтрокаСсылочногоТипа", Новый ОписаниеТипов("Булево"), ИмяОписания));
// Добавление реквизита описания зависимых реквизитов.
ТаблицаЗависимыхРеквизитов = "Свойства_ОписаниеЗависимыхДополнительныхРеквизитов";
Реквизиты.Добавить(Новый РеквизитФормы(
ТаблицаЗависимыхРеквизитов, Новый ОписаниеТипов("ТаблицаЗначений")));
Реквизиты.Добавить(Новый РеквизитФормы(
"ИмяРеквизитаЗначение", Новый ОписаниеТипов("Строка"), ТаблицаЗависимыхРеквизитов));
Реквизиты.Добавить(Новый РеквизитФормы(
"Доступен", Новый ОписаниеТипов("Булево"), ТаблицаЗависимыхРеквизитов));
Реквизиты.Добавить(Новый РеквизитФормы(
"УсловиеДоступности", Новый ОписаниеТипов(), ТаблицаЗависимыхРеквизитов));
Реквизиты.Добавить(Новый РеквизитФормы(
"Виден", Новый ОписаниеТипов("Булево"), ТаблицаЗависимыхРеквизитов));
Реквизиты.Добавить(Новый РеквизитФормы(
"УсловиеВидимости", Новый ОписаниеТипов(), ТаблицаЗависимыхРеквизитов));
Реквизиты.Добавить(Новый РеквизитФормы(
"ЗаполнятьОбязательно", Новый ОписаниеТипов("Булево"), ТаблицаЗависимыхРеквизитов));
Реквизиты.Добавить(Новый РеквизитФормы(
"УсловиеОбязательностиЗаполнения", Новый ОписаниеТипов(), ТаблицаЗависимыхРеквизитов));
Реквизиты.Добавить(Новый РеквизитФормы(
"ВыводитьВВидеГиперссылки", Новый ОписаниеТипов("Булево"), ТаблицаЗависимыхРеквизитов));
// Добавление реквизита содержащего элементы создаваемых групп дополнительных реквизитов.
Реквизиты.Добавить(Новый РеквизитФормы(
"Свойства_ЭлементыГруппДополнительныхРеквизитов", Новый ОписаниеТипов("СписокЗначений")));
// Добавление реквизита с именем элемента в котором будут размещаться поля ввода.
Реквизиты.Добавить(Новый РеквизитФормы(
"Свойства_ИмяЭлементаДляРазмещения", Новый ОписаниеТипов()));
// Добавление команды формы, если установлена роль "ДобавлениеИзменениеДополнительныхРеквизитовИСведений" или это
// полноправный пользователь.
Если ПравоДоступа("Изменение", Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений) Тогда
// Добавление команды.
Команда = Форма.Команды.Добавить("РедактироватьСоставДополнительныхРеквизитов");
Команда.Заголовок = НСтр("ru = 'Изменить состав дополнительных реквизитов'");
Команда.Действие = "Подключаемый_СвойстваВыполнитьКоманду";
Команда.Подсказка = НСтр("ru = 'Изменить состав дополнительных реквизитов'");
Команда.Картинка = БиблиотекаКартинок.НастройкаСписка;
Кнопка = Форма.Элементы.Добавить(
"РедактироватьСоставДополнительныхРеквизитов",
Тип("КнопкаФормы"),
?(ИмяЭлементаКоманднойПанели = "",
Форма.КоманднаяПанель,
Форма.Элементы[ИмяЭлементаКоманднойПанели]));
Кнопка.ТолькоВоВсехДействиях = Истина;
Кнопка.ИмяКоманды = "РедактироватьСоставДополнительныхРеквизитов";
КонецЕсли;
Команда = Форма.Команды.Добавить("РедактироватьГиперссылкуРеквизита");
Команда.Заголовок = НСтр("ru = 'Начать/закончить редактирование'");
Команда.Действие = "Подключаемый_СвойстваВыполнитьКоманду";
Команда.Подсказка = НСтр("ru = 'Начать/закончить редактирование'");
Команда.Картинка = БиблиотекаКартинок.Изменить;
Команда.Отображение = ОтображениеКнопки.Картинка;
КонецЕсли;
КонецЕсли;
Форма.ИзменитьРеквизиты(Реквизиты);
Форма.Свойства_ИспользоватьСвойства = ОпцияИспользоватьСвойства;
Форма.ПараметрыСвойств = Новый Структура;
Если ОтложеннаяИнициализация Тогда
// Если свойства не используются, признак выполнения отложенной инициализации
// взводится в истину.
Значение = ?(ОпцияИспользоватьСвойства, Ложь, Истина);
Форма.ПараметрыСвойств.Вставить("ВыполненаОтложеннаяИнициализация", Значение);
КонецЕсли;
Если ОпцияИспользоватьСвойства Тогда
Форма.Свойства_ИспользоватьДопРеквизиты = СоздатьОписаниеДополнительныхРеквизитов;
КонецЕсли;
Если ОпцияИспользоватьСвойства И СоздатьОписаниеДополнительныхРеквизитов Тогда
Форма.Свойства_ИмяЭлементаДляРазмещения = ИмяЭлементаДляРазмещения;
КонецЕсли;
// Если дополнительные реквизиты расположены на отдельной странице, включена
// отложенная инициализация и свойства включены, то в страницу размещается пустая декорация.
// Декорация удаляется автоматически при переключении на закладку.
// Также блокируется возможность перемещения дополнительных реквизитов из группы.
Если ОпцияИспользоватьСвойства
И ОтложеннаяИнициализация
И ИмяЭлементаДляРазмещения <> "" Тогда
Форма.ПараметрыСвойств.Вставить("КоллекцияДекораций");
Форма.ПараметрыСвойств.КоллекцияДекораций = Новый Массив;
Форма.ПараметрыСвойств.Вставить("ДобавленаПустаяДекорация", Истина);
Если ТипЗнч(ИмяЭлементаДляРазмещения ) = Тип("СписокЗначений") Тогда
Индекс = 0;
Для Каждого ГруппаРазмещения Из ИмяЭлементаДляРазмещения Цикл
ПодготовитьФормуДляОтложеннойИнициализации(Форма, ГруппаРазмещения.Представление, Индекс);
Индекс = Индекс + 1;
КонецЦикла;
Иначе
ПодготовитьФормуДляОтложеннойИнициализации(Форма, ИмяЭлементаДляРазмещения, "");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Добавляет на форму защиту-предупреждение от перемещения группы дополнительных реквизитов
// при включенной отложенной инициализации.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения:
// * ПараметрыСвойств - Структура:
// ** КоллекцияДекораций - Массив
// ИмяЭлементаДляРазмещения - Строка
// Индекс - Число
//
Процедура ПодготовитьФормуДляОтложеннойИнициализации(Форма, ИмяЭлементаДляРазмещения, Индекс)
ГруппаФормы = Форма.Элементы[ИмяЭлементаДляРазмещения];
Если ГруппаФормы.Вид <> ВидГруппыФормы.Страница Тогда
Родитель = СтраницаРодитель(ГруппаФормы);
Иначе
Родитель = ГруппаФормы;
КонецЕсли;
Если Родитель <> Неопределено
И Не Форма.ПараметрыСвойств.Свойство(Родитель.Имя) Тогда
ИмяДекорации = "Свойства_ПустаяДекорация" + Индекс;
Форма.ПараметрыСвойств.КоллекцияДекораций.Добавить(ИмяДекорации);
Декорация = Форма.Элементы.Добавить(ИмяДекорации, Тип("ДекорацияФормы"), ГруппаФормы);
ГруппаСтраниц = Родитель.Родитель;
ЗаголовокСтраницы = ?(ЗначениеЗаполнено(Родитель.Заголовок), Родитель.Заголовок, Родитель.Имя);
ЗаголовокГруппыСтраниц = ?(ЗначениеЗаполнено(ГруппаСтраниц.Заголовок), ГруппаСтраниц.Заголовок, ГруппаСтраниц.Имя);
ПредупреждениеОРазмещении = НСтр("ru = 'Для отображения дополнительных реквизитов разместите группу ""%1"" не первым элементом (после любой другой группы) в группе ""%2"" (меню Еще - Изменить форму).'");
ПредупреждениеОРазмещении = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ПредупреждениеОРазмещении,
ЗаголовокСтраницы, ЗаголовокГруппыСтраниц);
ТекстПодсказки = НСтр("ru = 'Также можно установить стандартные настройки формы:
| • в меню Еще выбрать пункт Изменить форму...;
| • в открывшейся форме ""Настройка формы"" в меню Еще выбрать пункт ""Установить стандартные настройки"".'");
Декорация.ОтображениеПодсказки = ОтображениеПодсказки.Кнопка;
Декорация.Заголовок = ПредупреждениеОРазмещении;
Декорация.Подсказка = ТекстПодсказки;
Декорация.ЦветТекста = ЦветаСтиля.ПоясняющийОшибкуТекст;
// Страница, на которой размещаются дополнительные реквизиты.
Форма.ПараметрыСвойств.Вставить(Родитель.Имя);
КонецЕсли;
ГруппаФормы.РазрешитьИзменениеСостава = Ложь;
КонецПроцедуры
Функция СтраницаРодитель(ГруппаФормы)
Родитель = ГруппаФормы.Родитель;
Если ТипЗнч(Родитель) = Тип("ГруппаФормы") Тогда
Родитель.РазрешитьИзменениеСостава = Ложь;
Если Родитель.Вид = ВидГруппыФормы.Страница Тогда
Возврат Родитель;
Иначе
Возврат СтраницаРодитель(Родитель);
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции
Процедура ОбновитьКлючНазначенияФормы(Форма, КлючНазначения)
Если КлючНазначения = Неопределено Тогда
КлючНазначения = КлючНаборовСвойств(Форма.Свойства_НаборыДополнительныхРеквизитовОбъекта);
КонецЕсли;
Если ПустаяСтрока(КлючНазначения) Тогда
Возврат;
КонецЕсли;
НачалоКлюча = "КлючНаборовСвойств";
КлючНаборовСвойств = НачалоКлюча + Лев(КлючНазначения + "00000000000000000000000000000000", 32);
НовыйКлюч = НовыйКлючНазначения(Форма.КлючНазначенияИспользования, НачалоКлюча, КлючНаборовСвойств);
Если НовыйКлюч <> Неопределено Тогда
Форма.КлючНазначенияИспользования = НовыйКлюч;
КонецЕсли;
КонецПроцедуры
Функция РезультатВычисленияУсловия(Форма, ОписаниеОбъекта, Параметры)
ПараметрыУсловия = Новый Структура;
ПараметрыУсловия.Вставить("ЗначенияПараметров", Параметры.ЗначенияПараметров);
ПараметрыУсловия.Вставить("Форма", Форма);
ПараметрыУсловия.Вставить("ОписаниеОбъекта", ОписаниеОбъекта);
Возврат ОбщегоНазначения.ВычислитьВБезопасномРежиме(Параметры.КодУсловия, ПараметрыУсловия);
КонецФункции
Функция НовыйКлючНазначения(ТекущийКлюч, НачалоКлюча, КлючНаборовСвойств)
Позиция = СтрНайти(ТекущийКлюч, НачалоКлюча);
НовыйКлючНазначения = Неопределено;
Если Позиция = 0 Тогда
НовыйКлючНазначения = ТекущийКлюч + КлючНаборовСвойств;
ИначеЕсли СтрНайти(ТекущийКлюч, КлючНаборовСвойств) = 0 Тогда
НовыйКлючНазначения = Лев(ТекущийКлюч, Позиция - 1) + КлючНаборовСвойств
+ Сред(ТекущийКлюч, Позиция + СтрДлина(НачалоКлюча) + 32);
КонецЕсли;
Возврат НовыйКлючНазначения;
КонецФункции
Функция КлючНаборовСвойств(Наборы)
ИдентификаторыНаборов = Новый СписокЗначений;
Для каждого ЭлементСписка Из Наборы Цикл
ИдентификаторыНаборов.Добавить(Строка(ЭлементСписка.Значение.УникальныйИдентификатор()));
КонецЦикла;
ИдентификаторыНаборов.СортироватьПоЗначению();
СтрокаИдентификаторов = "";
Для каждого ЭлементСписка Из ИдентификаторыНаборов Цикл
СтрокаИдентификаторов = СтрокаИдентификаторов + СтрЗаменить(ЭлементСписка.Значение, "-", "");
КонецЦикла;
Возврат ОбщегоНазначения.КонтрольнаяСуммаСтрокой(СтрокаИдентификаторов);
КонецФункции
Функция РеквизитДоступенПоФункциональнымОпциям(ОписаниеСвойства)
ОбъектДоступен = Истина;
Для Каждого Тип Из ОписаниеСвойства.ТипЗначения.Типы() Цикл
ОбъектМетаданных = Метаданные.НайтиПоТипу(Тип);
Если ОбъектМетаданных = Неопределено Тогда
Продолжить;
КонецЕсли;
ОбъектДоступен = ОбщегоНазначения.ОбъектМетаданныхДоступенПоФункциональнымОпциям(ОбъектМетаданных);
Если ОбъектДоступен Тогда
Прервать; // Если хоть один тип доступен, то реквизит не скрывается.
КонецЕсли;
КонецЦикла;
Возврат ОбъектДоступен;
КонецФункции
Функция ИспользуютсяСвойства(Форма, ДополнительныеПараметры)
Если Не ПравоДоступа("Чтение", Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений) Тогда
ОтключитьДополнительныеРеквизитыНаФорме(Форма, ДополнительныеПараметры);
Возврат Ложь;
КонецЕсли;
Если ДополнительныеПараметры <> Неопределено
И ДополнительныеПараметры.Свойство("ПроизвольныйОбъект")
И ДополнительныеПараметры.ПроизвольныйОбъект Тогда
Возврат Истина;
КонецЕсли;
Если ДополнительныеПараметры <> Неопределено
И ДополнительныеПараметры.Свойство("Объект") Тогда
ОписаниеОбъекта = ДополнительныеПараметры.Объект;
Иначе
ОписаниеОбъекта = Форма.Объект;
КонецЕсли;
ТипОбъекта = ТипЗнч(ОписаниеОбъекта.Ссылка);
МетаданныеОбъекта = Метаданные.НайтиПоТипу(ТипОбъекта);
ТабличнаяЧасть = МетаданныеОбъекта.ТабличныеЧасти.Найти("ДополнительныеРеквизиты");
Если ТабличнаяЧасть = Неопределено Тогда
ОтключитьДополнительныеРеквизитыНаФорме(Форма, ДополнительныеПараметры);
Возврат Ложь;
КонецЕсли;
Если ОбщегоНазначения.ВидОбъектаПоТипу(ТипОбъекта) = "Справочник" Тогда
Если Не МетаданныеОбъекта.Иерархический
Или МетаданныеОбъекта.ВидИерархии <> Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда
ЭтоГруппа = Ложь;
ИначеЕсли ЗначениеЗаполнено(ОписаниеОбъекта.Ссылка) Тогда
ЭтоГруппа = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ОписаниеОбъекта.Ссылка, "ЭтоГруппа");
ИначеЕсли ОписаниеОбъекта.Свойство("ЭтоГруппа") Тогда
ЭтоГруппа = ОписаниеОбъекта.ЭтоГруппа;
Иначе
ЭтоГруппа = Ложь;
КонецЕсли;
Если ЭтоГруппа И ТабличнаяЧасть.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента
Или Не ЭтоГруппа И ТабличнаяЧасть.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы Тогда
ОтключитьДополнительныеРеквизитыНаФорме(Форма, ДополнительныеПараметры);
Возврат Ложь;
КонецЕсли;
КонецЕсли;
ПолноеИмя = МетаданныеОбъекта.ПолноеИмя();
МассивИмениФормы = СтрРазделить(ПолноеИмя, ".");
ИмяЭлемента = МассивИмениФормы[0] + "_" + МассивИмениФормы[1];
НаборСвойств = НаборСвойствПоИмени(ИмяЭлемента);
Если НаборСвойств = Неопределено Тогда
НаборСвойств = Справочники.НаборыДополнительныхРеквизитовИСведений[ИмяЭлемента];
КонецЕсли;
ИспользуютсяСвойства = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(НаборСвойств, "Используется");
Если Не ИспользуютсяСвойства Тогда
ОтключитьДополнительныеРеквизитыНаФорме(Форма, ДополнительныеПараметры);
КонецЕсли;
Возврат ИспользуютсяСвойства;
КонецФункции
Процедура ОтключитьДополнительныеРеквизитыНаФорме(Форма, ДополнительныеПараметры)
МассивРеквизитов = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(
Новый РеквизитФормы("Свойства_ИспользоватьСвойства", Новый ОписаниеТипов("Булево")));
ПараметрыСвойствДобавлены = Ложь;
Если ТипЗнч(ДополнительныеПараметры) = Тип("Структура") Тогда
Если ДополнительныеПараметры.Свойство("ИмяЭлементаДляРазмещения") Тогда
Если ТипЗнч(ДополнительныеПараметры.ИмяЭлементаДляРазмещения) = Тип("СписокЗначений") Тогда
Для Каждого ЭлементСписка Из ДополнительныеПараметры.ИмяЭлементаДляРазмещения Цикл
Форма.Элементы[ЭлементСписка.Представление].Видимость = Ложь;
КонецЦикла;
Иначе
Форма.Элементы[ДополнительныеПараметры.ИмяЭлементаДляРазмещения].Видимость = Ложь;
КонецЕсли;
КонецЕсли;
Если ДополнительныеПараметры.Свойство("ОтложеннаяИнициализация") Тогда
РеквизитПараметрыСвойств = Новый РеквизитФормы("ПараметрыСвойств", Новый ОписаниеТипов());
МассивРеквизитов.Добавить(РеквизитПараметрыСвойств);
ПараметрыСвойствДобавлены = Истина;
КонецЕсли;
КонецЕсли;
Форма.ИзменитьРеквизиты(МассивРеквизитов);
Форма.Свойства_ИспользоватьСвойства = Ложь;
Если ПараметрыСвойствДобавлены Тогда
Форма.ПараметрыСвойств = Новый Структура;
Форма.ПараметрыСвойств.Вставить("ВыполненаОтложеннаяИнициализация", Истина);
КонецЕсли;
КонецПроцедуры
Функция ПредставлениеЗначения(Значение, КодЯзыка, ФорматСвойства)
Если Значение = Неопределено Тогда
Возврат Значение;
КонецЕсли;
Если ТипЗнч(Значение) = Тип("Строка") Тогда
Представление = Значение;
ИначеЕсли ТипЗнч(Значение) = Тип("Булево")
Или ТипЗнч(Значение) = Тип("Дата")
Или ТипЗнч(Значение) = Тип("Число") Тогда
Если ЗначениеЗаполнено(ФорматСвойства) Тогда
Если СтрНайти(ФорматСвойства, "Л=''") > 0 Тогда
ФорматСвойства = СтрЗаменить(ФорматСвойства, "Л=''", "Л=" + КодЯзыка);
ИначеЕсли СтрНайти(ФорматСвойства, "Л=") = 0 Тогда
ФорматСвойства = "Л=" + КодЯзыка + ";" + ФорматСвойства;
КонецЕсли;
Представление = Формат(Значение, ФорматСвойства);
Иначе
Представление = Формат(Значение, "Л=" + КодЯзыка);
КонецЕсли;
Иначе
Представление = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Значение, "Наименование", , КодЯзыка);
КонецЕсли;
Возврат Представление;
КонецФункции
Функция ФорматСвойства(Свойство)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Свойство", Свойство);
Запрос.Текст =
"ВЫБРАТЬ
| ДополнительныеРеквизитыИСведения.ФорматСвойства КАК ФорматСвойства
|ИЗ
| ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
|ГДЕ
| &Условие";
Если ТипЗнч(Свойство) = Тип("Строка") Тогда
Запрос.Текст = СтрЗаменить(Запрос.Текст, "&Условие", "ДополнительныеРеквизитыИСведения.Имя = &Свойство");
Иначе
Запрос.Текст = СтрЗаменить(Запрос.Текст, "&Условие", "ДополнительныеРеквизитыИСведения.Ссылка = &Свойство");
КонецЕсли;
Результат = Запрос.Выполнить().Выгрузить();
Если Результат.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
Возврат Результат[0].ФорматСвойства;
КонецФункции
#КонецОбласти