10303 lines
677 KiB
Plaintext
10303 lines
677 KiB
Plaintext
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
// Copyright (c) 2024, ООО 1С-Софт
|
||
// Все права защищены. Эта программа и сопроводительные материалы предоставляются
|
||
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
|
||
// Текст лицензии доступен по ссылке:
|
||
// https://creativecommons.org/licenses/by/4.0/legalcode
|
||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
#Область ПрограммныйИнтерфейс
|
||
|
||
#Область ОповещениеПользователя
|
||
|
||
// Формирует и выводит сообщение, которое может быть связано с элементом управления формы.
|
||
//
|
||
// В фоновом задании длительной операции, если вызов выполнен вне транзакции,
|
||
// сообщение записывается в служебный регистр и отправляется сразу на клиент,
|
||
// если подключена система взаимодействия.
|
||
// В конце фонового задания длительной операции, а также при отправке прогресса,
|
||
// все сообщения извлекаются из очереди сообщений фонового задания,
|
||
// записываются в служебный регистр и отправляются сразу на клиент,
|
||
// если подключена система взаимодействия.
|
||
//
|
||
// АПК:142-выкл 4 необязательных параметра для совместимости
|
||
// с устаревшей процедурой ОбщегоНазначенияКлиентСервер.СообщитьПользователю.
|
||
//
|
||
// Параметры:
|
||
// ТекстСообщенияПользователю - Строка - текст сообщения.
|
||
// КлючДанных - Произвольный - объект, ссылка или ключ записи информационной базы, к которому это сообщение относится.
|
||
// Поле - Строка - наименование реквизита формы.
|
||
// ПутьКДанным - Строка - путь к данным (путь к реквизиту формы).
|
||
// Отказ - Булево - выходной параметр, всегда устанавливается в значение Истина.
|
||
//
|
||
// Пример:
|
||
//
|
||
// 1. Для вывода сообщения у поля управляемой формы, связанного с реквизитом объекта:
|
||
// ОбщегоНазначения.СообщитьПользователю(
|
||
// НСтр("ru = 'Сообщение об ошибке.'"), ,
|
||
// "ПолеВРеквизитеФормыОбъект",
|
||
// "Объект");
|
||
//
|
||
// Альтернативный вариант использования в форме объекта:
|
||
// ОбщегоНазначения.СообщитьПользователю(
|
||
// НСтр("ru = 'Сообщение об ошибке.'"), ,
|
||
// "Объект.ПолеВРеквизитеФормыОбъект");
|
||
//
|
||
// 2. Для вывода сообщения рядом с полем управляемой формы, связанным с реквизитом формы:
|
||
// ОбщегоНазначения.СообщитьПользователю(
|
||
// НСтр("ru = 'Сообщение об ошибке.'"), ,
|
||
// "ИмяРеквизитаФормы");
|
||
//
|
||
// 3. Для вывода сообщения связанного с объектом информационной базы:
|
||
// ОбщегоНазначения.СообщитьПользователю(
|
||
// НСтр("ru = 'Сообщение об ошибке.'"), ОбъектИнформационнойБазы, "Ответственный",,Отказ);
|
||
//
|
||
// 4. Для вывода сообщения по ссылке на объект информационной базы:
|
||
// ОбщегоНазначения.СообщитьПользователю(
|
||
// НСтр("ru = 'Сообщение об ошибке.'"), Ссылка, , , Отказ);
|
||
//
|
||
// Случаи некорректного использования:
|
||
// 1. Передача одновременно параметров КлючДанных и ПутьКДанным.
|
||
// 2. Передача в параметре КлючДанных значения типа отличного от допустимого.
|
||
// 3. Установка ссылки без установки поля (и/или пути к данным).
|
||
//
|
||
Процедура СообщитьПользователю(Знач ТекстСообщенияПользователю, Знач КлючДанных = Неопределено, Знач Поле = "",
|
||
Знач ПутьКДанным = "", Отказ = Ложь) Экспорт
|
||
|
||
ЭтоОбъект = Ложь;
|
||
|
||
Если КлючДанных <> Неопределено
|
||
И XMLТипЗнч(КлючДанных) <> Неопределено Тогда
|
||
|
||
ТипЗначенияСтрокой = XMLТипЗнч(КлючДанных).ИмяТипа;
|
||
ЭтоОбъект = СтрНайти(ТипЗначенияСтрокой, "Object.") > 0;
|
||
КонецЕсли;
|
||
|
||
Сообщение = ОбщегоНазначенияСлужебныйКлиентСервер.СообщениеПользователю(ТекстСообщенияПользователю,
|
||
КлючДанных, Поле, ПутьКДанным, Отказ, ЭтоОбъект);
|
||
|
||
#Если НЕ МобильныйАвтономныйСервер Тогда
|
||
Если СтандартныеПодсистемыПовтИсп.ЭтоСеансДлительнойОперации()
|
||
И Не ТранзакцияАктивна() Тогда
|
||
|
||
ДлительныеОперации.ОтправитьОповещениеКлиенту("СообщениеПользователю", Сообщение);
|
||
Иначе
|
||
Сообщение.Сообщить();
|
||
КонецЕсли;
|
||
#Иначе
|
||
Сообщение.Сообщить();
|
||
#КонецЕсли
|
||
|
||
КонецПроцедуры
|
||
|
||
// АПК:142-вкл
|
||
|
||
#КонецОбласти
|
||
|
||
#Если НЕ МобильныйАвтономныйСервер Тогда
|
||
|
||
#Область ДанныеВБазе
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
// Общие процедуры и функции для работы с данными в базе.
|
||
|
||
// Возвращает структуру, содержащую значения реквизитов, прочитанные из информационной базы по ссылке на объект.
|
||
// Рекомендуется использовать вместо обращения к реквизитам объекта через точку от ссылки на объект
|
||
// для быстрого чтения отдельных реквизитов объекта из базы данных.
|
||
//
|
||
// Если необходимо зачитать реквизит независимо от прав текущего пользователя,
|
||
// то следует использовать предварительный переход в привилегированный режим.
|
||
//
|
||
// Параметры:
|
||
// Ссылка - ЛюбаяСсылка - объект, значения реквизитов которого необходимо получить.
|
||
// - Строка - полное имя предопределенного элемента, значения реквизитов которого необходимо получить.
|
||
// Реквизиты - Строка - имена реквизитов, перечисленные через запятую, в формате
|
||
// требований к свойствам структуры.
|
||
// Например, "Код, Наименование, Родитель".
|
||
// - Структура
|
||
// - ФиксированнаяСтруктура - в качестве ключа передается
|
||
// псевдоним поля для возвращаемой структуры с результатом, а в качестве
|
||
// значения (опционально) фактическое имя поля в таблице.
|
||
// Если ключ задан, а значение не определено, то имя поля берется из ключа.
|
||
// Допускается указание имени поля через точку, но при этом параметр КодЯзыка для такого поля
|
||
// учитываться не будет.
|
||
// - Массив из Строка
|
||
// - ФиксированныйМассив из Строка - имена реквизитов в формате требований к свойствам структуры.
|
||
// ВыбратьРазрешенные - Булево - если Истина, то запрос к объекту выполняется с учетом прав пользователя;
|
||
// если есть ограничение на уровне записей, то все реквизиты вернутся со
|
||
// значением Неопределено; если нет прав для работы с таблицей, то возникнет исключение;
|
||
// если Ложь, то возникнет исключение при отсутствии прав на таблицу
|
||
// или любой из реквизитов.
|
||
// КодЯзыка - Строка - код языка для мультиязычного реквизита. Значение по умолчанию - основной язык конфигурации.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Структура - содержит имена (ключи) и значения затребованных реквизитов.
|
||
// Если в параметр Реквизиты передана пустая строка, то возвращается пустая структура.
|
||
// Если в параметр Ссылка передана пустая ссылка, то возвращается структура,
|
||
// соответствующая именам реквизитов со значениями Неопределено.
|
||
// Если в параметр Ссылка передана ссылка несуществующего объекта (битая ссылка),
|
||
// то все реквизиты вернутся со значением Неопределено.
|
||
//
|
||
Функция ЗначенияРеквизитовОбъекта(Ссылка, Знач Реквизиты, ВыбратьРазрешенные = Ложь, Знач КодЯзыка = Неопределено) Экспорт
|
||
|
||
// Если передано имя предопределенного.
|
||
Если ТипЗнч(Ссылка) = Тип("Строка") Тогда
|
||
|
||
ПолноеИмяПредопределенногоЭлемента = Ссылка;
|
||
|
||
// Вычисление ссылки по имени предопределенного.
|
||
// - дополнительно выполняет проверку метаданных предопределенного, выполняется предварительно.
|
||
Попытка
|
||
Ссылка = ПредопределенныйЭлемент(ПолноеИмяПредопределенногоЭлемента);
|
||
Исключение
|
||
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверный первый параметр %1 в функции %2:
|
||
|%3'"), "Ссылка", "ОбщегоНазначения.ЗначенияРеквизитовОбъекта",
|
||
ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
|
||
ВызватьИсключение(ТекстОшибки, КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецПопытки;
|
||
|
||
// Разбор полного имени предопределенного.
|
||
ЧастиПолногоИмени = СтрРазделить(ПолноеИмяПредопределенногоЭлемента, ".");
|
||
ПолноеИмяОбъектаМетаданных = ЧастиПолногоИмени[0] + "." + ЧастиПолногоИмени[1];
|
||
|
||
// Если предопределенный не создан в ИБ, то требуется выполнить проверку доступа к объекту.
|
||
// В других сценариях проверка доступа выполняется в момент исполнения запроса.
|
||
Если Ссылка = Неопределено Тогда
|
||
МетаданныеОбъекта = ОбъектМетаданныхПоПолномуИмени(ПолноеИмяОбъектаМетаданных);
|
||
Если Не ПравоДоступа("Чтение", МетаданныеОбъекта) Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Недостаточно прав для работы с таблицей ""%1""'"), ПолноеИмяОбъектаМетаданных),
|
||
КатегорияОшибки.НарушениеПравДоступа);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Иначе // Если передана ссылка.
|
||
|
||
Попытка
|
||
ПолноеИмяОбъектаМетаданных = Ссылка.Метаданные().ПолноеИмя();
|
||
Исключение
|
||
ВызватьИсключение (СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверный первый параметр %1 в функции %2:
|
||
|Значение должно быть ссылкой или именем предопределенного элемента.'"),
|
||
"Ссылка", "ОбщегоНазначения.ЗначенияРеквизитовОбъекта"),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецПопытки;
|
||
|
||
КонецЕсли;
|
||
|
||
// Разбор реквизитов, если второй параметр Строка.
|
||
Если ТипЗнч(Реквизиты) = Тип("Строка") Тогда
|
||
Если ПустаяСтрока(Реквизиты) Тогда
|
||
Возврат Новый Структура;
|
||
КонецЕсли;
|
||
|
||
Реквизиты = СтрРазделить(Реквизиты, ",", Ложь);
|
||
Для Индекс = 0 По Реквизиты.ВГраница() Цикл
|
||
Реквизиты[Индекс] = СокрЛП(Реквизиты[Индекс]);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
МультиязычныеРеквизиты = Новый Соответствие;
|
||
СуффиксЯзыка = "";
|
||
Если ЗначениеЗаполнено(КодЯзыка) Тогда
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
|
||
МодульМультиязычностьСервер = ОбщийМодуль("МультиязычностьСервер");
|
||
СуффиксЯзыка = МодульМультиязычностьСервер.СуффиксЯзыка(КодЯзыка);
|
||
Если ЗначениеЗаполнено(СуффиксЯзыка) Тогда
|
||
МультиязычныеРеквизиты = МодульМультиязычностьСервер.МультиязычныеРеквизитыОбъекта(Ссылка);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
// Приведение реквизитов к единому формату.
|
||
СтруктураПолей = Новый Структура;
|
||
Если ТипЗнч(Реквизиты) = Тип("Структура")
|
||
Или ТипЗнч(Реквизиты) = Тип("ФиксированнаяСтруктура") Тогда
|
||
|
||
Для Каждого КлючИЗначение Из Реквизиты Цикл
|
||
СтруктураПолей.Вставить(КлючИЗначение.Ключ, СокрЛП(КлючИЗначение.Значение));
|
||
КонецЦикла;
|
||
|
||
ИначеЕсли ТипЗнч(Реквизиты) = Тип("Массив")
|
||
Или ТипЗнч(Реквизиты) = Тип("ФиксированныйМассив") Тогда
|
||
|
||
Для Каждого Реквизит Из Реквизиты Цикл
|
||
Реквизит = СокрЛП(Реквизит);
|
||
Попытка
|
||
ПсевдонимПоля = СтрЗаменить(Реквизит, ".", "");
|
||
СтруктураПолей.Вставить(ПсевдонимПоля, Реквизит);
|
||
Исключение
|
||
// Если псевдоним не является ключом.
|
||
|
||
// Поиск ошибки доступности полей.
|
||
Результат = ПроверитьСуществованиеРеквизитовОбъекта(ПолноеИмяОбъектаМетаданных, Реквизиты);
|
||
Если Результат.Ошибка Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверный второй параметр %1 в функции %2: %3'"),
|
||
"Реквизиты", "ОбщегоНазначения.ЗначенияРеквизитовОбъекта", Результат.ОписаниеОшибки),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
// Не удалось распознать ошибку, проброс первичной ошибки.
|
||
ВызватьИсключение;
|
||
|
||
КонецПопытки;
|
||
КонецЦикла;
|
||
Иначе
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверный тип второго параметра %1 в функции %2: %3.'"),
|
||
"Реквизиты", "ОбщегоНазначения.ЗначенияРеквизитовОбъекта", Строка(ТипЗнч(Реквизиты))),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
// Подготовка результата (после выполнения запроса переопределится).
|
||
Результат = Новый Структура;
|
||
|
||
// Формирование текста запроса к выбираемым полям.
|
||
ТекстЗапросаПолей = "";
|
||
Для каждого КлючИЗначение Из СтруктураПолей Цикл
|
||
|
||
ИмяПоля = ?(ЗначениеЗаполнено(КлючИЗначение.Значение),
|
||
КлючИЗначение.Значение,
|
||
КлючИЗначение.Ключ);
|
||
ПсевдонимПоля = КлючИЗначение.Ключ;
|
||
|
||
Если МультиязычныеРеквизиты[ИмяПоля] <> Неопределено Тогда
|
||
ИмяПоля = ИмяПоля + СуффиксЯзыка;
|
||
КонецЕсли;
|
||
|
||
ТекстЗапросаПолей =
|
||
ТекстЗапросаПолей + ?(ПустаяСтрока(ТекстЗапросаПолей), "", ",") + "
|
||
| " + ИмяПоля + " КАК " + ПсевдонимПоля;
|
||
|
||
// Предварительное добавление поля по псевдониму в возвращаемый результат.
|
||
Результат.Вставить(ПсевдонимПоля);
|
||
|
||
КонецЦикла;
|
||
|
||
// Если предопределенного нет в ИБ.
|
||
// - приведение результата к отсутствию объекта в ИБ или передаче пустой ссылки.
|
||
Если Ссылка = Неопределено Тогда
|
||
Возврат Результат;
|
||
КонецЕсли;
|
||
|
||
Если Тип("Структура") = ТипЗнч(Реквизиты)
|
||
Или Тип("ФиксированнаяСтруктура") = ТипЗнч(Реквизиты) Тогда
|
||
Реквизиты = Новый Массив;
|
||
Для Каждого КлючИЗначение Из СтруктураПолей Цикл
|
||
ИмяПоля = ?(ЗначениеЗаполнено(КлючИЗначение.Значение),
|
||
КлючИЗначение.Значение,
|
||
КлючИЗначение.Ключ);
|
||
Реквизиты.Добавить(ИмяПоля);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
РеквизитыЧерезТочку = Новый Массив;
|
||
Для Индекс = -Реквизиты.ВГраница() По 0 Цикл
|
||
ИмяПоля = Реквизиты[-Индекс];
|
||
Если СтрНайти(ИмяПоля, ".") Тогда
|
||
РеквизитыЧерезТочку.Добавить(ИмяПоля);
|
||
Реквизиты.Удалить(-Индекс);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если ЗначениеЗаполнено(Реквизиты) Тогда
|
||
ЗначенияРеквизитовОбъекта = ЗначенияРеквизитовОбъектов(ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Ссылка), Реквизиты, ВыбратьРазрешенные, КодЯзыка)[Ссылка];
|
||
Если ЗначенияРеквизитовОбъекта <> Неопределено Тогда
|
||
Для Каждого КлючИЗначение Из СтруктураПолей Цикл
|
||
ИмяПоля = ?(ЗначениеЗаполнено(КлючИЗначение.Значение),
|
||
КлючИЗначение.Значение,
|
||
КлючИЗначение.Ключ);
|
||
Если СтрНайти(ИмяПоля, ".") = 0 И ЗначенияРеквизитовОбъекта.Свойство(ИмяПоля) Тогда
|
||
Результат[КлючИЗначение.Ключ] = ЗначенияРеквизитовОбъекта[ИмяПоля];
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Если Не ЗначениеЗаполнено(РеквизитыЧерезТочку) Тогда
|
||
Возврат Результат;
|
||
КонецЕсли;
|
||
|
||
Реквизиты = РеквизитыЧерезТочку;
|
||
|
||
ТекстЗапроса =
|
||
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
|
||
|&ТекстЗапросаПолей
|
||
|ИЗ
|
||
| &ПолноеИмяОбъектаМетаданных КАК ПсевдонимЗаданнойТаблицы
|
||
|ГДЕ
|
||
| ПсевдонимЗаданнойТаблицы.Ссылка = &Ссылка";
|
||
|
||
Если Не ВыбратьРазрешенные Тогда
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "РАЗРЕШЕННЫЕ", ""); // @Query-part-1
|
||
КонецЕсли;
|
||
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ТекстЗапросаПолей", ТекстЗапросаПолей);
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПолноеИмяОбъектаМетаданных", ПолноеИмяОбъектаМетаданных);
|
||
|
||
// Выполнение запроса.
|
||
Запрос = Новый Запрос;
|
||
Запрос.УстановитьПараметр("Ссылка", Ссылка);
|
||
Запрос.Текст = ТекстЗапроса;
|
||
|
||
Попытка
|
||
Выборка = Запрос.Выполнить().Выбрать();
|
||
Исключение
|
||
|
||
// Если реквизиты были переданы строкой, то они уже конвертированы в массив.
|
||
// Если реквизиты - массив, оставляем без изменений.
|
||
// Если реквизиты - структура - конвертируем в массив.
|
||
// В остальных случаях уже было бы выброшено исключение.
|
||
Если Тип("Структура") = ТипЗнч(Реквизиты)
|
||
Или Тип("ФиксированнаяСтруктура") = ТипЗнч(Реквизиты) Тогда
|
||
Реквизиты = Новый Массив;
|
||
Для каждого КлючИЗначение Из СтруктураПолей Цикл
|
||
ИмяПоля = ?(ЗначениеЗаполнено(КлючИЗначение.Значение),
|
||
КлючИЗначение.Значение,
|
||
КлючИЗначение.Ключ);
|
||
Реквизиты.Добавить(ИмяПоля);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
// Поиск ошибки доступности полей.
|
||
Результат = ПроверитьСуществованиеРеквизитовОбъекта(ПолноеИмяОбъектаМетаданных, Реквизиты);
|
||
Если Результат.Ошибка Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверный второй параметр %1 в функции %2: %3'"),
|
||
"Реквизиты", "ОбщегоНазначения.ЗначенияРеквизитовОбъекта", Результат.ОписаниеОшибки),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
ВызватьИсключение;
|
||
|
||
КонецПопытки;
|
||
|
||
// Заполнение реквизитов.
|
||
Если Выборка.Следующий() Тогда
|
||
ЗаполнитьЗначенияСвойств(Результат, Выборка);
|
||
КонецЕсли;
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает значения реквизита, прочитанного из информационной базы по ссылке на объект.
|
||
// Рекомендуется использовать вместо обращения к реквизитам объекта через точку от ссылки на объект
|
||
// для быстрого чтения отдельных реквизитов объекта из базы данных.
|
||
//
|
||
// Если необходимо зачитать реквизит независимо от прав текущего пользователя,
|
||
// то следует использовать предварительный переход в привилегированный режим.
|
||
//
|
||
// Если передано имя несуществующего реквизита, то вызывается исключение "Поле объекта не существует".
|
||
//
|
||
// Параметры:
|
||
// Ссылка - ЛюбаяСсылка - объект, значения реквизитов которого необходимо получить.
|
||
// - Строка - полное имя предопределенного элемента, значения реквизитов которого необходимо получить.
|
||
// ИмяРеквизита - Строка - имя получаемого реквизита.
|
||
// Допускается указание имени реквизита через точку, но при этом параметр КодЯзыка для
|
||
// такого реквизита учитываться не будет.
|
||
// ВыбратьРазрешенные - Булево - если Истина, то запрос к объекту выполняется с учетом прав пользователя;
|
||
// если есть ограничение на уровне записей, то возвращается Неопределено;
|
||
// если нет прав для работы с таблицей, то возникнет исключение;
|
||
// если Ложь, то возникнет исключение при отсутствии прав на таблицу
|
||
// или любой из реквизитов.
|
||
// КодЯзыка - Строка - код языка для мультиязычного реквизита. Значение по умолчанию - основной язык конфигурации.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Произвольный - если в параметр Ссылка передана пустая ссылка, то возвращается Неопределено.
|
||
// Если в параметр Ссылка передана ссылка несуществующего объекта (битая ссылка),
|
||
// то возвращается Неопределено.
|
||
//
|
||
Функция ЗначениеРеквизитаОбъекта(Ссылка, ИмяРеквизита, ВыбратьРазрешенные = Ложь, Знач КодЯзыка = Неопределено) Экспорт
|
||
|
||
Если ПустаяСтрока(ИмяРеквизита) Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверный второй параметр %1 в функции %2:
|
||
|Имя реквизита должно быть заполнено.'"),
|
||
"ИмяРеквизита", "ОбщегоНазначения.ЗначениеРеквизитаОбъекта"),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
Результат = ЗначенияРеквизитовОбъекта(Ссылка, ИмяРеквизита, ВыбратьРазрешенные, КодЯзыка);
|
||
Возврат Результат[СтрЗаменить(ИмяРеквизита, ".", "")];
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает значения реквизитов, прочитанные из информационной базы для нескольких объектов.
|
||
// Рекомендуется использовать вместо обращения к реквизитам объекта через точку от ссылки на объект
|
||
// для быстрого чтения отдельных реквизитов объекта из базы данных.
|
||
//
|
||
// Если необходимо зачитать реквизит независимо от прав текущего пользователя,
|
||
// то следует использовать предварительный переход в привилегированный режим.
|
||
//
|
||
// Если передано имя несуществующего реквизита, то вызывается исключение "Поле объекта не существует".
|
||
//
|
||
// Параметры:
|
||
// Ссылки - Массив из ЛюбаяСсылка
|
||
// - ФиксированныйМассив из ЛюбаяСсылка - ссылки на объекты.
|
||
// Если массив пуст, то результатом будет пустое соответствие.
|
||
// Реквизиты - Строка - имена реквизитов перечисленные через запятую, в формате требований к свойствам
|
||
// структуры. Например, "Код, Наименование, Родитель".
|
||
// - Массив из Строка
|
||
// - ФиксированныйМассив из Строка - имена реквизитов в формате требований к свойствам структуры.
|
||
// ВыбратьРазрешенные - Булево - если Истина, то запрос к объектам выполняется с учетом прав пользователя;
|
||
// если какой-либо объект будет исключен из выборки по правам, то этот объект
|
||
// будет исключен и из результата;
|
||
// если Ложь, то возникнет исключение при отсутствии прав на таблицу
|
||
// или любой из реквизитов.
|
||
// КодЯзыка - Строка - код языка для мультиязычного реквизита. Значение по умолчанию - основной язык конфигурации.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Соответствие из КлючИЗначение - список объектов и значений их реквизитов:
|
||
// * Ключ - ЛюбаяСсылка - ссылка на объект;
|
||
// * Значение - Структура:
|
||
// ** Ключ - Строка - имя реквизита;
|
||
// ** Значение - Произвольный - значение реквизита.
|
||
//
|
||
Функция ЗначенияРеквизитовОбъектов(Ссылки, Знач Реквизиты, ВыбратьРазрешенные = Ложь, Знач КодЯзыка = Неопределено) Экспорт
|
||
|
||
Если ТипЗнч(Реквизиты) = Тип("Массив") Или ТипЗнч(Реквизиты) = Тип("ФиксированныйМассив") Тогда
|
||
Реквизиты = СтрСоединить(Реквизиты, ",");
|
||
КонецЕсли;
|
||
|
||
Если ПустаяСтрока(Реквизиты) Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверный второй параметр %1 в функции %2:
|
||
|Поле объекта должно быть указано.'"),
|
||
"Реквизиты", "ОбщегоНазначения.ЗначенияРеквизитовОбъектов"),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
Если СтрНайти(Реквизиты, ".") <> 0 Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверный второй параметр %1 в функции %2:
|
||
|Обращение через точку не поддерживается.'"),
|
||
"Реквизиты", "ОбщегоНазначения.ЗначенияРеквизитовОбъектов"),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
ЗначенияРеквизитов = Новый Соответствие;
|
||
Если Ссылки.Количество() = 0 Тогда
|
||
Возврат ЗначенияРеквизитов;
|
||
КонецЕсли;
|
||
|
||
Если ЗначениеЗаполнено(КодЯзыка) Тогда
|
||
КодЯзыка = СтрРазделить(КодЯзыка, "_", Истина)[0];
|
||
КонецЕсли;
|
||
|
||
РеквизитыТекстЗапроса = Реквизиты;
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
|
||
МодульМультиязычностьСервер = ОбщийМодуль("МультиязычностьСервер");
|
||
Если ЗначениеЗаполнено(КодЯзыка) Тогда
|
||
СуффиксЯзыка = МодульМультиязычностьСервер.СуффиксЯзыка(КодЯзыка);
|
||
Если ЗначениеЗаполнено(СуффиксЯзыка) Тогда
|
||
МультиязычныеРеквизиты = МодульМультиязычностьСервер.МультиязычныеРеквизитыОбъекта(Ссылки[0]);
|
||
НаборРеквизитов = СтрРазделить(Реквизиты, ",");
|
||
Для Позиция = 0 По НаборРеквизитов.ВГраница() Цикл
|
||
ИмяРеквизита = СокрЛП(НаборРеквизитов[Позиция]);
|
||
Если МультиязычныеРеквизиты[ИмяРеквизита] <> Неопределено Тогда
|
||
ИмяССуффиксом = ИмяРеквизита + СуффиксЯзыка;
|
||
НаборРеквизитов[Позиция] = ИмяССуффиксом + " КАК " + ИмяРеквизита;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
РеквизитыТекстЗапроса = СтрСоединить(НаборРеквизитов, ",");
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
СсылкиПоТипам = Новый Соответствие;
|
||
Для Каждого Ссылка Из Ссылки Цикл
|
||
Тип = ТипЗнч(Ссылка);
|
||
Если СсылкиПоТипам[Тип] = Неопределено Тогда
|
||
СсылкиПоТипам[Тип] = Новый Массив;
|
||
КонецЕсли;
|
||
ЭлементПоТипу = СсылкиПоТипам[Тип]; // Массив
|
||
ЭлементПоТипу.Добавить(Ссылка);
|
||
КонецЦикла;
|
||
|
||
ТекстыЗапросов = Новый Массив;
|
||
ПараметрыЗапроса = Новый Структура;
|
||
|
||
ИменаОбъектовМетаданных = Новый Массив;
|
||
|
||
Для Каждого СсылкиПоТипу Из СсылкиПоТипам Цикл
|
||
Тип = СсылкиПоТипу.Ключ;
|
||
ОбъектМетаданных = Метаданные.НайтиПоТипу(Тип);
|
||
Если ОбъектМетаданных = Неопределено Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверный первый параметр %1 в функции %2:
|
||
|Значения массива должны быть ссылками.'"),
|
||
"Ссылки", "ОбщегоНазначения.ЗначенияРеквизитовОбъектов"),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
ПолноеИмяОбъектаМетаданных = ОбъектМетаданных.ПолноеИмя();
|
||
ИменаОбъектовМетаданных.Добавить(ПолноеИмяОбъектаМетаданных);
|
||
|
||
ТекстЗапроса =
|
||
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
|
||
| Ссылка,
|
||
| &Реквизиты
|
||
|ИЗ
|
||
| &ПолноеИмяОбъектаМетаданных КАК ПсевдонимЗаданнойТаблицы
|
||
|ГДЕ
|
||
| ПсевдонимЗаданнойТаблицы.Ссылка В (&Ссылки)";
|
||
Если Не ВыбратьРазрешенные Или ТекстыЗапросов.Количество() > 0 Тогда
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "РАЗРЕШЕННЫЕ", ""); // @Query-part-1
|
||
КонецЕсли;
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Реквизиты", РеквизитыТекстЗапроса);
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПолноеИмяОбъектаМетаданных", ПолноеИмяОбъектаМетаданных);
|
||
ИмяПараметра = "Ссылки" + СтрЗаменить(ПолноеИмяОбъектаМетаданных, ".", "");
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Ссылки", "&" + ИмяПараметра); // @Query-part-1
|
||
ПараметрыЗапроса.Вставить(ИмяПараметра, СсылкиПоТипу.Значение);
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
|
||
МодульМультиязычностьСервер = ОбщийМодуль("МультиязычностьСервер");
|
||
|
||
Если ЗначениеЗаполнено(КодЯзыка) И КодЯзыка <> КодОсновногоЯзыка()
|
||
И МодульМультиязычностьСервер.ОбъектСодержитТЧПредставления(ПолноеИмяОбъектаМетаданных) Тогда
|
||
|
||
МультиязычныеРеквизиты = МодульМультиязычностьСервер.МультиязычныеРеквизитыОбъекта(ОбъектМетаданных);
|
||
ПоляТаблиц = Новый Массив;
|
||
ПоляТаблиц.Добавить("ПсевдонимЗаданнойТаблицы.Ссылка");
|
||
Для Каждого Реквизит Из СтрРазделить(Реквизиты, ",") Цикл
|
||
Если МультиязычныеРеквизиты[Реквизит] <> Неопределено Тогда
|
||
|
||
Если МультиязычныеРеквизиты[Реквизит] = Истина Тогда
|
||
ПолеРеквизита = "ЕСТЬNULL(ТаблицаПредставления." + Реквизит + ", """")";
|
||
Иначе
|
||
СуффиксЯзыка = МодульМультиязычностьСервер.СуффиксЯзыка(КодЯзыка);
|
||
ПолеРеквизита = ?(ЗначениеЗаполнено(СуффиксЯзыка), Реквизит + СуффиксЯзыка, Реквизит);
|
||
КонецЕсли;
|
||
|
||
ПоляТаблиц.Добавить(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1 КАК %2",
|
||
ПолеРеквизита, Реквизит));
|
||
Иначе
|
||
ПоляТаблиц.Добавить(Реквизит);
|
||
КонецЕсли;
|
||
|
||
КонецЦикла;
|
||
|
||
ПоляТаблиц = СтрСоединить(ПоляТаблиц, "," + Символы.ПС);
|
||
|
||
Таблицы = ПолноеИмяОбъектаМетаданных + " " + "КАК ПсевдонимЗаданнойТаблицы" + Символы.ПС
|
||
+ "ЛЕВОЕ СОЕДИНЕНИЕ" + " " + ПолноеИмяОбъектаМетаданных + ".Представления КАК ТаблицаПредставления" + Символы.ПС
|
||
+ "ПО ТаблицаПредставления.Ссылка = ПсевдонимЗаданнойТаблицы.Ссылка И ТаблицаПредставления.КодЯзыка = &КодЯзыка";
|
||
|
||
ИмяПараметра = "Ссылки" + СтрЗаменить(ПолноеИмяОбъектаМетаданных, ".", "");
|
||
Условия = "ПсевдонимЗаданнойТаблицы.Ссылка В (&" + ИмяПараметра + ")";
|
||
|
||
СтрокиЗапроса = Новый Массив;
|
||
СтрокиЗапроса.Добавить("ВЫБРАТЬ" + ?(ВыбратьРазрешенные И Не ЗначениеЗаполнено(ТекстыЗапросов), " " + "РАЗРЕШЕННЫЕ", "")); // @Query-part-1, @Query-part-3
|
||
СтрокиЗапроса.Добавить(ПоляТаблиц);
|
||
СтрокиЗапроса.Добавить("ИЗ"); // @Query-part-1
|
||
СтрокиЗапроса.Добавить(Таблицы);
|
||
СтрокиЗапроса.Добавить("ГДЕ"); // @Query-part-1
|
||
СтрокиЗапроса.Добавить(Условия);
|
||
|
||
ТекстЗапроса = СтрСоединить(СтрокиЗапроса, Символы.ПС);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
ТекстыЗапросов.Добавить(ТекстЗапроса);
|
||
КонецЦикла;
|
||
|
||
ТекстЗапроса = СтрСоединить(ТекстыЗапросов, Символы.ПС + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС);
|
||
|
||
Запрос = Новый Запрос(ТекстЗапроса);
|
||
Запрос.УстановитьПараметр("КодЯзыка", КодЯзыка);
|
||
Для Каждого Параметр Из ПараметрыЗапроса Цикл
|
||
Запрос.УстановитьПараметр(Параметр.Ключ, Параметр.Значение);
|
||
КонецЦикла;
|
||
|
||
Попытка
|
||
Выборка = Запрос.Выполнить().Выбрать();
|
||
Исключение
|
||
|
||
// Удаление пробелов.
|
||
Реквизиты = СтрЗаменить(Реквизиты, " ", "");
|
||
// Преобразование параметра в массив полей.
|
||
Реквизиты = СтрРазделить(Реквизиты, ",");
|
||
|
||
// Поиск ошибки доступности полей.
|
||
СписокОшибок = Новый Массив;
|
||
Для Каждого ПолноеИмяОбъектаМетаданных Из ИменаОбъектовМетаданных Цикл
|
||
Результат = ПроверитьСуществованиеРеквизитовОбъекта(ПолноеИмяОбъектаМетаданных, Реквизиты);
|
||
Если Результат.Ошибка Тогда
|
||
СписокОшибок.Добавить(Результат.ОписаниеОшибки);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если ЗначениеЗаполнено(СписокОшибок) Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверный второй параметр %1 в функции %2: %3'"),
|
||
"Реквизиты", "ОбщегоНазначения.ЗначенияРеквизитовОбъектов",
|
||
СтрСоединить(СписокОшибок, Символы.ПС)),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
ВызватьИсключение;
|
||
|
||
КонецПопытки;
|
||
|
||
Пока Выборка.Следующий() Цикл
|
||
Результат = Новый Структура(Реквизиты);
|
||
ЗаполнитьЗначенияСвойств(Результат, Выборка);
|
||
ЗначенияРеквизитов[Выборка.Ссылка] = Результат;
|
||
|
||
КонецЦикла;
|
||
|
||
Возврат ЗначенияРеквизитов;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает значения реквизита, прочитанного из информационной базы для нескольких объектов.
|
||
// Рекомендуется использовать вместо обращения к реквизитам объекта через точку от ссылки на объект
|
||
// для быстрого чтения отдельных реквизитов объекта из базы данных.
|
||
//
|
||
// Если необходимо зачитать реквизит независимо от прав текущего пользователя,
|
||
// то следует использовать предварительный переход в привилегированный режим.
|
||
//
|
||
// Если передано имя несуществующего реквизита, то вызывается исключение "Поле объекта не существует".
|
||
//
|
||
// Параметры:
|
||
// МассивСсылок - Массив из ЛюбаяСсылка
|
||
// - ФиксированныйМассив из ЛюбаяСсылка
|
||
// ИмяРеквизита - Строка - например, "Код".
|
||
// ВыбратьРазрешенные - Булево - если Истина, то запрос к объектам выполняется с учетом прав пользователя;
|
||
// если какой-либо объект будет исключен из выборки по правам, то этот объект
|
||
// будет исключен и из результата;
|
||
// если Ложь, то возникнет исключение при отсутствии прав на таблицу
|
||
// или любой из реквизитов.
|
||
// КодЯзыка - Строка - код языка для мультиязычного реквизита. Значение по умолчанию - основной язык конфигурации.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Соответствие из КлючИЗначение:
|
||
// * Ключ - ЛюбаяСсылка - ссылка на объект,
|
||
// * Значение - Произвольный - значение прочитанного реквизита.
|
||
//
|
||
Функция ЗначениеРеквизитаОбъектов(МассивСсылок, ИмяРеквизита, ВыбратьРазрешенные = Ложь, Знач КодЯзыка = Неопределено) Экспорт
|
||
|
||
Если ПустаяСтрока(ИмяРеквизита) Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверный второй параметр %1 в функции %2:
|
||
|Имя реквизита должно быть заполнено.'"),
|
||
"ИмяРеквизита", "ОбщегоНазначения.ЗначениеРеквизитаОбъектов"),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
ЗначенияРеквизитов = ЗначенияРеквизитовОбъектов(МассивСсылок, ИмяРеквизита, ВыбратьРазрешенные, КодЯзыка);
|
||
Для каждого Элемент Из ЗначенияРеквизитов Цикл
|
||
ЗначенияРеквизитов[Элемент.Ключ] = Элемент.Значение[ИмяРеквизита];
|
||
КонецЦикла;
|
||
|
||
Возврат ЗначенияРеквизитов;
|
||
|
||
КонецФункции
|
||
|
||
// Добавляет или изменяет значение реквизита в объекте.
|
||
//
|
||
// Если передано имя несуществующего реквизита, то вызывается исключение.
|
||
//
|
||
// Параметры:
|
||
// Объект - СправочникОбъект
|
||
// - ДокументОбъект
|
||
// - ПланВидовХарактеристикОбъект
|
||
// - РегистрСведенийЗапись - заполняемый объект.
|
||
// ИмяРеквизита - Строка - имя заполняемого реквизита. Например, "Комментарий"
|
||
// Значение - Строка - значение помещаемое в реквизит.
|
||
// КодЯзыка - Строка - код языка реквизита. Например, "ru".
|
||
//
|
||
Процедура УстановитьЗначениеРеквизита(Объект, ИмяРеквизита, Значение, КодЯзыка = Неопределено) Экспорт
|
||
УстановитьЗначенияРеквизитов(Объект, Новый Структура(ИмяРеквизита, Значение), КодЯзыка);
|
||
КонецПроцедуры
|
||
|
||
// Добавляет или изменяет значения реквизитов в объекте.
|
||
//
|
||
// Если передано имя несуществующего реквизита, то вызывается исключение.
|
||
//
|
||
// Параметры:
|
||
// Объект - СправочникОбъект
|
||
// - ДокументОбъект
|
||
// - ПланВидовХарактеристикОбъект
|
||
// - РегистрСведенийЗапись - заполняемый объект.
|
||
// Значения - Структура - где ключ это имя реквизита, а значение содержит строку помещаемую в реквизит.
|
||
// КодЯзыка - Строка - код языка реквизита. Например, "ru".
|
||
//
|
||
Процедура УстановитьЗначенияРеквизитов(Объект, Значения, КодЯзыка = Неопределено) Экспорт
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
|
||
МодульМультиязычностьСервер = ОбщийМодуль("МультиязычностьСервер");
|
||
МодульМультиязычностьСервер.УстановитьЗначенияРеквизитов(Объект, Значения, КодЯзыка);
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
Для Каждого ЗначениеРеквизита Из Значения Цикл
|
||
Значение = ЗначениеРеквизита.Значение;
|
||
Если ТипЗнч(Значение) = Тип("Строка") И СтрокаВВидеНСтр(Значение) Тогда
|
||
Значение = НСтр(ЗначениеРеквизита.Значение);
|
||
КонецЕсли;
|
||
Объект[ЗначениеРеквизита.Ключ] = Значение;
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Возвращает код основного языка информационной базы, например "ru".
|
||
// На котором программно записываются автогенерируемые строки в информационную базу.
|
||
// Например, при начальном заполнении информационной базы данными из макета, автогенерации комментария
|
||
// к проводке или определении значения параметра ИмяСобытия метода ЗаписьЖурналаРегистрации.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка
|
||
//
|
||
Функция КодОсновногоЯзыка() Экспорт
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
|
||
МодульМультиязычностьСервер = ОбщийМодуль("МультиязычностьСервер");
|
||
Возврат МодульМультиязычностьСервер.КодОсновногоЯзыка();
|
||
КонецЕсли;
|
||
|
||
Возврат Метаданные.ОсновнойЯзык.КодЯзыка;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает признак того, что для пользователя установлен язык интерфейса
|
||
// соответствующий основному языку информационной базы.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево
|
||
//
|
||
Функция ЭтоОсновнойЯзык() Экспорт
|
||
|
||
Возврат СтрСравнить(КодОсновногоЯзыка(), ТекущийЯзык().КодЯзыка) = 0;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает ссылку предопределенного элемента по его полному имени.
|
||
// Предопределенные элементы могут содержаться только в следующих объектах:
|
||
// - справочники;
|
||
// - планы видов характеристик;
|
||
// - планы счетов;
|
||
// - планы видов расчета.
|
||
// После изменения состава предопределенных следует выполнить метод
|
||
// ОбновитьПовторноИспользуемыеЗначения(), который сбросит кэш ПовтИсп в текущем сеансе.
|
||
//
|
||
// Параметры:
|
||
// ПолноеИмяПредопределенного - Строка - полный путь к предопределенному элементу, включая его имя.
|
||
// Формат аналогичен функции глобального контекста ПредопределенноеЗначение().
|
||
// Например:
|
||
// "Справочник.ВидыКонтактнойИнформации.EmailПользователя"
|
||
// "ПланСчетов.Хозрасчетный.Материалы"
|
||
// "ПланВидовРасчета.Начисления.ОплатаПоОкладу".
|
||
//
|
||
// Возвращаемое значение:
|
||
// ЛюбаяСсылка - ссылка на предопределенный элемент.
|
||
// Неопределено - если предопределенный элемент есть в метаданных, но не создан в ИБ.
|
||
//
|
||
Функция ПредопределенныйЭлемент(ПолноеИмяПредопределенного) Экспорт
|
||
|
||
СтандартнаяОбработка = ОбщегоНазначенияСлужебныйКлиентСервер.ИспользоватьСтандартнуюФункциюПолученияПредопределенного(
|
||
ПолноеИмяПредопределенного);
|
||
|
||
Если СтандартнаяОбработка Тогда
|
||
Возврат ПредопределенноеЗначение(ПолноеИмяПредопределенного);
|
||
КонецЕсли;
|
||
|
||
ПоляПредопределенного = ОбщегоНазначенияСлужебныйКлиентСервер.ИмяПредопределенногоПоПолям(ПолноеИмяПредопределенного);
|
||
|
||
ПредопределенныеЗначения = СтандартныеПодсистемыПовтИсп.СсылкиПоИменамПредопределенных(
|
||
ПоляПредопределенного.ПолноеИмяОбъектаМетаданных);
|
||
|
||
Возврат ОбщегоНазначенияСлужебныйКлиентСервер.ПредопределенныйЭлемент(
|
||
ПолноеИмяПредопределенного, ПоляПредопределенного, ПредопределенныеЗначения);
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает информацию о том, являются ли переданные элементы предопределенными.
|
||
// Если нет прав доступа на уровне записей, то элемент не включается в результат.
|
||
// Если нет прав доступа к таблице, то вызывается исключение.
|
||
//
|
||
// Параметры:
|
||
// Элементы - Массив из ЛюбаяСсылка
|
||
//
|
||
// Возвращаемое значение:
|
||
// Соответствие из КлючИЗначение - список объектов и значений их реквизитов:
|
||
// * Ключ - ЛюбаяСсылка - ссылка на объект.
|
||
// * Значение - Булево - Истина, если это ссылка на предопределенный элемент.
|
||
//
|
||
Функция ЭтоПредопределенныеЭлементы(Знач Элементы) Экспорт
|
||
|
||
ИменаРеквизитов = Новый Массив;
|
||
Для каждого ИмяРеквизита Из СтандартныеПодсистемыСервер.РеквизитыПредопределенныхДанных() Цикл
|
||
ИменаРеквизитов.Добавить(ИмяРеквизита.Ключ);
|
||
КонецЦикла;
|
||
|
||
ЗначенияРеквизитов = СтандартныеПодсистемыСервер.ЗначенияРеквизитовОбъектовЕслиСуществуют(Элементы, ИменаРеквизитов);
|
||
Результат = Новый Соответствие;
|
||
Для каждого Элемент Из ЗначенияРеквизитов Цикл
|
||
ЭтоПредопределенныйЭлемент = Ложь;
|
||
Для каждого Значение Из Элемент.Значение Цикл
|
||
Если ЗначениеЗаполнено(Значение.Значение) Тогда
|
||
ЭтоПредопределенныйЭлемент = Истина;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Результат[Элемент.Ключ] = ЭтоПредопределенныйЭлемент;
|
||
КонецЦикла;
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Проверяет статус проведения переданных документов и возвращает
|
||
// те из них, которые не проведены.
|
||
//
|
||
// Параметры:
|
||
// Документы - Массив из ДокументСсылка - документы, статус проведения которых необходимо проверить.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Массив из ДокументСсылка - непроведенные документы.
|
||
//
|
||
Функция ПроверитьПроведенностьДокументов(Знач Документы) Экспорт
|
||
|
||
Результат = Новый Массив;
|
||
|
||
ШаблонЗапроса =
|
||
"ВЫБРАТЬ
|
||
| ПсевдонимЗаданнойТаблицы.Ссылка КАК Ссылка
|
||
|ИЗ
|
||
| &ИмяДокумента КАК ПсевдонимЗаданнойТаблицы
|
||
|ГДЕ
|
||
| ПсевдонимЗаданнойТаблицы.Ссылка В(&МассивДокументов)
|
||
| И НЕ ПсевдонимЗаданнойТаблицы.Проведен";
|
||
|
||
ТекстОбъединитьВсе = ТекстОбъединитьВсе();
|
||
|
||
ИменаДокументов = Новый Массив;
|
||
Для Каждого Документ Из Документы Цикл
|
||
МетаданныеДокумента = Документ.Метаданные();
|
||
Если ИменаДокументов.Найти(МетаданныеДокумента.ПолноеИмя()) = Неопределено
|
||
И Метаданные.Документы.Содержит(МетаданныеДокумента)
|
||
И МетаданныеДокумента.Проведение = Метаданные.СвойстваОбъектов.Проведение.Разрешить Тогда
|
||
ИменаДокументов.Добавить(МетаданныеДокумента.ПолноеИмя());
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
ТекстЗапроса = "";
|
||
Для Каждого ИмяДокумента Из ИменаДокументов Цикл
|
||
Если Не ПустаяСтрока(ТекстЗапроса) Тогда
|
||
ТекстЗапроса = ТекстЗапроса + ТекстОбъединитьВсе;
|
||
КонецЕсли;
|
||
ТекстПодзапроса = СтрЗаменить(ШаблонЗапроса, "&ИмяДокумента", ИмяДокумента);
|
||
ТекстЗапроса = ТекстЗапроса + ТекстПодзапроса;
|
||
КонецЦикла;
|
||
|
||
Запрос = Новый Запрос;
|
||
Запрос.Текст = ТекстЗапроса;
|
||
Запрос.УстановитьПараметр("МассивДокументов", Документы);
|
||
|
||
Если Не ПустаяСтрока(ТекстЗапроса) Тогда
|
||
Результат = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
|
||
КонецЕсли;
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Выполняет попытку проведения документов.
|
||
//
|
||
// Параметры:
|
||
// Документы - Массив из ДокументСсылка - документы, которые необходимо провести.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Массив из Структура:
|
||
// * Ссылка - ДокументСсылка - документ, который не удалось провести,
|
||
// * ОписаниеОшибки - Строка - текст описания ошибки при проведении.
|
||
//
|
||
Функция ПровестиДокументы(Документы) Экспорт
|
||
|
||
НепроведенныеДокументы = Новый Массив;
|
||
|
||
Для Каждого ДокументСсылка Из Документы Цикл
|
||
|
||
ВыполненоУспешно = Ложь;
|
||
ДокументОбъект = ДокументСсылка.ПолучитьОбъект();
|
||
Если ДокументОбъект.ПроверитьЗаполнение() Тогда
|
||
РежимПроведения = РежимПроведенияДокумента.Неоперативный;
|
||
Если ДокументОбъект.Дата >= НачалоДня(ТекущаяДатаСеанса())
|
||
И ДокументСсылка.Метаданные().ОперативноеПроведение = Метаданные.СвойстваОбъектов.ОперативноеПроведение.Разрешить Тогда
|
||
РежимПроведения = РежимПроведенияДокумента.Оперативный;
|
||
КонецЕсли;
|
||
Попытка
|
||
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение, РежимПроведения);
|
||
ВыполненоУспешно = Истина;
|
||
Исключение
|
||
ПредставлениеОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
|
||
КонецПопытки;
|
||
Иначе
|
||
ПредставлениеОшибки = НСтр("ru = 'Поля документа не заполнены.'");
|
||
КонецЕсли;
|
||
|
||
Если Не ВыполненоУспешно Тогда
|
||
НепроведенныеДокументы.Добавить(Новый Структура("Ссылка,ОписаниеОшибки", ДокументСсылка, ПредставлениеОшибки));
|
||
КонецЕсли;
|
||
|
||
КонецЦикла;
|
||
|
||
Возврат НепроведенныеДокументы;
|
||
|
||
КонецФункции
|
||
|
||
// Проверяет наличие ссылок на объект в базе данных.
|
||
// При вызове в неразделенном сеансе не выявляет ссылок в разделенных областях.
|
||
//
|
||
// Параметры:
|
||
// СсылкаИлиМассивСсылок - ЛюбаяСсылка
|
||
// - Массив из ЛюбаяСсылка - объект или список объектов.
|
||
// ИскатьСредиСлужебныхОбъектов - Булево - если Истина, то не будут учитываться
|
||
// исключения поиска ссылок, заданные при разработке конфигурации.
|
||
// Про исключение поиска ссылок см. подробнее
|
||
// ОбщегоНазначенияПереопределяемый.ПриДобавленииИсключенийПоискаСсылок.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если есть ссылки на объект.
|
||
//
|
||
Функция ЕстьСсылкиНаОбъект(Знач СсылкаИлиМассивСсылок, Знач ИскатьСредиСлужебныхОбъектов = Ложь) Экспорт
|
||
|
||
Если ТипЗнч(СсылкаИлиМассивСсылок) = Тип("Массив") Тогда
|
||
МассивСсылок = СсылкаИлиМассивСсылок;
|
||
Иначе
|
||
МассивСсылок = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(СсылкаИлиМассивСсылок);
|
||
КонецЕсли;
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
МестаИспользования = НайтиПоСсылкам(МассивСсылок);
|
||
УстановитьПривилегированныйРежим(Ложь);
|
||
|
||
Если Не ИскатьСредиСлужебныхОбъектов Тогда
|
||
Для каждого Элемент Из СлужебныеСвязиДанных(МестаИспользования) Цикл
|
||
МестаИспользования.Удалить(Элемент.Ключ);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
Возврат МестаИспользования.Количество() > 0;
|
||
|
||
КонецФункции
|
||
|
||
|
||
// Определяет, указаны ли места использования в исключениях поиска ссылок.
|
||
//
|
||
// Параметры:
|
||
// МестаИспользования - ТаблицаЗначений - результат функции НайтиПоСсылкам:
|
||
// * Ссылка - ЛюбаяСсылка - проверяемая ссылка.
|
||
// * Данные - ЛюбаяСсылка - место использования.
|
||
// * Метаданные - ОбъектМетаданных - метаданные места использования.
|
||
// ИсключенияПоискаСсылок - см. ИсключенияПоискаСсылок
|
||
//
|
||
// Возвращаемое значение:
|
||
// Соответствие из КлючИЗначение:
|
||
// * Ключ - СтрокаТаблицыЗначений
|
||
// * Значение - Булево - всегда Истина. Если это не служебная связь данных, то в соответствии нет элемента.
|
||
//
|
||
Функция СлужебныеСвязиДанных(Знач МестаИспользования, Знач ИсключенияПоискаСсылок = Неопределено) Экспорт
|
||
|
||
Если ИсключенияПоискаСсылок = Неопределено Тогда
|
||
ИсключенияПоискаСсылок = ИсключенияПоискаСсылок();
|
||
КонецЕсли;
|
||
|
||
Результат = Новый Соответствие;
|
||
МестоИспользованияПоМетаданным = Новый Соответствие;
|
||
|
||
Для каждого МестоИспользования Из МестаИспользования Цикл
|
||
ИсключениеПоиска = ИсключенияПоискаСсылок[МестоИспользования.Метаданные];
|
||
|
||
// Данные могут быть как ссылкой, так и ключом записи регистра.
|
||
Если ИсключениеПоиска = Неопределено Тогда
|
||
Если МестоИспользования.Ссылка = МестоИспользования.Данные Тогда
|
||
Результат[МестоИспользования] = Истина; // Ссылку саму на себя исключаем.
|
||
КонецЕсли;
|
||
Продолжить;
|
||
ИначеЕсли ИсключениеПоиска = "*" Тогда
|
||
Результат[МестоИспользования] = Истина; // Если указано исключить все - считаем все исключением.
|
||
Продолжить;
|
||
КонецЕсли;
|
||
|
||
ЭтоСсылка = ЭтоСсылка(ТипЗнч(МестоИспользования.Данные));
|
||
Если Не ЭтоСсылка Тогда
|
||
Для Каждого ПутьКРеквизиту Из ИсключениеПоиска Цикл
|
||
ЗначениеРеквизита = Новый Структура(ПутьКРеквизиту);
|
||
ЗаполнитьЗначенияСвойств(ЗначениеРеквизита, МестоИспользования.Данные);
|
||
Если ЗначениеРеквизита[ПутьКРеквизиту] = МестоИспользования.Ссылка Тогда
|
||
Результат[МестоИспользования] = Истина;
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Продолжить;
|
||
КонецЕсли;
|
||
|
||
Если ИсключениеПоиска.Количество() = 0 Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
|
||
ИмяТаблицы = МестоИспользования.Метаданные.ПолноеИмя();
|
||
Значение = МестоИспользованияПоМетаданным[ИмяТаблицы];
|
||
Если Значение = Неопределено Тогда
|
||
Значение = Новый ТаблицаЗначений;
|
||
Значение.Колонки.Добавить("Ссылка", ОписаниеТипаВсеСсылки());
|
||
Значение.Колонки.Добавить("Данные", ОписаниеТипаВсеСсылки());
|
||
Значение.Колонки.Добавить("Метаданные");
|
||
МестоИспользованияПоМетаданным[ИмяТаблицы] = Значение;
|
||
КонецЕсли;
|
||
ЗаполнитьЗначенияСвойств(Значение.Добавить(), МестоИспользования);
|
||
|
||
КонецЦикла;
|
||
|
||
Индекс = 1;
|
||
Запрос = Новый Запрос;
|
||
ТекстыЗапроса = Новый Массив;
|
||
ВременныеТаблицы = Новый Массив;
|
||
|
||
Для каждого МестоИспользования Из МестоИспользованияПоМетаданным Цикл
|
||
|
||
ИмяТаблицы = МестоИспользования.Ключ; // Строка
|
||
МестоИспользования = МестоИспользования.Значение; // ТаблицаЗначений
|
||
|
||
// Проверка, есть ли по исключаемому пути в указанных данных проверяемая ссылка.
|
||
Если МестоИспользования.Количество() > 1 Тогда
|
||
ШаблонЗапроса =
|
||
"ВЫБРАТЬ
|
||
| Ссылки.Данные КАК Ссылка,
|
||
| Ссылки.Ссылка КАК ПроверяемаяСсылка
|
||
|ПОМЕСТИТЬ ВТТаблицаСсылок
|
||
|ИЗ
|
||
| &Ссылки КАК Ссылки
|
||
|;
|
||
|
|
||
|ВЫБРАТЬ
|
||
| ТаблицаСсылок.Ссылка КАК Ссылка,
|
||
| ТаблицаСсылок.ПроверяемаяСсылка КАК ПроверяемаяСсылка
|
||
|ИЗ
|
||
| ВТТаблицаСсылок КАК ТаблицаСсылок
|
||
| ЛЕВОЕ СОЕДИНЕНИЕ #ПолноеИмяОбъектаМетаданных КАК Таблица
|
||
| ПО ТаблицаСсылок.Ссылка = Таблица.Ссылка
|
||
|ГДЕ
|
||
| &Условие";
|
||
|
||
ТекстЗапроса = СтрЗаменить(ШаблонЗапроса, "#ПолноеИмяОбъектаМетаданных", ИмяТаблицы);
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ВТТаблицаСсылок", "ВТТаблицаСсылок" + Формат(Индекс, "ЧГ=;ЧН="));
|
||
|
||
ИмяПараметра = "Ссылки" + Формат(Индекс, "ЧГ=;ЧН=");
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Ссылки", "&" + ИмяПараметра);
|
||
Запрос.УстановитьПараметр(ИмяПараметра, МестоИспользования);
|
||
|
||
ЧастиЗапроса = СтрРазделить(ТекстЗапроса, ";");
|
||
ВременныеТаблицы.Добавить(ЧастиЗапроса[0]);
|
||
ТекстЗапроса = ЧастиЗапроса[1];
|
||
|
||
Иначе
|
||
ШаблонЗапроса =
|
||
"ВЫБРАТЬ
|
||
| &СсылкаНаВладельца КАК Ссылка,
|
||
| &ПроверяемаяСсылка КАК ПроверяемаяСсылка
|
||
|ИЗ
|
||
| #ПолноеИмяОбъектаМетаданных КАК Таблица
|
||
|ГДЕ
|
||
| Таблица.Ссылка = &СсылкаНаВладельца
|
||
| И (&Условие)";
|
||
|
||
ТекстЗапроса = СтрЗаменить(ШаблонЗапроса, "#ПолноеИмяОбъектаМетаданных", ИмяТаблицы);
|
||
|
||
ИмяПараметра = "СсылкаНаВладельца" + Формат(Индекс, "ЧГ=;ЧН=");
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&СсылкаНаВладельца", "&" + ИмяПараметра);
|
||
Запрос.УстановитьПараметр(ИмяПараметра, МестоИспользования[0].Данные);
|
||
|
||
ИмяПараметра = "ПроверяемаяСсылка" + Формат(Индекс, "ЧГ=;ЧН=");
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПроверяемаяСсылка", "&" + ИмяПараметра);
|
||
Запрос.УстановитьПараметр(ИмяПараметра, МестоИспользования[0].Ссылка);
|
||
|
||
КонецЕсли;
|
||
|
||
ТекстУсловия = Новый Массив;
|
||
// Относительный путь к реквизиту: "<ИмяРеквизитаИлиТЧ>[.<ИмяРеквизитаТЧ>]".
|
||
Для Каждого ПутьКРеквизиту Из ИсключенияПоискаСсылок[МестоИспользования[0].Метаданные] Цикл
|
||
ТекстУсловия.Добавить(ПутьКРеквизиту + " = "
|
||
+ ?(МестоИспользования.Количество() > 1, "ТаблицаСсылок.ПроверяемаяСсылка", "&" + ИмяПараметра));
|
||
КонецЦикла;
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Условие", СтрСоединить(ТекстУсловия, " ИЛИ "));
|
||
|
||
ТекстыЗапроса.Добавить(ТекстЗапроса);
|
||
Индекс = Индекс + 1;
|
||
|
||
КонецЦикла;
|
||
|
||
Если ТекстыЗапроса.Количество() = 0 Тогда
|
||
Возврат Результат;
|
||
КонецЕсли;
|
||
|
||
Запрос.Текст = СтрСоединить(ВременныеТаблицы, ";" + Символы.ПС)
|
||
+ ?(ВременныеТаблицы.Количество() > 0, ";" + Символы.ПС, "")
|
||
+ СтрСоединить(ТекстыЗапроса, Символы.ПС + "ОБЪЕДИНИТЬ" + Символы.ПС);
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
ВыборкаЗапроса = Запрос.Выполнить().Выбрать();
|
||
УстановитьПривилегированныйРежим(Ложь);
|
||
|
||
МестаИспользования.Индексы.Добавить("Ссылка,Данные");
|
||
Пока ВыборкаЗапроса.Следующий() Цикл
|
||
СлужебныеСвязиДанных = МестаИспользования.НайтиСтроки(Новый Структура("Ссылка,Данные",
|
||
ВыборкаЗапроса.ПроверяемаяСсылка, ВыборкаЗапроса.Ссылка));
|
||
Для каждого СлужебнаяСвязьДанных Из СлужебныеСвязиДанных Цикл
|
||
Результат[СлужебнаяСвязьДанных] = Истина;
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Определяет, указано ли место использования в исключениях поиска ссылок.
|
||
//
|
||
// Параметры:
|
||
// МестоИспользования - Структура:
|
||
// * Ссылка - ЛюбаяСсылка - проверяемая ссылка.
|
||
// * Данные - ЛюбаяСсылка - место использования.
|
||
// * Метаданные - ОбъектМетаданных - метаданные места использования.
|
||
// ИсключенияПоискаСсылок - см. ИсключенияПоискаСсылок
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево
|
||
//
|
||
Функция ЭтоСлужебнаяСвязьДанных(Знач МестоИспользования, Знач ИсключенияПоискаСсылок = Неопределено) Экспорт
|
||
|
||
Если ИсключенияПоискаСсылок = Неопределено Тогда
|
||
ИсключенияПоискаСсылок = ИсключенияПоискаСсылок();
|
||
КонецЕсли;
|
||
|
||
Значение = Новый ТаблицаЗначений;
|
||
Значение.Колонки.Добавить("Ссылка", ОписаниеТипаВсеСсылки());
|
||
Значение.Колонки.Добавить("Данные", ОписаниеТипаВсеСсылки());
|
||
Значение.Колонки.Добавить("Метаданные");
|
||
МестоИспользованияСтрока = Значение.Добавить();
|
||
ЗаполнитьЗначенияСвойств(МестоИспользованияСтрока, МестоИспользования);
|
||
|
||
Результат = СлужебныеСвязиДанных(Значение, ИсключенияПоискаСсылок);
|
||
Возврат Результат[МестоИспользованияСтрока] <> Неопределено;
|
||
|
||
КонецФункции
|
||
|
||
// Производит замену ссылок во всех данных. После замены неиспользуемые ссылки опционально удаляются.
|
||
// Замена ссылок происходит с транзакциями по изменяемому объекту и его связям, не по анализируемой ссылке.
|
||
// При вызове в неразделенном сеансе не выявляет ссылок в разделенных областях.
|
||
// Если описаны связи подчиненных и основных объектов (см. СвязиПодчиненныхОбъектов), то:
|
||
// * при замене основных объектов будет выполнен поиск замен подчиненных объектов;
|
||
// * если ВыполнятьАвтоматическийПоискЗамен = Истина, то будет выполнена попытка поиска замен для подчиненных объектов
|
||
// по значениям полей связи. В случае, если объект не существует, будет выполнена процедура ПриПоискеЗаменыСсылок;
|
||
// * если МетодПоиска в описании связей задан, то если автоматический поиск не нашел замен
|
||
// или не выполнялся, будет вызван МетодПоиска для подбора замен.
|
||
//
|
||
// Параметры:
|
||
// ПарыЗамен - Соответствие из КлючИЗначение:
|
||
// * Ключ - ЛюбаяСсылка - что ищем (дубль).
|
||
// * Значение - ЛюбаяСсылка - на что заменяем (оригинал).
|
||
// Ссылки сами на себя и пустые ссылки для поиска будут проигнорированы.
|
||
//
|
||
// ПараметрыЗамены - см. ОбщегоНазначения.ПараметрыЗаменыСсылок
|
||
//
|
||
// Возвращаемое значение:
|
||
// ТаблицаЗначений - неуспешные замены (ошибки):
|
||
// * Ссылка - ЛюбаяСсылка - ссылка, которую заменяли.
|
||
// * ОбъектОшибки - Произвольный - объект-причина ошибки.
|
||
// * ПредставлениеОбъектаОшибки - Строка - строковое представление объекта ошибки.
|
||
// * ТипОшибки - Строка - тип ошибки:
|
||
// "ОшибкаБлокировки" - при замене в объекте данные были заблокированы другим сеансом.
|
||
// "ДанныеИзменены" - в процессе замены данные были изменены другим пользователем.
|
||
// "ОшибкаЗаписи" - не удалось записать объект, или метод ВозможностьЗаменыЭлементов вернул отказ.
|
||
// "ОшибкаУдаления" - не удалось удалить объект.
|
||
// "НеизвестныеДанные" - при обработке были найдены данные, которые не планировались к замене.
|
||
// * ИнформацияОбОшибке - ИнформацияОбОшибке
|
||
// * ТекстОшибки - Строка - если свойство ИнформацияОбОшибке содержит Неопределено, то описание причины.
|
||
//
|
||
Функция ЗаменитьСсылки(Знач ПарыЗамен, Знач ПараметрыЗамены = Неопределено) Экспорт
|
||
|
||
Статистика = Новый Соответствие;
|
||
ТипСтрока = Новый ОписаниеТипов("Строка");
|
||
|
||
ОшибкиЗамены = Новый ТаблицаЗначений;
|
||
ОшибкиЗамены.Колонки.Добавить("Ссылка");
|
||
ОшибкиЗамены.Колонки.Добавить("ОбъектОшибки");
|
||
ОшибкиЗамены.Колонки.Добавить("ПредставлениеОбъектаОшибки", ТипСтрока);
|
||
ОшибкиЗамены.Колонки.Добавить("ТипОшибки", ТипСтрока);
|
||
ОшибкиЗамены.Колонки.Добавить("ТекстОшибки", ТипСтрока);
|
||
ОшибкиЗамены.Колонки.Добавить("ИнформацияОбОшибке");
|
||
|
||
ОшибкиЗамены.Индексы.Добавить("Ссылка");
|
||
ОшибкиЗамены.Индексы.Добавить("Ссылка, ОбъектОшибки, ТипОшибки");
|
||
|
||
Результат = РезультатЗаменыСсылок(ОшибкиЗамены);
|
||
|
||
ПараметрыВыполнения = НовыйПараметрыВыполненияЗаменыСсылок(ПараметрыЗамены);
|
||
|
||
ПараметрыПоискаМестИспользования = ПараметрыПоискаМестИспользования();
|
||
ДополнитьИсключенияПоискаСсылокПодчиненнымиОбъектами(ПараметрыПоискаМестИспользования.ДополнительныеИсключенияПоискаСсылок);
|
||
ПараметрыВыполнения.Вставить("ПараметрыПоискаМестИспользования", ПараметрыПоискаМестИспользования);
|
||
|
||
ИнтеграцияПодсистемБСП.ПередПоискомМестИспользования(ПарыЗамен, ПараметрыВыполнения);
|
||
|
||
Если ПарыЗамен.Количество() = 0 Тогда
|
||
Возврат Результат.Ошибки;
|
||
КонецЕсли;
|
||
|
||
Дубли = СформироватьДубли(ПараметрыВыполнения, ПараметрыЗамены, ПарыЗамен, Результат);
|
||
ТаблицаПоиска = МестаИспользования(Дубли,, ПараметрыВыполнения.ПараметрыПоискаМестИспользования);
|
||
|
||
// Для каждой ссылки объекта будем производить замены в порядке "Константа", "Объект", "Набор".
|
||
// Одновременно пустая строка в этой колонке - флаг того, что эта замена не нужна или уже была произведена.
|
||
ТаблицаПоиска.Колонки.Добавить("КлючЗамены", ТипСтрока);
|
||
ТаблицаПоиска.Индексы.Добавить("Ссылка, КлючЗамены");
|
||
ТаблицаПоиска.Индексы.Добавить("Данные, КлючЗамены");
|
||
|
||
// Вспомогательные данные
|
||
ТаблицаПоиска.Колонки.Добавить("ЦелеваяСсылка");
|
||
ТаблицаПоиска.Колонки.Добавить("Обработано", Новый ОписаниеТипов("Булево"));
|
||
|
||
// Определяем порядок обработки и проверяем то, что можно обработать.
|
||
ОшибкиРазметки = Новый Массив;
|
||
ОбъектыСОшибками = Новый Массив;
|
||
Количество = Дубли.Количество();
|
||
Для Номер = 1 По Количество Цикл
|
||
ОбратныйИндекс = Количество - Номер;
|
||
Дубль = Дубли[ОбратныйИндекс];
|
||
РезультатРазметки = РазметитьМестаИспользования(ПараметрыВыполнения, Дубль, ПарыЗамен[Дубль], ТаблицаПоиска);
|
||
Если Не РезультатРазметки.Успех Тогда
|
||
Дубли.Удалить(ОбратныйИндекс);
|
||
Для Каждого Ошибка Из РезультатРазметки.ОшибкиРазметки Цикл
|
||
Ошибка.Вставить("Дубль", Дубль);
|
||
ОбъектыСОшибками.Добавить(Ошибка.Объект);
|
||
КонецЦикла;
|
||
ОбщегоНазначенияКлиентСервер.ДополнитьМассив(ОшибкиРазметки, РезультатРазметки.ОшибкиРазметки);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если ОшибкиРазметки.Количество() > 0 Тогда
|
||
ПредставленияОбъектов = ПредметыСтрокой(ОбъектыСОшибками);
|
||
Для Каждого Ошибка Из ОшибкиРазметки Цикл
|
||
ЗарегистрироватьОшибкуЗамены(Результат, Ошибка.Дубль,
|
||
ОписаниеОшибкиЗамены("НеизвестныеДанные", Ошибка.Объект, ПредставленияОбъектов[Ошибка.Объект],
|
||
Ошибка.Текст));
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
// Замена и удаление найденных дублей.
|
||
ПараметрыВыполнения.Вставить("ПарыЗамен", ПарыЗамен);
|
||
ПараметрыВыполнения.Вставить("УспешныеЗамены", Новый Соответствие);
|
||
|
||
ОтключитьОбновлениеКлючейДоступа(Истина);
|
||
|
||
Попытка
|
||
|
||
КоличествоДублей = Дубли.Количество();
|
||
Номер = 1;
|
||
Для Каждого Дубль Из Дубли Цикл
|
||
|
||
БылиОшибки = Результат.ЕстьОшибки;
|
||
Результат.ЕстьОшибки = Ложь;
|
||
|
||
// @skip-check query-in-loop - Порционная обработка большого объема данных.
|
||
ЗаменитьСсылкиКороткимиТранзакциями(Результат, ПараметрыВыполнения, Дубль, ТаблицаПоиска);
|
||
|
||
Если НЕ Результат.ЕстьОшибки Тогда
|
||
ПараметрыВыполнения.УспешныеЗамены.Вставить(Дубль, ПараметрыВыполнения.ПарыЗамен[Дубль]);
|
||
КонецЕсли;
|
||
Результат.ЕстьОшибки = Результат.ЕстьОшибки ИЛИ БылиОшибки;
|
||
|
||
ДополнительныеПараметры = Новый Структура;
|
||
ДополнительныеПараметры.Вставить("НомерСеанса", НомерСеансаИнформационнойБазы());
|
||
ДополнительныеПараметры.Вставить("КоличествоОбработанных", Номер);
|
||
ДлительныеОперации.СообщитьПрогресс(Номер,
|
||
СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Замена дублей... обработано (%1 из %2)'"),
|
||
Номер, КоличествоДублей), ДополнительныеПараметры);
|
||
Номер = Номер + 1;
|
||
ДобавитьВСтатистикуЗаменыСсылок(Статистика, Дубль, Результат.ЕстьОшибки);
|
||
|
||
КонецЦикла;
|
||
|
||
ОбщегоНазначенияПереопределяемый.ПослеЗаменыСсылок(Результат, ПараметрыВыполнения, ТаблицаПоиска);
|
||
|
||
ОтключитьОбновлениеКлючейДоступа(Ложь);
|
||
|
||
Исключение
|
||
ОтключитьОбновлениеКлючейДоступа(Ложь);
|
||
ВызватьИсключение;
|
||
КонецПопытки;
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.УдалениеПомеченныхОбъектов")
|
||
И ПараметрыВыполнения.УдалятьНепосредственно Тогда
|
||
|
||
МодульУдалениеПомеченныхОбъектов = ОбщийМодуль("УдалениеПомеченныхОбъектов");
|
||
|
||
ДлительныеОперации.СообщитьПрогресс(0, НСтр("ru = 'Удаление дублей...'"));
|
||
РезультатУдаления = МодульУдалениеПомеченныхОбъектов.УдалитьПомеченныеОбъекты(Результат.ОчередьКНепосредственномуУдалению);
|
||
ЗарегистрироватьОшибкиУдаления(Результат, РезультатУдаления.ПрепятствующиеУдалению);
|
||
|
||
КонецЕсли;
|
||
|
||
ОтправитьСтатистикуЗаменыСсылок(Статистика);
|
||
|
||
Возврат Результат.Ошибки;
|
||
|
||
КонецФункции
|
||
|
||
// Конструктор структуры для параметра ПараметрыЗамены функции ОбщегоНазначения.ЗаменитьСсылки.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Структура:
|
||
// * СпособУдаления - Строка - указывает, что делать с дублем после успешной замены:
|
||
// "" - не предпринимать никаких действий (по умолчанию);
|
||
// "Пометка" - помечать на удаление;
|
||
// "Непосредственно" - удалять непосредственно.
|
||
// * УчитыватьПрикладныеПравила - Булево - если Истина, то для каждой пары "дубль-оригинал"
|
||
// вызывается функция ВозможностьЗаменыЭлементов модуля менеджера
|
||
// (требуется подсистема "Поиск и удаление дублей"). По умолчанию, Ложь.
|
||
// * ВключатьБизнесЛогику - Булево - режим записи объектов при замене в них ссылок дублей на оригиналы.
|
||
// Если Истина (по умолчанию), то места использования дублей записываются в обычном режиме,
|
||
// иначе запись ведется в режиме ОбменДанными.Загрузка = Истина.
|
||
// * ЗаменаПарыВТранзакции - Булево - устарел. определяет размер транзакции при замене дублей.
|
||
// Если Истина (по умолчанию), то все места использования одного дубля заменяются в одной транзакции.
|
||
// Это может быть очень ресурсоемко в случае большого количества мест использований.
|
||
// Если Ложь, то замена в каждом месте использования выполняется в отдельной транзакции.
|
||
// * ПривилегированнаяЗапись - Булево - если Истина, то устанавливать привилегированный режим перед запись
|
||
// объектов при замене в них ссылок дублей на оригиналы. По умолчанию Ложь.
|
||
//
|
||
Функция ПараметрыЗаменыСсылок() Экспорт
|
||
Результат = Новый Структура;
|
||
Результат.Вставить("СпособУдаления", "");
|
||
Результат.Вставить("УчитыватьПрикладныеПравила", Ложь);
|
||
Результат.Вставить("ВключатьБизнесЛогику", Истина);
|
||
Результат.Вставить("ЗаменаПарыВТранзакции", Ложь);
|
||
Результат.Вставить("ПривилегированнаяЗапись", Ложь);
|
||
Возврат Результат;
|
||
КонецФункции
|
||
|
||
// Получает все места использования ссылок.
|
||
// Если какая-либо ссылка нигде не используется, то строк для нее в результирующей таблице не будет.
|
||
// При вызове в неразделенном сеансе не выявляет ссылок в разделенных областях.
|
||
//
|
||
// Параметры:
|
||
// НаборСсылок - Массив из ЛюбаяСсылка - ссылки, для которых ищем места использования.
|
||
// АдресРезультата - Строка - адрес во временном хранилище, куда будет помещен копия результата замены.
|
||
// ДополнительныеПараметры - см. ОбщегоНазначения.ПараметрыПоискаМестИспользования
|
||
//
|
||
// Возвращаемое значение:
|
||
// ТаблицаЗначений:
|
||
// * Ссылка - ЛюбаяСсылка - ссылка, которая анализируется.
|
||
// * Данные - Произвольный - данные, содержащие анализируемую ссылку.
|
||
// * Метаданные - ОбъектМетаданных - метаданные найденных данных.
|
||
// * ПредставлениеДанных - Строка - представление данных, содержащих анализируемую ссылку.
|
||
// * ТипСсылки - Тип - тип анализируемой ссылки.
|
||
// * ВспомогательныеДанные - Булево - Истина, если данные используются анализируемой ссылкой как
|
||
// вспомогательные данные (ведущее измерение или попали в исключение ПриДобавленииИсключенийПоискаСсылок).
|
||
// * ЭтоСлужебныеДанные - Булево - данные попали в исключение ПриДобавленииИсключенийПоискаСсылок
|
||
//
|
||
Функция МестаИспользования(Знач НаборСсылок, Знач АдресРезультата = "", ДополнительныеПараметры = Неопределено) Экспорт
|
||
|
||
МестаИспользования = Новый ТаблицаЗначений;
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
МестаИспользования = НайтиПоСсылкам(НаборСсылок); // см. МестаИспользования.
|
||
УстановитьПривилегированныйРежим(Ложь);
|
||
|
||
// МестаИспользования - ТаблицаЗначений - где:
|
||
// * Ссылка - ЛюбаяСсылка - Ссылка, которая анализируется.
|
||
// * Данные - Произвольный - Данные, содержащие анализируемую ссылку.
|
||
// * Метаданные - ОбъектМетаданных - Метаданные найденных данных.
|
||
|
||
МестаИспользования.Колонки.Добавить("ПредставлениеДанных", Новый ОписаниеТипов("Строка"));
|
||
МестаИспользования.Колонки.Добавить("ТипСсылки");
|
||
МестаИспользования.Колонки.Добавить("ИнформацияОМестеИспользования");
|
||
МестаИспользования.Колонки.Добавить("ВспомогательныеДанные", Новый ОписаниеТипов("Булево"));
|
||
МестаИспользования.Колонки.Добавить("ЭтоСлужебныеДанные", Новый ОписаниеТипов("Булево"));
|
||
|
||
МестаИспользования.Индексы.Добавить("Ссылка");
|
||
МестаИспользования.Индексы.Добавить("Данные");
|
||
МестаИспользования.Индексы.Добавить("ВспомогательныеДанные");
|
||
МестаИспользования.Индексы.Добавить("Ссылка, ВспомогательныеДанные");
|
||
|
||
ТипКлючиЗаписей = ОписаниеТипаКлючиЗаписей();
|
||
ТипВсеСсылки = ОписаниеТипаВсеСсылки();
|
||
|
||
МетаданныеПоследовательностей = Метаданные.Последовательности;
|
||
МетаданныеКонстант = Метаданные.Константы;
|
||
МетаданныеДокументов = Метаданные.Документы;
|
||
|
||
ИсключенияПоискаСсылок = ИсключенияПоискаСсылок();
|
||
|
||
ДополнительныеИсключенияПоискаСсылок = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(
|
||
ДополнительныеПараметры,
|
||
"ДополнительныеИсключенияПоискаСсылок",
|
||
Новый Соответствие);
|
||
Для каждого МетаданныеРеквизитыИсключения Из ДополнительныеИсключенияПоискаСсылок Цикл
|
||
|
||
ЗначениеИсключения = ИсключенияПоискаСсылок[МетаданныеРеквизитыИсключения.Ключ];
|
||
Если ЗначениеИсключения = Неопределено Тогда
|
||
ИсключенияПоискаСсылок.Вставить(МетаданныеРеквизитыИсключения.Ключ,
|
||
МетаданныеРеквизитыИсключения.Значение);
|
||
Иначе
|
||
|
||
Если ТипЗнч(ЗначениеИсключения) = Тип("Массив") Тогда
|
||
ОбщегоНазначенияКлиентСервер.ДополнитьМассив(ЗначениеИсключения,
|
||
МетаданныеРеквизитыИсключения.Значение);
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
ОтменаИсключенийПоискаСсылок = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ДополнительныеПараметры,
|
||
"ОтменаИсключенийПоискаСсылок", Новый Массив);
|
||
Для каждого ОтменаИсключения Из ОтменаИсключенийПоискаСсылок Цикл
|
||
ИсключенияПоискаСсылок.Удалить(ОтменаИсключения);
|
||
КонецЦикла;
|
||
|
||
СлужебныеСвязиДанных = СлужебныеСвязиДанных(МестаИспользования, ИсключенияПоискаСсылок);
|
||
КэшИзмеренийРегистров = Новый Соответствие;
|
||
|
||
Для Каждого МестоИспользования Из МестаИспользования Цикл
|
||
ТипДанных = ТипЗнч(МестоИспользования.Данные);
|
||
|
||
ЭтоСлужебныеДанные = СлужебныеСвязиДанных[МестоИспользования] <> Неопределено;
|
||
ЭтоВспомогательныеДанные = ЭтоСлужебныеДанные;
|
||
|
||
Если ТипДанных = Неопределено Или МетаданныеДокументов.Содержит(МестоИспользования.Метаданные) Тогда
|
||
Представление = Строка(МестоИспользования.Данные);
|
||
|
||
ИначеЕсли МетаданныеКонстант.Содержит(МестоИспользования.Метаданные) Тогда
|
||
Представление = МестоИспользования.Метаданные.Представление() + " (" + НСтр("ru = 'константа'") + ")";
|
||
|
||
ИначеЕсли МетаданныеПоследовательностей.Содержит(МестоИспользования.Метаданные) Тогда
|
||
Представление = МестоИспользования.Метаданные.Представление() + " (" + НСтр("ru = 'последовательность'") + ")";
|
||
|
||
ИначеЕсли ТипВсеСсылки.СодержитТип(ТипДанных) Тогда
|
||
МетаПредставлениеОбъекта = Новый Структура("ПредставлениеОбъекта");
|
||
ЗаполнитьЗначенияСвойств(МетаПредставлениеОбъекта, МестоИспользования.Метаданные);
|
||
Если ПустаяСтрока(МетаПредставлениеОбъекта.ПредставлениеОбъекта) Тогда
|
||
МетаПредставление = МестоИспользования.Метаданные.Представление();
|
||
Иначе
|
||
МетаПредставление = МетаПредставлениеОбъекта.ПредставлениеОбъекта;
|
||
КонецЕсли;
|
||
Представление = Строка(МестоИспользования.Данные);
|
||
Если Не ПустаяСтрока(МетаПредставление) Тогда
|
||
Представление = Представление + " (" + МетаПредставление + ")";
|
||
КонецЕсли;
|
||
|
||
ИначеЕсли ТипКлючиЗаписей.СодержитТип(ТипДанных) Тогда
|
||
Представление = МестоИспользования.Метаданные.ПредставлениеЗаписи;
|
||
Если ПустаяСтрока(Представление) Тогда
|
||
Представление = МестоИспользования.Метаданные.Представление();
|
||
КонецЕсли;
|
||
|
||
ОписаниеИзмерений = Новый Массив;
|
||
Для Каждого МетаданныеРеквизитыИсключения Из ОписаниеИзмеренийНабора(МестоИспользования.Метаданные, КэшИзмеренийРегистров) Цикл
|
||
Значение = МестоИспользования.Данные[МетаданныеРеквизитыИсключения.Ключ];
|
||
Описание = МетаданныеРеквизитыИсключения.Значение;
|
||
Если МестоИспользования.Ссылка = Значение Тогда
|
||
Если Описание.Ведущее Тогда
|
||
ЭтоВспомогательныеДанные = Истина;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если Не ЭтоСлужебныеДанные Тогда // для оптимизации
|
||
ФорматЗначения = Описание.Формат;
|
||
ОписаниеИзмерений.Добавить(Описание.Представление + " """
|
||
+ ?(ФорматЗначения = Неопределено, Строка(Значение), Формат(Значение, ФорматЗначения)) + """");
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если ОписаниеИзмерений.Количество() > 0 Тогда
|
||
Представление = Представление + " (" + СтрСоединить(ОписаниеИзмерений, ", ") + ")";
|
||
КонецЕсли;
|
||
|
||
Иначе
|
||
Представление = Строка(МестоИспользования.Данные);
|
||
КонецЕсли;
|
||
|
||
МестоИспользования.ПредставлениеДанных = Представление;
|
||
МестоИспользования.ВспомогательныеДанные = ЭтоВспомогательныеДанные;
|
||
МестоИспользования.ЭтоСлужебныеДанные = ЭтоСлужебныеДанные;
|
||
МестоИспользования.ТипСсылки = ТипЗнч(МестоИспользования.Ссылка);
|
||
КонецЦикла;
|
||
|
||
Если Не ПустаяСтрока(АдресРезультата) Тогда
|
||
ПоместитьВоВременноеХранилище(МестаИспользования, АдресРезультата);
|
||
КонецЕсли;
|
||
|
||
Возврат МестаИспользования;
|
||
КонецФункции
|
||
|
||
// Возвращает структуру для параметра ДополнительныеПараметры функции ОбщегоНазначения.МестаИспользования.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Структура:
|
||
// * ДополнительныеИсключенияПоискаСсылок - Соответствие - позволяет расширить исключения поиска ссылок
|
||
// см. ОбщегоНазначенияПереопределяемый.ПриДобавленииИсключенийПоискаСсылок
|
||
// * ОтменаИсключенийПоискаСсылок - Массив из ОбъектМетаданных - полностью отменяет исключения поиска ссылок для
|
||
// объектов метаданных.
|
||
//
|
||
Функция ПараметрыПоискаМестИспользования() Экспорт
|
||
|
||
ПараметрыПоиска = Новый Структура;
|
||
ПараметрыПоиска.Вставить("ДополнительныеИсключенияПоискаСсылок", Новый Соответствие);
|
||
ПараметрыПоиска.Вставить("ОтменаИсключенийПоискаСсылок", Новый Соответствие);
|
||
|
||
Возврат ПараметрыПоиска;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает исключения при поиске мест использования объектов.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Соответствие из КлючИЗначение - исключения поиска ссылок в разрезе объектов метаданных:
|
||
// * Ключ - ОбъектМетаданных - объект метаданных, для которого применяются исключения.
|
||
// * Значение - Строка
|
||
// - Массив из Строка - описание исключенных реквизитов.
|
||
// Если "*", то исключены все реквизиты объекта метаданных.
|
||
// Если массив строк, то содержит относительные имена исключенных реквизитов.
|
||
//
|
||
Функция ИсключенияПоискаСсылок() Экспорт
|
||
|
||
ИсключенияПоискаИнтеграция = Новый Массив;
|
||
ИнтеграцияПодсистемБСП.ПриДобавленииИсключенийПоискаСсылок(ИсключенияПоискаИнтеграция);
|
||
|
||
ИсключенияПоиска = Новый Массив;
|
||
ОбщегоНазначенияКлиентСервер.ДополнитьМассив(ИсключенияПоиска, ИсключенияПоискаИнтеграция);
|
||
ОбщегоНазначенияПереопределяемый.ПриДобавленииИсключенийПоискаСсылок(ИсключенияПоиска);
|
||
|
||
Результат = Новый Соответствие;
|
||
Для Каждого ИсключениеПоиска Из ИсключенияПоиска Цикл
|
||
// Определение полного имени реквизита и объекта метаданных - носителя реквизита.
|
||
Если ТипЗнч(ИсключениеПоиска) = Тип("Строка") Тогда
|
||
ПолноеИмя = ИсключениеПоиска;
|
||
МассивПодстрок = СтрРазделить(ПолноеИмя, ".");
|
||
КоличествоПодстрок = МассивПодстрок.Количество();
|
||
ОбъектМетаданных = ОбъектМетаданныхПоПолномуИмени(МассивПодстрок[0] + "." + МассивПодстрок[1]);
|
||
Иначе
|
||
ОбъектМетаданных = ИсключениеПоиска;
|
||
ПолноеИмя = ОбъектМетаданных.ПолноеИмя();
|
||
МассивПодстрок = СтрРазделить(ПолноеИмя, ".");
|
||
КоличествоПодстрок = МассивПодстрок.Количество();
|
||
Если КоличествоПодстрок > 2 Тогда
|
||
Пока Истина Цикл
|
||
Родитель = ОбъектМетаданных.Родитель();
|
||
Если ТипЗнч(Родитель) = Тип("ОбъектМетаданныхКонфигурация") Тогда
|
||
Прервать;
|
||
Иначе
|
||
ОбъектМетаданных = Родитель;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
// Регистрация.
|
||
Если КоличествоПодстрок < 4 Тогда
|
||
Результат.Вставить(ОбъектМетаданных, "*");
|
||
Иначе
|
||
ПутиКРеквизитам = Результат.Получить(ОбъектМетаданных);
|
||
Если ПутиКРеквизитам = "*" Тогда
|
||
Продолжить; // Весь объект метаданных уже исключен.
|
||
ИначеЕсли ПутиКРеквизитам = Неопределено Тогда
|
||
ПутиКРеквизитам = Новый Массив;
|
||
Результат.Вставить(ОбъектМетаданных, ПутиКРеквизитам);
|
||
КонецЕсли;
|
||
// Формат реквизита:
|
||
// "<ВидОМ>.<ИмяОМ>.<ТипРеквизитаИлиТЧ>.<ИмяРеквизитаИлиТЧ>[.<ТипРеквизита>.<ИмяРеквизитаТЧ>]".
|
||
// Примеры:
|
||
// "РегистрСведений.ВерсииОбъектов.Реквизит.АвторВерсии",
|
||
// "Документ.ЗаказПокупателя.ТабличнаяЧасть.СчетаНаОплату.Реквизит.Счет",
|
||
// "ПланВидовРасчета.ОсновныеНачисления.СтандартнаяТабличнаяЧасть.БазовыеВидыРасчета.СтандартныйРеквизит.ВидРасчета".
|
||
// Относительный путь к реквизиту должен получиться таким, чтобы его можно было использовать в условиях запроса:
|
||
// "<ИмяРеквизитаИлиТЧ>[.<ИмяРеквизитаТЧ>]".
|
||
Если КоличествоПодстрок = 4 Тогда
|
||
ОтносительныйПутьКРеквизиту = МассивПодстрок[3];
|
||
Иначе
|
||
ОтносительныйПутьКРеквизиту = МассивПодстрок[3] + "." + МассивПодстрок[5];
|
||
КонецЕсли;
|
||
ПутиКРеквизитам.Добавить(ОтносительныйПутьКРеквизиту);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает связи подчиненных объектов и перечень реквизитов, по которым осуществляется связь.
|
||
//
|
||
// Есть возможность переопределить процедуру поиска подчиненных объектов.
|
||
// Для этого в общем модуле или модуле менеджера необходимо реализовать процедуру
|
||
// ПриПоискеЗаменыСсылок с параметрами:
|
||
// ПарыЗамен - Соответствие - содержит пары значение оригинал/дубль.
|
||
// НеобработанныеЗначенияОригиналов - Массив из Структура - дополнительная информация об обрабатываемых объектах:
|
||
// * ЗаменяемоеЗначение - ПроизвольнаяСсылка - оригинальное значение заменяемого объекта.
|
||
// * ИспользуемыеСвязи - см. ОбщегоНазначения.СвязиПодчиненныхОбъектовПоТипам
|
||
// * ЗначениеКлючевыхРеквизитов - Структура - где Ключ - имя реквизита, значение - значение реквизита.
|
||
//
|
||
// Возвращаемое значение:
|
||
// ТаблицаЗначений:
|
||
// * ПодчиненныйОбъект - ОбъектМетаданных - объект метаданных подчиненного объекта.
|
||
// * ПоляСвязей - Строка - имена реквизитов, определяющих связь между основными и подчиненными объектами.
|
||
// * ПриПоискеЗаменыСсылок - Строка - опционально. Имя общего модуля или модуля менеджера, в котором определена
|
||
// процедура ПриПоискеЗаменыСсылок.
|
||
// * ВыполнятьАвтоматическийПоискЗаменСсылок - Булево - если указать Истина, то будет выполнена попытка поиска замен
|
||
// для подчиненных объектов по значениям полей связи. В случае, если объект не существует,
|
||
// будет выполнена процедура ПриПоискеЗаменыСсылок. См. также ЗаменитьСсылки.
|
||
//
|
||
Функция ПодчиненныеОбъекты() Экспорт
|
||
|
||
ОписаниеСвязей = Новый ТаблицаЗначений;
|
||
ОписаниеСвязей.Колонки.Добавить("ПодчиненныйОбъект", Новый ОписаниеТипов("ОбъектМетаданных"));
|
||
ОписаниеСвязей.Колонки.Добавить("ПоляСвязей");
|
||
ОписаниеСвязей.Колонки.Добавить("ПриПоискеЗаменыСсылок", ОписаниеТипаСтрока(0));
|
||
ОписаниеСвязей.Колонки.Добавить("ВыполнятьАвтоматическийПоискЗаменСсылок", Новый ОписаниеТипов("Булево"));
|
||
|
||
ИнтеграцияПодсистемБСП.ПриОпределенииПодчиненныхОбъектов(ОписаниеСвязей);
|
||
ОбщегоНазначенияПереопределяемый.ПриОпределенииПодчиненныхОбъектов(ОписаниеСвязей);
|
||
|
||
// Если передали соответствие или структуру преобразуем к необходимому типу.
|
||
Для каждого СтрокаСвязи Из ОписаниеСвязей Цикл
|
||
|
||
ТипОписанияПолейСвязи = ТипЗнч(СтрокаСвязи.ПоляСвязей);
|
||
Если ТипОписанияПолейСвязи = Тип("Структура")
|
||
ИЛИ ТипОписанияПолейСвязи = Тип("Соответствие") Тогда
|
||
|
||
ПоляСвязейСтрокой = "";
|
||
Для каждого КлючЗначение Из СтрокаСвязи.ПоляСвязей Цикл
|
||
ПоляСвязейСтрокой = ПоляСвязейСтрокой + КлючЗначение.Ключ + ",";
|
||
КонецЦикла;
|
||
СтроковыеФункцииКлиентСервер.УдалитьПоследнийСимволВСтроке(ПоляСвязейСтрокой,1);
|
||
СтрокаСвязи.ПоляСвязей = ПоляСвязейСтрокой;
|
||
|
||
КонецЕсли;
|
||
|
||
Если ТипОписанияПолейСвязи = Тип("Массив") Тогда
|
||
СтрокаСвязи.ПоляСвязей = СтрСоединить(СтрокаСвязи.ПоляСвязей, ",");
|
||
КонецЕсли;
|
||
|
||
КонецЦикла;
|
||
|
||
Возврат ОписаниеСвязей;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает связи подчиненных объектов с указанием типа поля связи.
|
||
//
|
||
// Возвращаемое значение:
|
||
// ТаблицаЗначений:
|
||
// * Ключ - Строка
|
||
// * ТипРеквизита - Тип
|
||
// * ИмяРеквизита - Строка
|
||
// * Используется - Булево
|
||
// * Метаданные - ОбъектМетаданных
|
||
//
|
||
Функция СвязиПодчиненныхОбъектовПоТипам() Экспорт
|
||
|
||
Результат = Новый ТаблицаЗначений;
|
||
Результат.Колонки.Добавить("ТипРеквизита", Новый ОписаниеТипов("Тип"));
|
||
Результат.Колонки.Добавить("ИмяРеквизита", ОписаниеТипаСтрока(0));
|
||
Результат.Колонки.Добавить("Ключ", ОписаниеТипаСтрока(0));
|
||
Результат.Колонки.Добавить("Используется", Новый ОписаниеТипов("Булево"));
|
||
Результат.Колонки.Добавить("Метаданные");
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область УсловныеВызовы
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
// Процедуры и функции для вызова необязательных подсистем.
|
||
|
||
// Возвращает Истина, если функциональная подсистема существует в конфигурации.
|
||
// Предназначена для вызова необязательной подсистемы (условного вызова) совместно с ОбщегоНазначения.ОбщийМодуль.
|
||
//
|
||
// У функциональной подсистемы снят флажок "Включать в командный интерфейс".
|
||
// См. также ОбщегоНазначенияПереопределяемый.ПриОпределенииОтключенныхПодсистем
|
||
// и ОбщегоНазначенияКлиент.ПодсистемаСуществует для вызова из клиентского кода.
|
||
//
|
||
// Параметры:
|
||
// ПолноеИмяПодсистемы - Строка - полное имя объекта метаданных подсистема
|
||
// без слов "Подсистема." и с учетом регистра символов.
|
||
// Например: "СтандартныеПодсистемы.ВариантыОтчетов".
|
||
//
|
||
// Пример:
|
||
// Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ВариантыОтчетов") Тогда
|
||
// МодульВариантыОтчетов = ОбщегоНазначения.ОбщийМодуль("ВариантыОтчетов");
|
||
// МодульВариантыОтчетов.<Имя процедуры>();
|
||
// КонецЕсли;
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево
|
||
//
|
||
Функция ПодсистемаСуществует(ПолноеИмяПодсистемы) Экспорт
|
||
|
||
ИменаПодсистем = СтандартныеПодсистемыПовтИсп.ИменаПодсистем();
|
||
Возврат ИменаПодсистем.Получить(ПолноеИмяПодсистемы) <> Неопределено;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает ссылку на общий модуль или модуль менеджера по имени.
|
||
// Применяется для условного вызова процедуры или функции совместно с ОбщегоНазначения.ПодсистемаСуществует.
|
||
// См. также ОбщегоНазначенияКлиент.ОбщийМодуль для вызова клиентского кода.
|
||
//
|
||
// Параметры:
|
||
// Имя - Строка - имя общего модуля или модуля менеджера, например "ОбновлениеКонфигурации",
|
||
// "Обработка.ПолнотекстовыйПоиск".
|
||
//
|
||
// Возвращаемое значение:
|
||
// ОбщийМодуль
|
||
// МодульМенеджераОбъекта
|
||
//
|
||
// Пример:
|
||
// Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбновлениеКонфигурации") Тогда
|
||
// МодульОбновлениеКонфигурации = ОбщегоНазначения.ОбщийМодуль("ОбновлениеКонфигурации");
|
||
// МодульОбновлениеКонфигурации.<Имя процедуры>();
|
||
// КонецЕсли;
|
||
//
|
||
// Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ПолнотекстовыйПоиск") Тогда
|
||
// МодульОбработкаПолнотекстовыйПоиск = ОбщегоНазначения.ОбщийМодуль("Обработка.ПолнотекстовыйПоиск");
|
||
// МодульОбработкаПолнотекстовыйПоиск.<Имя процедуры>();
|
||
// КонецЕсли;
|
||
//
|
||
Функция ОбщийМодуль(Имя) Экспорт
|
||
|
||
Если Метаданные.ОбщиеМодули.Найти(Имя) <> Неопределено Тогда
|
||
// АПК:488-выкл ВычислитьВБезопасномРежиме не используется, чтобы избежать вызова ОбщийМодуль рекурсивно.
|
||
УстановитьБезопасныйРежим(Истина);
|
||
Модуль = Вычислить(Имя);
|
||
// АПК:488-вкл
|
||
ИначеЕсли СтрЧислоВхождений(Имя, ".") = 1 Тогда
|
||
Возврат СерверныйМодульМенеджера(Имя);
|
||
Иначе
|
||
Модуль = Неопределено;
|
||
КонецЕсли;
|
||
|
||
Если ТипЗнч(Модуль) <> Тип("ОбщийМодуль") Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверное значение параметра %1 в %2. Общий модуль ""%1"" не существует.'"),
|
||
"Имя", "ОбщегоНазначения.ОбщийМодуль", Имя),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
Возврат Модуль;
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область ТекущееОкружение
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
// Функции описания текущего окружения клиентского приложения и операционной системы.
|
||
|
||
// Возвращает Истина, если клиентское приложение запущено под управлением ОС Windows.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - если нет клиентского приложения, возвращается Ложь.
|
||
//
|
||
Функция ЭтоWindowsКлиент() Экспорт
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
ЭтоWindowsКлиент = СтандартныеПодсистемыСервер.ПараметрыКлиентаНаСервере().Получить("ЭтоWindowsКлиент");
|
||
|
||
Если ЭтоWindowsКлиент = Неопределено Тогда
|
||
Возврат Ложь; // Нет клиентского приложения.
|
||
КонецЕсли;
|
||
|
||
Возврат ЭтоWindowsКлиент;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает Истина, если текущий сеанс выполняется на сервере, работающем под управлением ОС Windows.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если сервер работает под управлением ОС Windows.
|
||
//
|
||
Функция ЭтоWindowsСервер() Экспорт
|
||
|
||
СистемнаяИнформация = Новый СистемнаяИнформация;
|
||
Возврат СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86
|
||
Или СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86_64;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает Истина, если клиентское приложение запущено под управлением ОС Linux.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - если нет клиентского приложения, возвращается Ложь.
|
||
//
|
||
Функция ЭтоLinuxКлиент() Экспорт
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
ЭтоLinuxКлиент = СтандартныеПодсистемыСервер.ПараметрыКлиентаНаСервере().Получить("ЭтоLinuxКлиент");
|
||
|
||
Если ЭтоLinuxКлиент = Неопределено Тогда
|
||
Возврат Ложь; // Нет клиентского приложения.
|
||
КонецЕсли;
|
||
|
||
Возврат ЭтоLinuxКлиент;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает Истина, если текущий сеанс выполняется на сервере, работающем под управлением ОС Linux.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если сервер работает под управлением ОС Linux.
|
||
//
|
||
Функция ЭтоLinuxСервер() Экспорт
|
||
|
||
СистемнаяИнформация = Новый СистемнаяИнформация;
|
||
Возврат СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Linux_x86
|
||
Или СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Linux_x86_64
|
||
Или ОбщегоНазначенияКлиентСервер.СравнитьВерсии(СистемнаяИнформация.ВерсияПриложения, "8.3.22.1923") >= 0
|
||
И (СистемнаяИнформация.ТипПлатформы = ТипПлатформы["Linux_ARM64"]
|
||
Или СистемнаяИнформация.ТипПлатформы = ТипПлатформы["Linux_E2K"]);
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает Истина, если клиентское приложение запущено под управлением macОС.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - если нет клиентского приложения, возвращается Ложь.
|
||
//
|
||
Функция ЭтоMacOSКлиент() Экспорт
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
ЭтоMacOSКлиент = СтандартныеПодсистемыСервер.ПараметрыКлиентаНаСервере().Получить("ЭтоMacOSКлиент");
|
||
|
||
Если ЭтоMacOSКлиент = Неопределено Тогда
|
||
Возврат Ложь; // Нет клиентского приложения.
|
||
КонецЕсли;
|
||
|
||
Возврат ЭтоMacOSКлиент;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает Истина, если клиентское приложение является Веб-клиентом.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - если нет клиентского приложения, возвращается Ложь.
|
||
//
|
||
Функция ЭтоВебКлиент() Экспорт
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
ЭтоВебКлиент = СтандартныеПодсистемыСервер.ПараметрыКлиентаНаСервере().Получить("ЭтоВебКлиент");
|
||
|
||
Если ЭтоВебКлиент = Неопределено Тогда
|
||
Возврат Ложь; // Нет клиентского приложения.
|
||
КонецЕсли;
|
||
|
||
Возврат ЭтоВебКлиент;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает Истина, если клиентское приложение является мобильным клиентом.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - если нет клиентского приложения, возвращается Ложь.
|
||
//
|
||
Функция ЭтоМобильныйКлиент() Экспорт
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
ЭтоМобильныйКлиент = СтандартныеПодсистемыСервер.ПараметрыКлиентаНаСервере().Получить("ЭтоМобильныйКлиент");
|
||
|
||
Если ЭтоМобильныйКлиент = Неопределено Тогда
|
||
Возврат Ложь; // Нет клиентского приложения.
|
||
КонецЕсли;
|
||
|
||
Возврат ЭтоМобильныйКлиент;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает Истина, если клиентское приложение подключено к базе через веб-сервер.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если подключен.
|
||
//
|
||
Функция КлиентПодключенЧерезВебСервер() Экспорт
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
СтрокаСоединенияИнформационнойБазы = СтандартныеПодсистемыСервер.ПараметрыКлиентаНаСервере().Получить("СтрокаСоединенияИнформационнойБазы");
|
||
|
||
Если СтрокаСоединенияИнформационнойБазы = Неопределено Тогда
|
||
Возврат Ложь; // Нет клиентского приложения.
|
||
КонецЕсли;
|
||
|
||
Возврат СтрНайти(ВРег(СтрокаСоединенияИнформационнойБазы), "WS=") = 1;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает системную информацию клиента, если есть клиентское приложение.
|
||
// До первого серверного вызова с клиента вернет Неопределено.
|
||
//
|
||
// Возвращаемое значение:
|
||
// ФиксированнаяСтруктура:
|
||
// * ВерсияОС - Строка
|
||
// * ВерсияПриложения - Строка
|
||
// * ИдентификаторКлиента - УникальныйИдентификатор
|
||
// * ИнформацияПрограммыПросмотра - Строка
|
||
// * ОперативнаяПамять - Число
|
||
// * Процессор - Строка
|
||
// * ТипПлатформы - см. ОбщегоНазначенияКлиентСервер.ИмяТипаПлатформы
|
||
// Неопределено - если нет клиентского приложения или информация запрашивается
|
||
// до первого серверного вызова, например, при первом вызове события
|
||
// платформы УстановкаПараметровСеанса в модуле сеанса.
|
||
//
|
||
Функция СистемнаяИнформацияКлиента() Экспорт
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
Возврат СтандартныеПодсистемыСервер.ПараметрыКлиентаНаСервере().Получить("СистемнаяИнформация");
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает имя используемого клиента, а для веб-браузера название и версию, если есть.
|
||
// До первого серверного вызова с клиента вернет Неопределено.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - варианты строк "ВебКлиент.<Название>[.<Версия>]", "ТонкийКлиент",
|
||
// "ТолстыйКлиентУправляемоеПриложение", "ТолстыйКлиентОбычноеПриложение",
|
||
// где <Название> - варианты строк "Chrome", "Firefox", "Safari", "IE", "Opera"
|
||
// или "Другой", когда не определен (ни один из указанных), например "ВебКлиент.Chrome.109".
|
||
// Неопределено - если нет клиентского приложения или информация запрашивается
|
||
// до первого серверного вызова, например, при первом вызове события
|
||
// платформы УстановкаПараметровСеанса в модуле сеанса.
|
||
//
|
||
Функция ИспользуемыйКлиент() Экспорт
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
Возврат СтандартныеПодсистемыСервер.ПараметрыКлиентаНаСервере().Получить("ИспользуемыйКлиент");
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает Истина, если включен режим отладки.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если включен режим отладки.
|
||
//
|
||
Функция РежимОтладки() Экспорт
|
||
|
||
ПараметрЗапускаПриложения = СтандартныеПодсистемыСервер.ПараметрыКлиентаНаСервере(Ложь).Получить("ПараметрЗапуска");
|
||
|
||
Возврат СтрНайти(ПараметрЗапускаПриложения, "РежимОтладки") > 0;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает объем оперативной памяти, доступной клиентскому приложению.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Число - количество гигабайтов оперативной памяти с точностью до десятых долей.
|
||
// Неопределено - нет клиентского приложения, то есть ТекущийРежимЗапуска() = Неопределено.
|
||
//
|
||
Функция ОперативнаяПамятьДоступнаяКлиентскомуПриложению() Экспорт
|
||
|
||
ДоступныйОбъем = СтандартныеПодсистемыСервер.ПараметрыКлиентаНаСервере().Получить("ОперативнаяПамять");
|
||
Возврат ДоступныйОбъем;
|
||
|
||
КонецФункции
|
||
|
||
// Определяет режим эксплуатации информационной базы файловый (Истина) или серверный (Ложь).
|
||
// При проверке используется СтрокаСоединенияИнформационнойБазы, которую можно указать явно.
|
||
//
|
||
// Параметры:
|
||
// СтрокаСоединенияИнформационнойБазы - Строка - параметр используется, если
|
||
// нужно проверить строку соединения не текущей информационной базы.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если файловая.
|
||
//
|
||
Функция ИнформационнаяБазаФайловая(Знач СтрокаСоединенияИнформационнойБазы = "") Экспорт
|
||
|
||
Если ПустаяСтрока(СтрокаСоединенияИнформационнойБазы) Тогда
|
||
Возврат СтандартныеПодсистемыПовтИсп.ИнформационнаяБазаФайловая();
|
||
КонецЕсли;
|
||
|
||
Возврат СтрНайти(ВРег(СтрокаСоединенияИнформационнойБазы), "FILE=") = 1;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает Истина, если эта информационная база подключена к 1С:Fresh.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - признак автономного рабочего места.
|
||
//
|
||
Функция ЭтоАвтономноеРабочееМесто() Экспорт
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными") Тогда
|
||
МодульОбменДаннымиСервер = ОбщийМодуль("ОбменДаннымиСервер");
|
||
Возврат МодульОбменДаннымиСервер.ЭтоАвтономноеРабочееМесто();
|
||
КонецЕсли;
|
||
|
||
Возврат Ложь;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает признак того, что информационная база является распределенной (РИБ).
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево
|
||
//
|
||
Функция ЭтоРаспределеннаяИнформационнаяБаза() Экспорт
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
Возврат СтандартныеПодсистемыПовтИсп.ИспользуетсяРИБ();
|
||
|
||
КонецФункции
|
||
|
||
// Определяет, что эта информационная база является подчиненным узлом
|
||
// распределенной информационной базы (РИБ).
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если эта информационная база является подчиненным узлом РИБ.
|
||
//
|
||
Функция ЭтоПодчиненныйУзелРИБ() Экспорт
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
Возврат ПланыОбмена.ГлавныйУзел() <> Неопределено;
|
||
|
||
КонецФункции
|
||
|
||
// Определяет, что эта информационная база является подчиненным узлом
|
||
// распределенной информационной базы (РИБ) с фильтром.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если эта информационная база является подчиненным узлом РИБ с фильтром.
|
||
//
|
||
Функция ЭтоПодчиненныйУзелРИБСФильтром() Экспорт
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
Если ПланыОбмена.ГлавныйУзел() <> Неопределено
|
||
И ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными") Тогда
|
||
МодульОбменДаннымиСервер = ОбщийМодуль("ОбменДаннымиСервер");
|
||
Если МодульОбменДаннымиСервер.НазначениеПланаОбмена(ПланыОбмена.ГлавныйУзел().Метаданные().Имя) = "РИБСФильтром" Тогда
|
||
Возврат Истина;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Возврат Ложь;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает Истина при необходимости обновления конфигурации информационной базы подчиненного узла РИБ.
|
||
// В главном узле всегда Ложь.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если требуется.
|
||
//
|
||
Функция ТребуетсяОбновлениеКонфигурацииПодчиненногоУзлаРИБ() Экспорт
|
||
|
||
Возврат ЭтоПодчиненныйУзелРИБ() И КонфигурацияИзменена();
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает признак работы в режиме разделения данных по областям
|
||
// (технически это признак условного разделения).
|
||
//
|
||
// Возвращает Ложь, если конфигурация не может работать в режиме разделения данных
|
||
// (не содержит общих реквизитов, предназначенных для разделения данных).
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если разделение включено,
|
||
// Ложь, если разделение выключено или не поддерживается.
|
||
//
|
||
Функция РазделениеВключено() Экспорт
|
||
|
||
Возврат СтандартныеПодсистемыПовтИсп.РазделениеВключено();
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает признак возможности обращения к разделенным данным (которые входят в состав разделителей).
|
||
// Признак относится к сеансу, но может меняться во время работы сеанса, если разделение было включено
|
||
// в самом сеансе, поэтому проверку следует делать непосредственно перед обращением к разделенным данным.
|
||
//
|
||
// Возвращает Истина, если конфигурация не может работать в режиме разделения данных
|
||
// (не содержит общих реквизитов, предназначенных для разделения данных).
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если разделение не поддерживается, либо разделение выключено,
|
||
// либо разделение включено и разделители установлены.
|
||
// Ложь, если разделение включено и разделители не установлены.
|
||
//
|
||
Функция ДоступноИспользованиеРазделенныхДанных() Экспорт
|
||
|
||
Возврат СтандартныеПодсистемыПовтИсп.ДоступноИспользованиеРазделенныхДанных();
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает адрес публикации информационной базы для формирования прямых ссылок на объекты ИБ
|
||
// для возможности перехода к ним пользователей, имеющих доступ к базе через публикацию в сети Интернет.
|
||
// Например, если такой адрес включить в электронное письмо, то из письма одним нажатием
|
||
// можно перейти к форме объекта в самой программе.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - адрес информационной базы, как он задан в настройке "Адрес в Интернете" в панели администрирования
|
||
// (хранится в константе АдресПубликацииИнформационнойБазыВИнтернете).
|
||
// Например, "http://1c.com/database".
|
||
//
|
||
// Пример:
|
||
// ОбщегоНазначения.АдресПубликацииИнформационнойБазыВЛокальнойСети() + "/" + e1cib/app/Обработка.ВыгрузкаДанныхПроекта";
|
||
// возвращает прямую ссылку для открытия обработки ВыгрузкаДанныхПроекта.
|
||
//
|
||
Функция АдресПубликацииИнформационнойБазыВИнтернете() Экспорт
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
Результат = Константы.АдресПубликацииИнформационнойБазыВИнтернете.Получить();
|
||
Если РазделениеВключено() И ДоступноИспользованиеРазделенныхДанных() Тогда
|
||
Если ПустаяСтрока(Результат)
|
||
И ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность")
|
||
И ПодсистемаСуществует("ТехнологияСервиса.ВнешнийПрограммныйИнтерфейс") Тогда
|
||
|
||
МодульРаботаВМоделиСервиса = ОбщийМодуль("РаботаВМоделиСервиса");
|
||
МодульПрограммныйИнтерфейсСервиса = ОбщийМодуль("ПрограммныйИнтерфейсСервиса");
|
||
РазделительСеанса = МодульРаботаВМоделиСервиса.ЗначениеРазделителяСеанса();
|
||
Попытка
|
||
Результат = МодульПрограммныйИнтерфейсСервиса.СвойстваПриложения(РазделительСеанса).АдресПриложения;
|
||
Исключение
|
||
ЗаписьЖурналаРегистрации(НСтр("ru = 'Адрес публикации приложения'", КодОсновногоЯзыка()), // АПК:154 Не считаем ошибкой проблемы недоступности Менеджера сервиса.
|
||
УровеньЖурналаРегистрации.Предупреждение,,,
|
||
ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
|
||
Возврат "";
|
||
КонецПопытки;
|
||
Константы.АдресПубликацииИнформационнойБазыВИнтернете.Установить(Результат);
|
||
КонецЕсли;
|
||
Возврат Результат;
|
||
КонецЕсли;
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает адрес публикации информационной базы для формирования прямых ссылок на объекты ИБ
|
||
// для возможности перехода к ним пользователей, имеющих доступ к базе через публикацию локальной сети.
|
||
// Например, если такой адрес включить в электронное письмо, то из письма за одно нажатие
|
||
// можно перейти к форме объекта в самой программе.
|
||
//
|
||
// При работе в приложении в Интернете возвращает значение функции АдресПубликацииИнформационнойБазыВИнтернете.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - адрес информационной базы, как он задан в настройке "Локальный адрес" в панели администрирования
|
||
// (хранится в константе АдресПубликацииИнформационнойБазыВЛокальнойСети).
|
||
// Например, "http://localserver/base".
|
||
//
|
||
// Пример:
|
||
// ОбщегоНазначения.АдресПубликацииИнформационнойБазыВЛокальнойСети() + "/" + e1cib/app/Обработка.ВыгрузкаДанныхПроекта";
|
||
// возвращает прямую ссылку для открытия обработки ВыгрузкаДанныхПроекта.
|
||
//
|
||
Функция АдресПубликацииИнформационнойБазыВЛокальнойСети() Экспорт
|
||
|
||
Если РазделениеВключено() И ДоступноИспользованиеРазделенныхДанных() Тогда
|
||
Возврат АдресПубликацииИнформационнойБазыВИнтернете();
|
||
КонецЕсли;
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
Возврат Константы.АдресПубликацииИнформационнойБазыВЛокальнойСети.Получить();
|
||
|
||
КонецФункции
|
||
|
||
// Формирует ссылку для входа в программу для указанного пользователя.
|
||
//
|
||
// Параметры:
|
||
// Пользователь - Строка - логин пользователя для входа в программу;
|
||
// Пароль - Строка - пароль пользователя для входа в программу;
|
||
// ВидПубликацииИБ - Строка - через какую публикацию пользователь входит в программу:
|
||
// "ВИнтернете" или "ВЛокальнойСети".
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка, Неопределено - адрес входа в программу или Неопределено, если адрес не настроен.
|
||
//
|
||
Функция АдресВходаВПрограмму(Пользователь, Пароль, ВидПубликацииИБ) Экспорт
|
||
|
||
Результат = "";
|
||
|
||
Если НРег(ВидПубликацииИБ) = НРег("ВИнтернете") Тогда
|
||
Результат = АдресПубликацииИнформационнойБазыВИнтернете();
|
||
ИначеЕсли НРег(ВидПубликацииИБ) = НРег("ВЛокальнойСети") Тогда
|
||
Результат = АдресПубликацииИнформационнойБазыВЛокальнойСети();
|
||
КонецЕсли;
|
||
|
||
Если ПустаяСтрока(Результат) Тогда
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
|
||
Если Не СтрЗаканчиваетсяНа(Результат, "/") Тогда
|
||
Результат = Результат + "/";
|
||
КонецЕсли;
|
||
|
||
Результат = Результат + "?n=" + КодироватьСтроку(Пользователь, СпособКодированияСтроки.КодировкаURL);
|
||
Если ЗначениеЗаполнено(Пароль) Тогда
|
||
Результат = Результат + "&p=" + КодироватьСтроку(Пароль, СпособКодированияСтроки.КодировкаURL);
|
||
КонецЕсли;
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает редакцию конфигурации.
|
||
// Редакцией принято называть две первые группы цифр полной версии конфигурации.
|
||
// Например, у версии "1.2.3.4" редакция "1.2".
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - номер редакции конфигурации.
|
||
//
|
||
Функция РедакцияКонфигурации() Экспорт
|
||
|
||
Результат = "";
|
||
ВерсияКонфигурации = Метаданные.Версия;
|
||
|
||
Позиция = СтрНайти(ВерсияКонфигурации, ".");
|
||
Если Позиция > 0 Тогда
|
||
Результат = Лев(ВерсияКонфигурации, Позиция);
|
||
ВерсияКонфигурации = Сред(ВерсияКонфигурации, Позиция + 1);
|
||
Позиция = СтрНайти(ВерсияКонфигурации, ".");
|
||
Если Позиция > 0 Тогда
|
||
Результат = Результат + Лев(ВерсияКонфигурации, Позиция - 1);
|
||
Иначе
|
||
Результат = "";
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Если ПустаяСтрока(Результат) Тогда
|
||
Результат = Метаданные.Версия;
|
||
КонецЕсли;
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает общие параметры работы.
|
||
//
|
||
// Параметры:
|
||
// ВернутьЗакешированноеЗначение - Булево - служебный параметр.
|
||
//
|
||
// Возвращаемое значение:
|
||
// см. ОбщегоНазначенияПереопределяемый.ПриОпределенииОбщихПараметровБазовойФункциональности.ОбщиеПараметры
|
||
//
|
||
Функция ОбщиеПараметрыБазовойФункциональности(ВернутьЗакешированноеЗначение = Истина) Экспорт
|
||
|
||
Если ВернутьЗакешированноеЗначение Тогда
|
||
Возврат СтандартныеПодсистемыПовтИсп.ОбщиеПараметрыБазовойФункциональности();
|
||
КонецЕсли;
|
||
|
||
Результат = Новый Структура;
|
||
Результат.Вставить("ИмяФормыПерсональныхНастроек", "");
|
||
Результат.Вставить("ЗапрашиватьПодтверждениеПриЗавершенииПрограммы", Истина);
|
||
Результат.Вставить("РекомендуемыйОбъемОперативнойПамяти", 4);
|
||
Результат.Вставить("МинимальнаяВерсияПлатформы", МинимальнаяВерсияПлатформы());
|
||
Результат.Вставить("РекомендуемаяВерсияПлатформы", Результат.МинимальнаяВерсияПлатформы);
|
||
Результат.Вставить("ВыводитьПолныйСтекПриОшибкеДлительнойОперации", Ложь);
|
||
Результат.Вставить("ОтключитьИдентификаторыОбъектовМетаданных", Ложь);
|
||
// Устарело, следует использовать свойства МинимальнаяВерсияПлатформы и РекомендуемаяВерсияПлатформы:
|
||
Результат.Вставить("МинимальноНеобходимаяВерсияПлатформы", "");
|
||
Результат.Вставить("РаботаВПрограммеЗапрещена", Ложь); // Блокировать запуск, если версия ниже минимальной.
|
||
|
||
ОбщегоНазначенияПереопределяемый.ПриОпределенииОбщихПараметровБазовойФункциональности(Результат);
|
||
Результат.МинимальнаяВерсияПлатформы = НомерСборкиПоТекущейВерсииПлатформы(Результат.МинимальнаяВерсияПлатформы);
|
||
Результат.РекомендуемаяВерсияПлатформы = НомерСборкиПоТекущейВерсииПлатформы(Результат.РекомендуемаяВерсияПлатформы);
|
||
|
||
// Локализация
|
||
УточнитьМинимальнуюВерсиюПлатформыИзСервиса(Результат);
|
||
// Конец Локализация
|
||
|
||
СистемнаяИнформация = Новый СистемнаяИнформация;
|
||
Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(СистемнаяИнформация.ВерсияПриложения, Результат.МинимальнаяВерсияПлатформы) < 0
|
||
И ЭтоВерсияЗащищенногоПрограммногоКомплекса(СистемнаяИнформация.ВерсияПриложения) Тогда
|
||
Результат.МинимальнаяВерсияПлатформы = СистемнаяИнформация.ВерсияПриложения;
|
||
Результат.РекомендуемаяВерсияПлатформы = СистемнаяИнформация.ВерсияПриложения;
|
||
КонецЕсли;
|
||
|
||
Минимальная = Результат.МинимальнаяВерсияПлатформы;
|
||
Рекомендуемая = Результат.РекомендуемаяВерсияПлатформы;
|
||
Если МинимальнаяИРекомендуемаяВерсияПлатформыЗаполненаНеПравильно(Минимальная, Рекомендуемая) Тогда
|
||
ТекстСообщения = НСтр("ru = 'Указанные в %1 минимальная и рекомендуемая версии платформы не соответствуют следующим требованиям:
|
||
| - минимальная версия должна быть заполнена;
|
||
| - минимальная версия не должна быть меньше минимальной версии БСП (см. %2);
|
||
| - минимальная версия не должна быть меньше рекомендуемой версии.
|
||
|Минимальная версия: %3
|
||
|Минимальная версия БСП: %4
|
||
|Рекомендуемая версия: %5'",
|
||
КодОсновногоЯзыка());
|
||
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстСообщения,
|
||
"ОбщегоНазначенияПереопределяемый.ПриОпределенииОбщихПараметровБазовойФункциональности",
|
||
"ОбщегоНазначения.МинимальнаяВерсияПлатформы",
|
||
Минимальная, НомерСборкиПоТекущейВерсииПлатформы(МинимальнаяВерсияПлатформы()), Рекомендуемая);
|
||
ЗаписьЖурналаРегистрации(НСтр("ru = 'Базовая функциональность'", КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Предупреждение,,,
|
||
ТекстСообщения);
|
||
КонецЕсли;
|
||
|
||
// Обратная совместимость.
|
||
МинимальноНеобходимаяВерсияПлатформы = Результат.МинимальноНеобходимаяВерсияПлатформы;
|
||
Если ЗначениеЗаполнено(МинимальноНеобходимаяВерсияПлатформы) Тогда
|
||
Если Результат.РаботаВПрограммеЗапрещена Тогда
|
||
Результат.МинимальнаяВерсияПлатформы = МинимальноНеобходимаяВерсияПлатформы;
|
||
Результат.РекомендуемаяВерсияПлатформы = "";
|
||
Иначе
|
||
Результат.РекомендуемаяВерсияПлатформы = МинимальноНеобходимаяВерсияПлатформы;
|
||
Результат.МинимальнаяВерсияПлатформы = "";
|
||
КонецЕсли;
|
||
Иначе
|
||
Текущая = СистемнаяИнформация.ВерсияПриложения;
|
||
Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(Минимальная, Текущая) > 0 Тогда
|
||
Результат.МинимальноНеобходимаяВерсияПлатформы = Минимальная;
|
||
Результат.РаботаВПрограммеЗапрещена = Истина;
|
||
Иначе
|
||
Результат.МинимальноНеобходимаяВерсияПлатформы = Рекомендуемая;
|
||
Результат.РаботаВПрограммеЗапрещена = Ложь;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
УточнитьВерсиюПлатформы(Результат);
|
||
|
||
Возврат Результат;
|
||
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает описания всех библиотек конфигурации, включая
|
||
// описание самой конфигурации.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Массив - структур со свойствами:
|
||
// * Имя - Строка - имя подсистемы, например, "СтандартныеПодсистемы".
|
||
// * ИдентификаторИнтернетПоддержки - Строка - уникальное имя программы в сервисах интернет-поддержки.
|
||
// * Версия - Строка - версия в формате из четырех цифр, например "2.3.3.1".
|
||
// * ЭтоКонфигурация - Булево - признак того, что данная подсистема является основной конфигурацией.
|
||
//
|
||
Функция ОписанияПодсистем() Экспорт
|
||
Результат = Новый Массив;
|
||
ОписанияПодсистем = СтандартныеПодсистемыПовтИсп.ОписанияПодсистем();
|
||
Для Каждого ОписаниеПодсистемы Из ОписанияПодсистем.ПоИменам Цикл
|
||
Параметры = Новый Структура;
|
||
Параметры.Вставить("Имя");
|
||
Параметры.Вставить("ИдентификаторИнтернетПоддержки");
|
||
Параметры.Вставить("Версия");
|
||
Параметры.Вставить("ЭтоКонфигурация");
|
||
|
||
ЗаполнитьЗначенияСвойств(Параметры, ОписаниеПодсистемы.Значение);
|
||
Результат.Добавить(Параметры);
|
||
КонецЦикла;
|
||
|
||
Возврат Результат;
|
||
КонецФункции
|
||
|
||
// Возвращает идентификатор Интернет-поддержки основной конфигурации.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - уникальное имя программы в сервисах Интернет-поддержки.
|
||
//
|
||
Функция ИдентификаторИнтернетПоддержкиКонфигурации() Экспорт
|
||
ОписанияПодсистем = СтандартныеПодсистемыПовтИсп.ОписанияПодсистем();
|
||
Для Каждого ОписаниеПодсистемы Из ОписанияПодсистем.ПоИменам Цикл
|
||
Если ОписаниеПодсистемы.Значение.ЭтоКонфигурация Тогда
|
||
Возврат ОписаниеПодсистемы.Значение.ИдентификаторИнтернетПоддержки;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат "";
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область Даты
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
// Функции для работы с датами с учетом часового пояса сеанса
|
||
|
||
// Преобразует локальную дату к формату "YYYY-MM-DDThh:mm:ssTZD" согласно ISO 8601.
|
||
//
|
||
// Параметры:
|
||
// ЛокальнаяДата - Дата - дата в часовом поясе сеанса.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - представление даты.
|
||
//
|
||
Функция ПредставлениеЛокальнойДатыСоСмещением(ЛокальнаяДата) Экспорт
|
||
|
||
Смещение = СмещениеСтандартногоВремени(ЧасовойПоясСеанса());
|
||
Возврат ОбщегоНазначенияСлужебныйКлиентСервер.ПредставлениеЛокальнойДатыСоСмещением(ЛокальнаяДата, Смещение);
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает строковое представление интервала между переданными датами или
|
||
// относительно переданной даты и текущей даты сеанса.
|
||
//
|
||
// Параметры:
|
||
// ВремяНачала - Дата - начальная точка интервала.
|
||
// ВремяОкончания - Дата - конечная точка интервала, если не задана - берется текущая дата сеанса.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - представление интервала времени.
|
||
//
|
||
Функция ИнтервалВремениСтрокой(ВремяНачала, ВремяОкончания = Неопределено) Экспорт
|
||
|
||
Если ВремяОкончания = Неопределено Тогда
|
||
ВремяОкончания = ТекущаяДатаСеанса();
|
||
ИначеЕсли ВремяНачала > ВремяОкончания Тогда
|
||
ВызватьИсключение НСтр("ru = 'Дата окончания интервала не может быть меньше даты начала.'");
|
||
КонецЕсли;
|
||
|
||
ВеличинаИнтервала = ВремяОкончания - ВремяНачала;
|
||
ВеличинаИнтервалаВДнях = Цел(ВеличинаИнтервала/60/60/24);
|
||
|
||
Если ВеличинаИнтервалаВДнях > 365 Тогда
|
||
ОписаниеИнтервала = НСтр("ru = 'более года'");
|
||
ИначеЕсли ВеличинаИнтервалаВДнях > 31 Тогда
|
||
ОписаниеИнтервала = НСтр("ru = 'более месяца'");
|
||
ИначеЕсли ВеличинаИнтервалаВДнях >= 1 Тогда
|
||
ОписаниеИнтервала = Формат(ВеличинаИнтервалаВДнях, "ЧДЦ=0") + " "
|
||
+ ПользователиСлужебныйКлиентСервер.ПредметЦелогоЧисла(ВеличинаИнтервалаВДнях,
|
||
"", НСтр("ru = 'день,дня,дней,,,,,,0'"));
|
||
Иначе
|
||
ОписаниеИнтервала = НСтр("ru = 'менее одного дня'");
|
||
КонецЕсли;
|
||
|
||
Возврат ОписаниеИнтервала;
|
||
|
||
КонецФункции
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
// Функции для работы с настройкой рабочей даты.
|
||
|
||
// Сохраняет настройку рабочей даты пользователя.
|
||
//
|
||
// Параметры:
|
||
// НоваяРабочаяДата - Дата - дата, которую необходимо установить в качестве рабочей даты пользователя.
|
||
// ИмяПользователя - Строка - имя пользователя, для которого устанавливается рабочая дата.
|
||
// Если не задано, то устанавливается для текущего пользователя.
|
||
//
|
||
Процедура УстановитьРабочуюДатуПользователя(НоваяРабочаяДата, ИмяПользователя = Неопределено) Экспорт
|
||
|
||
КлючОбъекта = ВРег("РабочаяДата");
|
||
|
||
ХранилищеОбщихНастроекСохранить(КлючОбъекта, "", НоваяРабочаяДата, , ИмяПользователя);
|
||
|
||
КонецПроцедуры
|
||
|
||
// Возвращает значение настройки рабочей даты для пользователя.
|
||
//
|
||
// Параметры:
|
||
// ИмяПользователя - Строка - имя пользователя, для которого запрашивается рабочая дата.
|
||
// Если не задано, то устанавливается для текущего пользователя.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Дата - значение настройки рабочей даты пользователя или пустая дата, если настройка не задана.
|
||
//
|
||
Функция РабочаяДатаПользователя(ИмяПользователя = Неопределено) Экспорт
|
||
|
||
КлючОбъекта = ВРег("РабочаяДата");
|
||
|
||
Результат = ХранилищеОбщихНастроекЗагрузить(КлючОбъекта, "", '0001-01-01', , ИмяПользователя);
|
||
|
||
Если ТипЗнч(Результат) <> Тип("Дата") Тогда
|
||
Результат = '0001-01-01';
|
||
КонецЕсли;
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает значение настройки рабочей даты для пользователя или текущей даты сеанса,
|
||
// если рабочая дата пользователя не задана.
|
||
//
|
||
// Параметры:
|
||
// ИмяПользователя - Строка - имя пользователя, для которого запрашивается рабочая дата.
|
||
// Если не задано, то устанавливается для текущего пользователя.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Дата - значение настройки рабочей даты пользователя или текущая дата сеанса, если настройка не задана.
|
||
//
|
||
Функция ТекущаяДатаПользователя(ИмяПользователя = Неопределено) Экспорт
|
||
|
||
Результат = РабочаяДатаПользователя(ИмяПользователя);
|
||
|
||
Если НЕ ЗначениеЗаполнено(Результат) Тогда
|
||
Результат = ТекущаяДатаСеанса();
|
||
КонецЕсли;
|
||
|
||
Возврат НачалоДня(Результат);
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область Данные
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
// Общие процедуры и функции для работы с прикладными типами и коллекциями значений.
|
||
|
||
// Возвращает строковое имя значения перечисления по его ссылке.
|
||
// Вызывает исключение, если передано несуществующее значение перечисления
|
||
// (например, удаленное в конфигурации или от отключенного расширения конфигурации).
|
||
//
|
||
// Параметры:
|
||
// Значение - ПеречислениеСсылка - значение, для которого необходимо получить имя перечисления.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка
|
||
//
|
||
// Пример:
|
||
// В результат будет помещено строковое значение "ФизическоеЛицо":
|
||
// Результат = ОбщегоНазначения.ИмяЗначенияПеречисления(Перечисления.ЮридическоеФизическоеЛицо.ФизическоеЛицо);
|
||
//
|
||
Функция ИмяЗначенияПеречисления(Значение) Экспорт
|
||
|
||
ОбъектМетаданных = Значение.Метаданные();
|
||
ИндексЗначения = Перечисления[ОбъектМетаданных.Имя].Индекс(Значение);
|
||
Возврат ОбъектМетаданных.ЗначенияПеречисления[ИндексЗначения].Имя;
|
||
|
||
КонецФункции
|
||
|
||
// Процедура удаляет из массива МассивРеквизитов элементы, соответствующие именам
|
||
// реквизитов объекта из массива МассивНепроверяемыхРеквизитов.
|
||
// Для использования в обработчиках события ОбработкаПроверкиЗаполнения.
|
||
//
|
||
// Параметры:
|
||
// МассивРеквизитов - Массив - коллекция имен реквизитов объекта.
|
||
// МассивНепроверяемыхРеквизитов - Массив - коллекция имен реквизитов объекта, не требующих проверки.
|
||
//
|
||
Процедура УдалитьНепроверяемыеРеквизитыИзМассива(МассивРеквизитов, МассивНепроверяемыхРеквизитов) Экспорт
|
||
|
||
Для Каждого ЭлементМассива Из МассивНепроверяемыхРеквизитов Цикл
|
||
|
||
ПорядковыйНомер = МассивРеквизитов.Найти(ЭлементМассива);
|
||
Если ПорядковыйНомер <> Неопределено Тогда
|
||
МассивРеквизитов.Удалить(ПорядковыйНомер);
|
||
КонецЕсли;
|
||
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Преобразует таблицу значений в массив структур.
|
||
// Может использоваться для передачи на клиент данных в том случае, если таблица
|
||
// значений содержит только такие значения, которые могут
|
||
// быть переданы с сервера на клиент.
|
||
//
|
||
// Полученный массив содержит структуры, каждая из которых повторяет
|
||
// структуру колонок таблицы значений.
|
||
//
|
||
// Не рекомендуется использовать для преобразования таблиц значений
|
||
// с большим количеством строк.
|
||
//
|
||
// Параметры:
|
||
// ТаблицаЗначений - ТаблицаЗначений - исходная таблица значений.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Массив - коллекция строк таблицы в виде структур.
|
||
//
|
||
Функция ТаблицаЗначенийВМассив(ТаблицаЗначений) Экспорт
|
||
|
||
Массив = Новый Массив();
|
||
СтруктураСтрокой = "";
|
||
НужнаЗапятая = Ложь;
|
||
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
|
||
Если НужнаЗапятая Тогда
|
||
СтруктураСтрокой = СтруктураСтрокой + ",";
|
||
КонецЕсли;
|
||
СтруктураСтрокой = СтруктураСтрокой + Колонка.Имя;
|
||
НужнаЗапятая = Истина;
|
||
КонецЦикла;
|
||
Для Каждого СтрокаТаблицы Из ТаблицаЗначений Цикл
|
||
НоваяСтрока = Новый Структура(СтруктураСтрокой);
|
||
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТаблицы);
|
||
Массив.Добавить(НоваяСтрока);
|
||
КонецЦикла;
|
||
Возврат Массив;
|
||
|
||
КонецФункции
|
||
|
||
// Преобразует строку таблицы значений в структуру.
|
||
// Свойства структуры и их значения совпадают с колонками переданной строки.
|
||
//
|
||
// Параметры:
|
||
// СтрокаТаблицыЗначений - СтрокаТаблицыЗначений
|
||
//
|
||
// Возвращаемое значение:
|
||
// Структура - преобразованная строка таблицы значений.
|
||
//
|
||
Функция СтрокаТаблицыЗначенийВСтруктуру(СтрокаТаблицыЗначений) Экспорт
|
||
|
||
Структура = Новый Структура;
|
||
Для каждого Колонка Из СтрокаТаблицыЗначений.Владелец().Колонки Цикл
|
||
Структура.Вставить(Колонка.Имя, СтрокаТаблицыЗначений[Колонка.Имя]);
|
||
КонецЦикла;
|
||
|
||
Возврат Структура;
|
||
|
||
КонецФункции
|
||
|
||
// Создает структуру, содержащую имена и значения измерений, ресурсов и реквизитов
|
||
// переданного менеджера записи регистра сведений.
|
||
//
|
||
// Параметры:
|
||
// МенеджерЗаписи - РегистрСведенийМенеджерЗаписиИмяРегистраСведений - менеджер записи, из которого надо получить структуру.
|
||
// МетаданныеРегистра - ОбъектМетаданныхРегистрСведений - метаданные регистра сведений.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Структура - коллекция измерений ресурсов и реквизитов, переданного менеджеру записи.
|
||
//
|
||
Функция СтруктураПоМенеджеруЗаписи(МенеджерЗаписи, МетаданныеРегистра) Экспорт
|
||
|
||
ЗаписьКакСтруктура = Новый Структура;
|
||
|
||
Если МетаданныеРегистра.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
|
||
ЗаписьКакСтруктура.Вставить("Период", МенеджерЗаписи.Период);
|
||
КонецЕсли;
|
||
Для Каждого Поле Из МетаданныеРегистра.Измерения Цикл
|
||
ЗаписьКакСтруктура.Вставить(Поле.Имя, МенеджерЗаписи[Поле.Имя]);
|
||
КонецЦикла;
|
||
Для Каждого Поле Из МетаданныеРегистра.Ресурсы Цикл
|
||
ЗаписьКакСтруктура.Вставить(Поле.Имя, МенеджерЗаписи[Поле.Имя]);
|
||
КонецЦикла;
|
||
Для Каждого Поле Из МетаданныеРегистра.Реквизиты Цикл
|
||
ЗаписьКакСтруктура.Вставить(Поле.Имя, МенеджерЗаписи[Поле.Имя]);
|
||
КонецЦикла;
|
||
|
||
Возврат ЗаписьКакСтруктура;
|
||
|
||
КонецФункции
|
||
|
||
// Создает массив и копирует в него значения, содержащиеся в колонке объекта, для
|
||
// которого доступен обход посредством оператора Для каждого … Из.
|
||
//
|
||
// Параметры:
|
||
// КоллекцияСтрок - ТаблицаЗначений
|
||
// - ДеревоЗначений
|
||
// - СписокЗначений
|
||
// - ТабличнаяЧасть
|
||
// - Соответствие
|
||
// - Структура - коллекция, колонку которой нужно выгрузить в массив.
|
||
// А так же другие объекты, для которых доступен обход
|
||
// посредством оператора Для каждого … Из … Цикл.
|
||
// ИмяКолонки - Строка - имя поля коллекции, значения которого нужно выгрузить.
|
||
// ТолькоУникальныеЗначения - Булево - если Истина, то в массив будут включены
|
||
// только различающиеся значения.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Массив - значения колонки.
|
||
//
|
||
Функция ВыгрузитьКолонку(КоллекцияСтрок, ИмяКолонки, ТолькоУникальныеЗначения = Ложь) Экспорт
|
||
|
||
МассивЗначений = Новый Массив;
|
||
|
||
УникальныеЗначения = Новый Соответствие;
|
||
|
||
Для каждого СтрокаКоллекции Из КоллекцияСтрок Цикл
|
||
Значение = СтрокаКоллекции[ИмяКолонки];
|
||
Если ТолькоУникальныеЗначения И УникальныеЗначения[Значение] <> Неопределено Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
МассивЗначений.Добавить(Значение);
|
||
УникальныеЗначения.Вставить(Значение, Истина);
|
||
КонецЦикла;
|
||
|
||
Возврат МассивЗначений;
|
||
|
||
КонецФункции
|
||
|
||
// Преобразует текст указанного формата XML в таблицу значений,
|
||
// при этом колонки таблицы формируются на основе описания в XML.
|
||
//
|
||
// Схема XML:
|
||
// <?xml version="1.0" encoding="utf-8"?>
|
||
// <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||
// <xs:element name="Items">
|
||
// <xs:complexType>
|
||
// <xs:sequence>
|
||
// <xs:element maxOccurs="unbounded" name="Item">
|
||
// <xs:complexType>
|
||
// <xs:attribute name="Code" type="xs:integer" use="required" />
|
||
// <xs:attribute name="Name" type="xs:string" use="required" />
|
||
// <xs:attribute name="Socr" type="xs:string" use="required" />
|
||
// <xs:attribute name="Index" type="xs:string" use="required" />
|
||
// </xs:complexType>
|
||
// </xs:element>
|
||
// </xs:sequence>
|
||
// <xs:attribute name="Description" type="xs:string" use="required" />
|
||
// <xs:attribute name="Columns" type="xs:string" use="required" />
|
||
// </xs:complexType>
|
||
// </xs:element>
|
||
// </xs:schema>
|
||
//
|
||
// Параметры:
|
||
// XML - Строка
|
||
// - ЧтениеXML - текст в формате XML или ЧтениеXML.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Структура:
|
||
// * ИмяТаблицы - Строка - имя таблицы.
|
||
// * Данные - ТаблицаЗначений - преобразованная из XML таблица.
|
||
//
|
||
// Пример:
|
||
// КлассификаторТаблица = ОбщегоНазначения.ПрочитатьXMLВТаблицу(
|
||
// Обработки.ЗагрузкаКурсовВалют.ПолучитьМакет("ОбщероссийскийКлассификаторВалют").ПолучитьТекст()).Данные;
|
||
//
|
||
Функция ПрочитатьXMLВТаблицу(Знач XML) Экспорт
|
||
|
||
Если ТипЗнч(XML) <> Тип("ЧтениеXML") Тогда
|
||
Чтение = Новый ЧтениеXML;
|
||
Чтение.УстановитьСтроку(XML);
|
||
Иначе
|
||
Чтение = XML;
|
||
КонецЕсли;
|
||
|
||
// Прочитаем первый узел и проверим его.
|
||
Если Не Чтение.Прочитать() Тогда
|
||
ВызватьИсключение НСтр("ru = 'Не удалось загрузить данные из XML-файла, т.к. он пустой.'");
|
||
ИначеЕсли Чтение.Имя <> "Items" Тогда
|
||
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Не удалось загрузить данные из XML-файла: отсутствует обязательный тег %1.'"),
|
||
"Items");
|
||
КонецЕсли;
|
||
|
||
// Получим описание таблицы и создадим ее.
|
||
ИмяТаблицы = Чтение.ПолучитьАтрибут("Description");
|
||
ИменаКолонок = СтрЗаменить(Чтение.ПолучитьАтрибут("Columns"), ",", Символы.ПС);
|
||
Колонок = СтрЧислоСтрок(ИменаКолонок);
|
||
|
||
ТаблицаЗначений = Новый ТаблицаЗначений;
|
||
Для Сч = 1 По Колонок Цикл
|
||
ТаблицаЗначений.Колонки.Добавить(СтрПолучитьСтроку(ИменаКолонок, Сч), Новый ОписаниеТипов("Строка"));
|
||
КонецЦикла;
|
||
|
||
// Заполним значения в таблице.
|
||
Пока Чтение.Прочитать() Цикл
|
||
|
||
Если Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента И Чтение.Имя = "Items" Тогда
|
||
Прервать;
|
||
ИначеЕсли Чтение.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
|
||
Продолжить;
|
||
ИначеЕсли Чтение.Имя <> "Item" Тогда
|
||
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Не удалось загрузить данные из XML-файла: в теге %1 отсутствует обязательный тег %2.'"),
|
||
"Items", "Item");
|
||
КонецЕсли;
|
||
|
||
новСтр = ТаблицаЗначений.Добавить();
|
||
Для Сч = 1 По Колонок Цикл
|
||
ИмяКолонки = СтрПолучитьСтроку(ИменаКолонок, Сч);
|
||
новСтр[Сч-1] = Чтение.ПолучитьАтрибут(ИмяКолонки);
|
||
КонецЦикла;
|
||
|
||
КонецЦикла;
|
||
|
||
// Заполним результат
|
||
Результат = Новый Структура;
|
||
Результат.Вставить("ИмяТаблицы", ИмяТаблицы);
|
||
Результат.Вставить("Данные", ТаблицаЗначений);
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Сравнивает две коллекции строк (ТаблицаЗначений, ДеревоЗначений и т.д.),
|
||
// для которых доступен обход посредством оператора Для каждого … Из … Цикл.
|
||
// Сравниваемые коллекции должны отвечать следующим требованиям:
|
||
// - доступен обход посредством оператора Для каждого … Из … Цикл,
|
||
// - наличие в обеих коллекциях всех колонок, перечисленных в параметре ИменаКолонок
|
||
// (если ИменаКолонок не заполнен - все колонки первой коллекции должны существовать во второй коллекции).
|
||
// Также позволяет сравнивать массивы.
|
||
// Для сравнения других коллекций, а также для сравнения коллекций с учетом вложенности см. функцию ДанныеСовпадают.
|
||
//
|
||
// Параметры:
|
||
// КоллекцияСтрок1 - ТаблицаЗначений
|
||
// - ДеревоЗначений
|
||
// - СписокЗначений
|
||
// - ТабличнаяЧасть
|
||
// - Соответствие
|
||
// - Массив
|
||
// - ФиксированныйМассив
|
||
// - Структура - коллекция, отвечающая вышеописанным требованиям. А также другие
|
||
// объекты, для которых доступен обход посредством оператора Для каждого … Из … Цикл.
|
||
// КоллекцияСтрок2 - ТаблицаЗначений
|
||
// - ДеревоЗначений
|
||
// - СписокЗначений
|
||
// - ТабличнаяЧасть
|
||
// - Соответствие
|
||
// - Массив
|
||
// - ФиксированныйМассив
|
||
// - Структура - коллекция, отвечающая вышеописанным требованиям. А также другие
|
||
// объекты, для которых доступен обход посредством оператора Для каждого … Из … Цикл.
|
||
// ИменаКолонок - Строка - имена колонок через запятую, по которым производится сравнение.
|
||
// Не обязательно для коллекций, состав колонок которых можно определить автоматически:
|
||
// ТаблицаЗначений, СписокЗначений, Соответствие, Структура.
|
||
// Если не указан, то сравнение производится по колонкам первой коллекции.
|
||
// Для коллекций других типов является обязательным.
|
||
// Следует также учитывать, что при сравнении коллекций, содержащих вместо строк другие типы
|
||
// элементов, в качестве имен колонок можно указывать только имена свойств этих элементов.
|
||
// Для соответствий и структур это "Ключ" и "Значение", но не значения ключей.
|
||
// Для списков значений это "Значение" и "Представление", но не сами значения.
|
||
//
|
||
// ИсключаяКолонки - Строка - имена колонок, которые игнорируются при сравнении.
|
||
// УчитыватьПоследовательностьСтрок - Булево - если Истина, то коллекции признаются
|
||
// идентичными, только если одинаковые строки размещены в коллекциях на одинаковых местах.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если идентичны.
|
||
//
|
||
Функция КоллекцииИдентичны(КоллекцияСтрок1, КоллекцияСтрок2, Знач ИменаКолонок = "", Знач ИсключаяКолонки = "",
|
||
УчитыватьПоследовательностьСтрок = Ложь) Экспорт
|
||
|
||
ТипКоллекции = ТипЗнч(КоллекцияСтрок1);
|
||
СравниваютсяМассивы = (ТипКоллекции = Тип("Массив") Или ТипКоллекции = Тип("ФиксированныйМассив"));
|
||
|
||
СравниваемыеКолонки = Неопределено;
|
||
Если Не СравниваютсяМассивы Тогда
|
||
СравниваемыеКолонки = СравниваемыеКолонки(КоллекцияСтрок1, ИменаКолонок, ИсключаяКолонки);
|
||
КонецЕсли;
|
||
|
||
Если УчитыватьПоследовательностьСтрок Тогда
|
||
Возврат СравнитьСУчетомПоследовательности(КоллекцияСтрок1, КоллекцияСтрок2, СравниваемыеКолонки);
|
||
ИначеЕсли СравниваютсяМассивы Тогда // Для массивов используется более простой алгоритм.
|
||
Возврат СравнитьМассивы(КоллекцияСтрок1, КоллекцияСтрок2);
|
||
Иначе
|
||
Возврат СравнитьБезУчетаПоследовательности(КоллекцияСтрок1, КоллекцияСтрок2, СравниваемыеКолонки);
|
||
КонецЕсли;
|
||
|
||
КонецФункции
|
||
|
||
// Сравнивает данные сложной структуры с учетом вложенности.
|
||
//
|
||
// Параметры:
|
||
// Данные1 - Структура
|
||
// - ФиксированнаяСтруктура
|
||
// - Соответствие
|
||
// - ФиксированноеСоответствие
|
||
// - Массив
|
||
// - ФиксированныйМассив
|
||
// - ХранилищеЗначения
|
||
// - ТаблицаЗначений
|
||
// - Строка
|
||
// - Число
|
||
// - Булево - сравниваемые данные.
|
||
// Данные2 - Произвольный - те же типы, что и для параметра Данные1.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если совпадают.
|
||
//
|
||
Функция ДанныеСовпадают(Данные1, Данные2) Экспорт
|
||
|
||
Если ТипЗнч(Данные1) <> ТипЗнч(Данные2) Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
Если ТипЗнч(Данные1) = Тип("Структура")
|
||
ИЛИ ТипЗнч(Данные1) = Тип("ФиксированнаяСтруктура") Тогда
|
||
|
||
Если Данные1.Количество() <> Данные2.Количество() Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
Для каждого КлючИЗначение Из Данные1 Цикл
|
||
СтароеЗначение = Неопределено;
|
||
|
||
Если НЕ Данные2.Свойство(КлючИЗначение.Ключ, СтароеЗначение)
|
||
ИЛИ НЕ ДанныеСовпадают(КлючИЗначение.Значение, СтароеЗначение) Тогда
|
||
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат Истина;
|
||
|
||
ИначеЕсли ТипЗнч(Данные1) = Тип("Соответствие")
|
||
ИЛИ ТипЗнч(Данные1) = Тип("ФиксированноеСоответствие") Тогда
|
||
|
||
Если Данные1.Количество() <> Данные2.Количество() Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
КлючиНовогоСоответствия = Новый Соответствие;
|
||
|
||
Для каждого КлючИЗначение Из Данные1 Цикл
|
||
КлючиНовогоСоответствия.Вставить(КлючИЗначение.Ключ, Истина);
|
||
СтароеЗначение = Данные2.Получить(КлючИЗначение.Ключ);
|
||
|
||
Если НЕ ДанныеСовпадают(КлючИЗначение.Значение, СтароеЗначение) Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Для каждого КлючИЗначение Из Данные2 Цикл
|
||
Если КлючиНовогоСоответствия[КлючИЗначение.Ключ] = Неопределено Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат Истина;
|
||
|
||
ИначеЕсли ТипЗнч(Данные1) = Тип("Массив")
|
||
ИЛИ ТипЗнч(Данные1) = Тип("ФиксированныйМассив") Тогда
|
||
|
||
Если Данные1.Количество() <> Данные2.Количество() Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
Индекс = Данные1.Количество()-1;
|
||
Пока Индекс >= 0 Цикл
|
||
Если НЕ ДанныеСовпадают(Данные1.Получить(Индекс), Данные2.Получить(Индекс)) Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
Индекс = Индекс - 1;
|
||
КонецЦикла;
|
||
|
||
Возврат Истина;
|
||
|
||
ИначеЕсли ТипЗнч(Данные1) = Тип("ТаблицаЗначений") Тогда
|
||
|
||
Если Данные1.Количество() <> Данные2.Количество() Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
Если Данные1.Колонки.Количество() <> Данные2.Колонки.Количество() Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
Для каждого Колонка Из Данные1.Колонки Цикл
|
||
Если Данные2.Колонки.Найти(Колонка.Имя) = Неопределено Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
Индекс = Данные1.Количество()-1;
|
||
Пока Индекс >= 0 Цикл
|
||
Если НЕ ДанныеСовпадают(Данные1[Индекс][Колонка.Имя], Данные2[Индекс][Колонка.Имя]) Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
Индекс = Индекс - 1;
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
|
||
Возврат Истина;
|
||
|
||
ИначеЕсли ТипЗнч(Данные1) = Тип("ХранилищеЗначения") Тогда
|
||
|
||
Если НЕ ДанныеСовпадают(Данные1.Получить(), Данные2.Получить()) Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
Возврат Истина;
|
||
КонецЕсли;
|
||
|
||
Возврат Данные1 = Данные2;
|
||
|
||
КонецФункции
|
||
|
||
// Фиксирует данные типов Структура, Соответствие, Массив с учетом вложенности.
|
||
//
|
||
// Параметры:
|
||
// Данные - Структура
|
||
// - Соответствие
|
||
// - Массив - коллекции, значения которых являются примитивными типами,
|
||
// хранилищем значения или не могут быть изменены. Поддерживаются типы значений:
|
||
// Булево, Строка, Число, Дата, Неопределено, УникальныйИдентификатор, Null, Тип,
|
||
// ХранилищеЗначения, ОбщийМодуль, ОбъектМетаданных, ТипЗначенияXDTO, ТипОбъектаXDTO,
|
||
// ЛюбаяСсылка.
|
||
//
|
||
// ВызыватьИсключение - Булево - начальное значение Истина. Когда установлено Ложь, тогда в случае наличия
|
||
// нефиксируемых данных исключение не будет вызвано, при этом данные будут
|
||
// зафиксированы на сколько возможно.
|
||
//
|
||
// Возвращаемое значение:
|
||
// ФиксированнаяСтруктура, ФиксированноеСоответствие, ФиксированныйМассив - фиксированные данные, аналогичные
|
||
// переданным в параметре Данные.
|
||
//
|
||
Функция ФиксированныеДанные(Данные, ВызыватьИсключение = Истина) Экспорт
|
||
|
||
Если ТипЗнч(Данные) = Тип("Массив") Тогда
|
||
Массив = Новый Массив;
|
||
|
||
Для каждого Значение Из Данные Цикл
|
||
|
||
Если ТипЗнч(Значение) = Тип("Структура")
|
||
ИЛИ ТипЗнч(Значение) = Тип("Соответствие")
|
||
ИЛИ ТипЗнч(Значение) = Тип("Массив") Тогда
|
||
|
||
Массив.Добавить(ФиксированныеДанные(Значение, ВызыватьИсключение));
|
||
Иначе
|
||
Если ВызыватьИсключение Тогда
|
||
ПроверкаФиксированностиДанных(Значение, Истина);
|
||
КонецЕсли;
|
||
Массив.Добавить(Значение);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат Новый ФиксированныйМассив(Массив);
|
||
|
||
ИначеЕсли ТипЗнч(Данные) = Тип("Структура")
|
||
ИЛИ ТипЗнч(Данные) = Тип("Соответствие") Тогда
|
||
|
||
Если ТипЗнч(Данные) = Тип("Структура") Тогда
|
||
Коллекция = Новый Структура;
|
||
Иначе
|
||
Коллекция = Новый Соответствие;
|
||
КонецЕсли;
|
||
|
||
Для каждого КлючИЗначение Из Данные Цикл
|
||
Значение = КлючИЗначение.Значение;
|
||
|
||
Если ТипЗнч(Значение) = Тип("Структура")
|
||
ИЛИ ТипЗнч(Значение) = Тип("Соответствие")
|
||
ИЛИ ТипЗнч(Значение) = Тип("Массив") Тогда
|
||
|
||
Коллекция.Вставить(
|
||
КлючИЗначение.Ключ, ФиксированныеДанные(Значение, ВызыватьИсключение));
|
||
Иначе
|
||
Если ВызыватьИсключение Тогда
|
||
ПроверкаФиксированностиДанных(Значение, Истина);
|
||
КонецЕсли;
|
||
Коллекция.Вставить(КлючИЗначение.Ключ, Значение);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если ТипЗнч(Данные) = Тип("Структура") Тогда
|
||
Возврат Новый ФиксированнаяСтруктура(Коллекция);
|
||
Иначе
|
||
Возврат Новый ФиксированноеСоответствие(Коллекция);
|
||
КонецЕсли;
|
||
|
||
ИначеЕсли ВызыватьИсключение Тогда
|
||
ПроверкаФиксированностиДанных(Данные);
|
||
КонецЕсли;
|
||
|
||
Возврат Данные;
|
||
|
||
КонецФункции
|
||
|
||
// Вычисляет контрольную сумму для произвольных данных по указанному алгоритму.
|
||
//
|
||
// Параметры:
|
||
// Данные - Произвольный - любое сериализуемое значение.
|
||
// Алгоритм - ХешФункция - алгоритм расчета контрольной суммы. По умолчанию, MD5.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - контрольная сумма строкой без пробелов (например 32 символа).
|
||
//
|
||
Функция КонтрольнаяСуммаСтрокой(Знач Данные, Знач Алгоритм = Неопределено) Экспорт
|
||
|
||
Если Алгоритм = Неопределено Тогда
|
||
Алгоритм = ХешФункция.MD5;
|
||
КонецЕсли;
|
||
|
||
ХешированиеДанных = Новый ХешированиеДанных(Алгоритм);
|
||
Если ТипЗнч(Данные) <> Тип("Строка") И ТипЗнч(Данные) <> Тип("ДвоичныеДанные") Тогда
|
||
Данные = ЗначениеВСтрокуXML(Данные);
|
||
КонецЕсли;
|
||
ХешированиеДанных.Добавить(Данные);
|
||
|
||
Если ТипЗнч(ХешированиеДанных.ХешСумма) = Тип("ДвоичныеДанные") Тогда
|
||
Результат = СтрЗаменить(ХешированиеДанных.ХешСумма, " ", "");
|
||
ИначеЕсли ТипЗнч(ХешированиеДанных.ХешСумма) = Тип("Число") Тогда
|
||
Результат = Формат(ХешированиеДанных.ХешСумма, "ЧГ=");
|
||
КонецЕсли;
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Сокращает строку до нужной длины, при этом обрезанная часть хешируется,
|
||
// обеспечивая уникальность строки. Проверяет длину строки на входе и, в случае
|
||
// превышения максимальной длины, преобразует ее конец по алгоритму MD5 в
|
||
// уникальную строку из 32 символов.
|
||
//
|
||
// Параметры:
|
||
// Строка - Строка - исходная строка произвольной длины.
|
||
// МаксимальнаяДлина - Число - требуемое максимальное количество символов в строке,
|
||
// минимальное значение: 32.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - строка, не превышающая максимальную длину.
|
||
//
|
||
Функция СократитьСтрокуКонтрольнойСуммой(Строка, МаксимальнаяДлина) Экспорт
|
||
|
||
Если МаксимальнаяДлина < 32 Тогда
|
||
ОбщегоНазначенияКлиентСервер.Проверить(Ложь,
|
||
СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Параметр %1 не может быть меньше 32.'"),
|
||
"МаксимальнаяДлина"), "ОбщегоНазначения.СократитьСтрокуКонтрольнойСуммой");
|
||
КонецЕсли;
|
||
|
||
Результат = Строка;
|
||
Если СтрДлина(Строка) > МаксимальнаяДлина Тогда
|
||
Результат = Лев(Строка, МаксимальнаяДлина - 32);
|
||
ХешированиеДанных = Новый ХешированиеДанных(ХешФункция.MD5);
|
||
ХешированиеДанных.Добавить(Сред(Строка, МаксимальнаяДлина - 32 + 1));
|
||
Результат = Результат + СтрЗаменить(ХешированиеДанных.ХешСумма, " ", "");
|
||
КонецЕсли;
|
||
Возврат Результат;
|
||
КонецФункции
|
||
|
||
// Создает полную копию структуры, соответствия, массива, списка или таблицы значений, рекурсивно,
|
||
// с учетом типов дочерних элементов. При этом содержимое значений объектных типов
|
||
// (СправочникОбъект, ДокументОбъект и т.п.) не копируются, а возвращаются ссылки на исходный объект.
|
||
//
|
||
// Параметры:
|
||
// Источник - Структура
|
||
// - ФиксированнаяСтруктура
|
||
// - Соответствие
|
||
// - ФиксированноеСоответствие
|
||
// - Массив
|
||
// - ФиксированныйМассив
|
||
// - СписокЗначений - объект, который необходимо скопировать.
|
||
// ФиксироватьДанные - Булево - если Истина - фиксировать, если Ложь - снять фиксацию.
|
||
// - Неопределено - не изменять.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Структура,
|
||
// ФиксированнаяСтруктура,
|
||
// Соответствие
|
||
// ФиксированноеСоответствие
|
||
// Массив
|
||
// ФиксированныйМассив
|
||
// СписокЗначений - копия объекта, переданного в параметре Источник.
|
||
//
|
||
Функция СкопироватьРекурсивно(Источник, ФиксироватьДанные = Неопределено) Экспорт
|
||
|
||
Перем Приемник;
|
||
|
||
ТипИсточника = ТипЗнч(Источник);
|
||
|
||
Если ТипИсточника = Тип("ТаблицаЗначений") Тогда
|
||
Приемник = Источник.Скопировать();
|
||
СкопироватьЗначенияТаблицыЗначений(Приемник, ФиксироватьДанные);
|
||
ИначеЕсли ТипИсточника = Тип("ДеревоЗначений") Тогда
|
||
Приемник = Источник.Скопировать();
|
||
СкопироватьЗначенияСтрокиДереваЗначений(Приемник.Строки, ФиксироватьДанные);
|
||
ИначеЕсли ТипИсточника = Тип("Структура")
|
||
Или ТипИсточника = Тип("ФиксированнаяСтруктура") Тогда
|
||
Приемник = СкопироватьСтруктуру(Источник, ФиксироватьДанные);
|
||
ИначеЕсли ТипИсточника = Тип("Соответствие")
|
||
Или ТипИсточника = Тип("ФиксированноеСоответствие") Тогда
|
||
Приемник = СкопироватьСоответствие(Источник, ФиксироватьДанные);
|
||
ИначеЕсли ТипИсточника = Тип("Массив")
|
||
Или ТипИсточника = Тип("ФиксированныйМассив") Тогда
|
||
Приемник = СкопироватьМассив(Источник, ФиксироватьДанные);
|
||
ИначеЕсли ТипИсточника = Тип("СписокЗначений") Тогда
|
||
Приемник = СкопироватьСписокЗначений(Источник, ФиксироватьДанные);
|
||
Иначе
|
||
Приемник = Источник;
|
||
КонецЕсли;
|
||
|
||
Возврат Приемник;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает описание предмета в виде текстовой строки.
|
||
// Для документов возвращается представление, для остальных ссылочных типов возвращается
|
||
// представление и тип в скобках, например, "Ножницы (Номенклатура)".
|
||
// Для пустых ссылок, Неопределено или незаполненных значений примитивных типов возвращается "не задан".
|
||
//
|
||
// Параметры:
|
||
// СсылкаНаПредмет - Произвольный.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - например, "Ножницы (Номенклатура)", "Заказ клиента № 0001 от 01.01.2001" или "не задан".
|
||
//
|
||
Функция ПредметСтрокой(СсылкаНаПредмет) Экспорт
|
||
|
||
Если СсылкаНаПредмет <> Неопределено Тогда
|
||
Возврат ПредметыСтрокой(ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(СсылкаНаПредмет))[СсылкаНаПредмет];
|
||
Иначе
|
||
Возврат НСтр("ru = 'не задан'");
|
||
КонецЕсли;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает описания предметов СсылкиНаПредметы.
|
||
// Для документов возвращается представление, для остальных ссылочных типов возвращается
|
||
// представление и тип в скобках, например, "Ножницы (Номенклатура)".
|
||
// Для пустых ссылок или незаполненных значений примитивных типов возвращается "не задан".
|
||
// Значение "удален", если объект не существует в информационной базе.
|
||
// Значения Неопределено пропускаются.
|
||
//
|
||
// Параметры:
|
||
// СсылкиНаПредметы - Массив из ЛюбаяСсылка
|
||
//
|
||
// Возвращаемое значение:
|
||
// Соответствие из КлючИЗначение:
|
||
// * Ключ - ЛюбаяСсылка
|
||
// * Значение - Строка - например, "Ножницы (Номенклатура)", "Заказ клиента № 0001 от 01.01.2001" или "не задан".
|
||
//
|
||
Функция ПредметыСтрокой(Знач СсылкиНаПредметы) Экспорт
|
||
|
||
ПроверяемыеСсылки = Новый Массив;
|
||
Результат = Новый Соответствие;
|
||
Для каждого СсылкаНаПредмет Из СсылкиНаПредметы Цикл
|
||
Если СсылкаНаПредмет = Неопределено Тогда
|
||
Результат[СсылкаНаПредмет] = НСтр("ru = 'не задан'");
|
||
ИначеЕсли Не ЭтоСсылка(ТипЗнч(СсылкаНаПредмет)) Тогда
|
||
Результат[СсылкаНаПредмет] = Строка(СсылкаНаПредмет);
|
||
ИначеЕсли СсылкаНаПредмет.Пустая() Тогда
|
||
Результат[СсылкаНаПредмет] = НСтр("ru = 'не задан'");
|
||
ИначеЕсли Метаданные.Перечисления.Содержит(СсылкаНаПредмет.Метаданные()) Тогда
|
||
Результат[СсылкаНаПредмет] = Строка(СсылкаНаПредмет);
|
||
Иначе
|
||
ПроверяемыеСсылки.Добавить(СсылкаНаПредмет);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Для каждого СуществующаяСсылка Из ПредставленияСсылок(ПроверяемыеСсылки) Цикл
|
||
СсылкаНаПредмет = СуществующаяСсылка.Ключ;
|
||
Результат[СсылкаНаПредмет] = СуществующаяСсылка.Значение;
|
||
Если Не Метаданные.Документы.Содержит(СсылкаНаПредмет.Метаданные()) Тогда
|
||
ПредставлениеОбъекта = СсылкаНаПредмет.Метаданные().ПредставлениеОбъекта;
|
||
Если ПустаяСтрока(ПредставлениеОбъекта) Тогда
|
||
ПредставлениеОбъекта = СсылкаНаПредмет.Метаданные().Представление();
|
||
КонецЕсли;
|
||
Результат[СсылкаНаПредмет] = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1 (%2)",
|
||
Результат[СсылкаНаПредмет], ПредставлениеОбъекта);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает представления переданных ссылок.
|
||
//
|
||
// Параметры:
|
||
// ПроверяемыеСсылки - Массив из ЛюбаяСсылка, ЛюбаяСсылка
|
||
//
|
||
// Возвращаемое значение:
|
||
// Соответствие из КлючИЗначение:
|
||
// * Ключ - ЛюбаяСсылка
|
||
// * Значение - Строка - представление ссылки или "удален", если ссылка не существует в информационной базе.
|
||
//
|
||
Функция ПредставленияСсылок(ПроверяемыеСсылки) Экспорт
|
||
|
||
ОбъектыПоТипу = Новый Соответствие;
|
||
Если ТипЗнч(ПроверяемыеСсылки) = Тип("Массив") Тогда
|
||
Для каждого ПроверяемаяСсылка Из ПроверяемыеСсылки Цикл
|
||
Объекты = ОбъектыПоТипу[ПроверяемаяСсылка.Метаданные()];
|
||
Если Объекты = Неопределено Тогда
|
||
Объекты = Новый Массив;
|
||
ОбъектыПоТипу[ПроверяемаяСсылка.Метаданные()] = Объекты;
|
||
КонецЕсли;
|
||
Объекты.Добавить(ПроверяемаяСсылка);
|
||
КонецЦикла;
|
||
Иначе
|
||
ОбъектыПоТипу[ПроверяемыеСсылки.Метаданные()] = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(ПроверяемыеСсылки);
|
||
КонецЕсли;
|
||
|
||
Результат = Новый Соответствие;
|
||
Если ОбъектыПоТипу.Количество() = 0 Тогда
|
||
Возврат Результат;
|
||
КонецЕсли;
|
||
|
||
Запрос = Новый Запрос;
|
||
ТекстыЗапросов = Новый Массив;
|
||
Индекс = 0;
|
||
Для каждого ТипОбъекта Из ОбъектыПоТипу Цикл
|
||
|
||
ТекстЗапроса =
|
||
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
|
||
| Представление КАК Представление,
|
||
| Таблица.Ссылка КАК Ссылка
|
||
|ИЗ
|
||
| &ИмяТаблицы КАК Таблица
|
||
|ГДЕ
|
||
| Таблица.Ссылка В (&Ссылка)";
|
||
|
||
Если ТекстыЗапросов.Количество() > 0 Тогда
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ВЫБРАТЬ РАЗРЕШЕННЫЕ", "ВЫБРАТЬ"); // @query-part-1, @query-part-2
|
||
КонецЕсли;
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ИмяТаблицы", ТипОбъекта.Ключ.ПолноеИмя());
|
||
|
||
ИмяПараметра = "Ссылка" + Формат(Индекс, "ЧГ=;ЧН=");
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Ссылка", "&" + ИмяПараметра);
|
||
ТекстыЗапросов.Добавить(ТекстЗапроса);
|
||
Запрос.УстановитьПараметр(ИмяПараметра, ТипОбъекта.Значение);
|
||
|
||
Индекс = Индекс + 1;
|
||
КонецЦикла;
|
||
|
||
Запрос.Текст = СтрСоединить(ТекстыЗапросов, Символы.ПС + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС); // @query-part;
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
ФактическиеСсылки = Запрос.Выполнить().Выгрузить();
|
||
УстановитьПривилегированныйРежим(Ложь);
|
||
|
||
ПредставленияСсылок = Запрос.Выполнить().Выгрузить();
|
||
ПредставленияСсылок.Индексы.Добавить("Ссылка");
|
||
|
||
Для каждого Ссылка Из ФактическиеСсылки Цикл
|
||
Если ЗначениеЗаполнено(Ссылка.Ссылка) Тогда
|
||
ПредставлениеСсылки = ПредставленияСсылок.Найти(Ссылка.Ссылка, "Ссылка");
|
||
Результат[Ссылка.Ссылка] = ?(ПредставлениеСсылки <> Неопределено,
|
||
ПредставлениеСсылки.Представление, Строка(Ссылка.Ссылка));
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Для каждого Ссылка Из ПроверяемыеСсылки Цикл
|
||
Если Результат[Ссылка] = Неопределено Тогда
|
||
Результат[Ссылка] = НСтр("ru = 'удален'");
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область ДинамическийСписок
|
||
|
||
// Создает структуру для второго параметра СвойстваСписка процедуры УстановитьСвойстваДинамическогоСписка.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Структура - любое поле может иметь значение Неопределено, если оно не устанавливается:
|
||
// * ТекстЗапроса - Строка - новый текст запроса.
|
||
// * ОсновнаяТаблица - Строка - имя основной таблицы.
|
||
// * ДинамическоеСчитываниеДанных - Булево - признак использования динамического считывания.
|
||
//
|
||
Функция СтруктураСвойствДинамическогоСписка() Экспорт
|
||
|
||
Возврат Новый Структура("ТекстЗапроса, ОсновнаяТаблица, ДинамическоеСчитываниеДанных");
|
||
|
||
КонецФункции
|
||
|
||
// Установить текст запроса, основную таблицу или динамическое считывание в динамическом списке.
|
||
// Устанавливать эти свойства следует за один вызов этой процедуры, чтобы не снижалась производительность.
|
||
//
|
||
// Параметры:
|
||
// Список - ТаблицаФормы - элемент формы динамического списка, для которого устанавливаются свойства.
|
||
// СвойстваСписка - см. СтруктураСвойствДинамическогоСписка
|
||
//
|
||
Процедура УстановитьСвойстваДинамическогоСписка(Список, СвойстваСписка) Экспорт
|
||
|
||
Форма = Список.Родитель;
|
||
ТипФормаКлиентскогоПриложения = Тип("ФормаКлиентскогоПриложения");
|
||
|
||
Пока ТипЗнч(Форма) <> ТипФормаКлиентскогоПриложения Цикл
|
||
Форма = Форма.Родитель;
|
||
КонецЦикла;
|
||
|
||
ДинамическийСписок = Форма[Список.ПутьКДанным];
|
||
ТекстЗапроса = СвойстваСписка.ТекстЗапроса;
|
||
|
||
Если Не ПустаяСтрока(ТекстЗапроса) Тогда
|
||
ДинамическийСписок.ТекстЗапроса = ТекстЗапроса;
|
||
КонецЕсли;
|
||
|
||
ОсновнаяТаблица = СвойстваСписка.ОсновнаяТаблица;
|
||
|
||
Если ОсновнаяТаблица <> Неопределено Тогда
|
||
ДинамическийСписок.ОсновнаяТаблица = ОсновнаяТаблица;
|
||
КонецЕсли;
|
||
|
||
ДинамическоеСчитываниеДанных = СвойстваСписка.ДинамическоеСчитываниеДанных;
|
||
|
||
Если ТипЗнч(ДинамическоеСчитываниеДанных) = Тип("Булево") Тогда
|
||
ДинамическийСписок.ДинамическоеСчитываниеДанных = ДинамическоеСчитываниеДанных;
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
#КонецОбласти
|
||
|
||
#Область ВнешнееСоединение
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
// Процедуры и функции для работы с внешним соединением.
|
||
|
||
// Возвращает CLSID COM-класса для работы с "1С:Предприятием 8" через COM-соединение.
|
||
//
|
||
// Параметры:
|
||
// ИмяCOMСоединителя - Строка - имя COM-класса для работы с "1С:Предприятием 8" через COM-соединение.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - строковое представление CLSID.
|
||
//
|
||
Функция ИдентификаторCOMСоединителя(Знач ИмяCOMСоединителя) Экспорт
|
||
|
||
Если ИмяCOMСоединителя = "v83.COMConnector" Тогда
|
||
Возврат "181E893D-73A4-4722-B61D-D604B3D67D47";
|
||
КонецЕсли;
|
||
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверное значение параметра %1 функции %2. Не задан CLSID для класса %3.'"),
|
||
"ИмяCOMСоединителя", "ОбщегоНазначения.ИдентификаторCOMСоединителя", ИмяCOMСоединителя),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
|
||
КонецФункции
|
||
|
||
// Устанавливает внешнее соединение с информационной базой по переданным параметрам подключения и возвращает указатель
|
||
// на это соединение.
|
||
//
|
||
// Параметры:
|
||
// Параметры - см. ОбщегоНазначенияКлиентСервер.СтруктураПараметровДляУстановкиВнешнегоСоединения
|
||
//
|
||
// Возвращаемое значение:
|
||
// Структура:
|
||
// * Соединение - COMОбъект
|
||
// - Неопределено - COM-объект соединения или Неопределено в случае ошибки;
|
||
// * КраткоеОписаниеОшибки - Строка - краткое описание ошибки;
|
||
// * ПодробноеОписаниеОшибки - Строка - подробное описание ошибки;
|
||
// * ОшибкаПодключенияКомпоненты - Булево - флаг ошибки подключения COM.
|
||
//
|
||
Функция УстановитьВнешнееСоединениеСБазой(Параметры) Экспорт
|
||
|
||
ПодключениеНедоступно = ЭтоLinuxСервер();
|
||
КраткоеОписаниеОшибки = НСтр("ru = 'Прямое подключение к информационной базе недоступно на сервере под управлением ОС Linux.'");
|
||
|
||
Возврат ОбщегоНазначенияСлужебныйКлиентСервер.УстановитьВнешнееСоединениеСБазой(Параметры, ПодключениеНедоступно, КраткоеОписаниеОшибки);
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область Метаданные
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
// Функции определения типов объектов метаданных.
|
||
|
||
// Ссылочные типы данных
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "Документ".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к документам.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является документом.
|
||
//
|
||
Функция ЭтоДокумент(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.Документы.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "Справочник".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является справочником.
|
||
//
|
||
Функция ЭтоСправочник(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.Справочники.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "Перечисление".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является перечислением.
|
||
//
|
||
Функция ЭтоПеречисление(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.Перечисления.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "План обмена".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является планом обмена.
|
||
//
|
||
Функция ЭтоПланОбмена(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.ПланыОбмена.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "План видов характеристик".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является планом видов характеристик.
|
||
//
|
||
Функция ЭтоПланВидовХарактеристик(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.ПланыВидовХарактеристик.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "Бизнес-процесс".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является бизнес-процессом.
|
||
//
|
||
Функция ЭтоБизнесПроцесс(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.БизнесПроцессы.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "Задача".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является задачей.
|
||
//
|
||
Функция ЭтоЗадача(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.Задачи.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "План счетов".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является планом счетов.
|
||
//
|
||
Функция ЭтоПланСчетов(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.ПланыСчетов.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "План видов расчета".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является планом видов расчета.
|
||
//
|
||
Функция ЭтоПланВидовРасчета(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.ПланыВидовРасчета.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Регистры
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "Регистр сведений".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является регистром сведений.
|
||
//
|
||
Функция ЭтоРегистрСведений(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "Регистр накопления".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является регистром накопления.
|
||
//
|
||
Функция ЭтоРегистрНакопления(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.РегистрыНакопления.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "Регистр бухгалтерии".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является регистром бухгалтерии.
|
||
//
|
||
Функция ЭтоРегистрБухгалтерии(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "Регистр расчета".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является регистром расчета.
|
||
//
|
||
Функция ЭтоРегистрРасчета(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.РегистрыРасчета.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Константы
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "Константа".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является константой.
|
||
//
|
||
Функция ЭтоКонстанта(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.Константы.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Журналы документов
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "Журнал документов".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является журналом документов.
|
||
//
|
||
Функция ЭтоЖурналДокументов(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.ЖурналыДокументов.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Последовательности
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "Последовательности".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является последовательностью.
|
||
//
|
||
Функция ЭтоПоследовательность(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.Последовательности.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// РегламентныеЗадания
|
||
|
||
// Определяет принадлежность объекта метаданных к общему типу "Регламентные задания".
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является регламентным заданием.
|
||
//
|
||
Функция ЭтоРегламентноеЗадание(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.РегламентныеЗадания.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Общие
|
||
|
||
// Определяет принадлежность объекта метаданных к типу регистр.
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект является каким-либо регистром.
|
||
//
|
||
Функция ЭтоРегистр(ОбъектМетаданных) Экспорт
|
||
|
||
Возврат Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМетаданных)
|
||
Или Метаданные.РегистрыНакопления.Содержит(ОбъектМетаданных)
|
||
Или Метаданные.РегистрыРасчета.Содержит(ОбъектМетаданных)
|
||
Или Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных);
|
||
|
||
КонецФункции
|
||
|
||
// Определяет принадлежность объекта метаданных к ссылочному типу.
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо определить принадлежность к заданному типу.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект ссылочного типа.
|
||
//
|
||
Функция ЭтоОбъектСсылочногоТипа(ОбъектМетаданных) Экспорт
|
||
|
||
ИмяОбъектаМетаданных = ОбъектМетаданных.ПолноеИмя();
|
||
Позиция = СтрНайти(ИмяОбъектаМетаданных, ".");
|
||
Если Позиция > 0 Тогда
|
||
ИмяБазовогоТипа = Лев(ИмяОбъектаМетаданных, Позиция - 1);
|
||
Возврат ИмяБазовогоТипа = "Справочник"
|
||
Или ИмяБазовогоТипа = "Документ"
|
||
Или ИмяБазовогоТипа = "БизнесПроцесс"
|
||
Или ИмяБазовогоТипа = "Задача"
|
||
Или ИмяБазовогоТипа = "ПланСчетов"
|
||
Или ИмяБазовогоТипа = "ПланОбмена"
|
||
Или ИмяБазовогоТипа = "ПланВидовХарактеристик"
|
||
Или ИмяБазовогоТипа = "ПланВидовРасчета";
|
||
Иначе
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
КонецФункции
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
// Процедуры и функции для работы с типами, объектами метаданных и их строковыми представлениями.
|
||
|
||
// Возвращает имена реквизитов объекта заданного типа.
|
||
//
|
||
// Параметры:
|
||
// Ссылка - ЛюбаяСсылка - ссылка на элемент базы данных, для которого требуется получить результат функции;
|
||
// Тип - Тип - тип значения реквизита.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - строка реквизитов объекта метаданных конфигурации, разделенных символом ",".
|
||
//
|
||
// Пример:
|
||
// РеквизитыОрганизации = ОбщегоНазначения.ИменаРеквизитовПоТипу(Документ.Ссылка, Тип("СправочникСсылка.Организации"));
|
||
//
|
||
Функция ИменаРеквизитовПоТипу(Ссылка, Тип) Экспорт
|
||
|
||
Результат = "";
|
||
МетаданныеОбъекта = Ссылка.Метаданные();
|
||
|
||
Для Каждого Реквизит Из МетаданныеОбъекта.Реквизиты Цикл
|
||
Если Реквизит.Тип.СодержитТип(Тип) Тогда
|
||
Результат = Результат + ?(ПустаяСтрока(Результат), "", ", ") + Реквизит.Имя;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат Результат;
|
||
КонецФункции
|
||
|
||
// Возвращает имя базового типа по переданному значению объекта метаданных.
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект метаданных, по которому необходимо определить базовый тип.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - имя базового типа по переданному значению объекта метаданных.
|
||
//
|
||
// Пример:
|
||
// ИмяБазовогоТипа = ОбщегоНазначения.ИмяБазовогоТипаПоОбъектуМетаданных(Метаданные.Справочники.Номенклатура); = "Справочники".
|
||
//
|
||
Функция ИмяБазовогоТипаПоОбъектуМетаданных(ОбъектМетаданных) Экспорт
|
||
|
||
Если Метаданные.Документы.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "Документы";
|
||
|
||
ИначеЕсли Метаданные.Справочники.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "Справочники";
|
||
|
||
ИначеЕсли Метаданные.Перечисления.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "Перечисления";
|
||
|
||
ИначеЕсли Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "РегистрыСведений";
|
||
|
||
ИначеЕсли Метаданные.РегистрыНакопления.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "РегистрыНакопления";
|
||
|
||
ИначеЕсли Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "РегистрыБухгалтерии";
|
||
|
||
ИначеЕсли Метаданные.РегистрыРасчета.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "РегистрыРасчета";
|
||
|
||
ИначеЕсли Метаданные.ПланыОбмена.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ПланыОбмена";
|
||
|
||
ИначеЕсли Метаданные.ПланыВидовХарактеристик.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ПланыВидовХарактеристик";
|
||
|
||
ИначеЕсли Метаданные.БизнесПроцессы.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "БизнесПроцессы";
|
||
|
||
ИначеЕсли Метаданные.Задачи.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "Задачи";
|
||
|
||
ИначеЕсли Метаданные.ПланыСчетов.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ПланыСчетов";
|
||
|
||
ИначеЕсли Метаданные.ПланыВидовРасчета.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ПланыВидовРасчета";
|
||
|
||
ИначеЕсли Метаданные.Константы.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "Константы";
|
||
|
||
ИначеЕсли Метаданные.ЖурналыДокументов.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ЖурналыДокументов";
|
||
|
||
ИначеЕсли Метаданные.Последовательности.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "Последовательности";
|
||
|
||
ИначеЕсли Метаданные.РегламентныеЗадания.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "РегламентныеЗадания";
|
||
|
||
ИначеЕсли Метаданные.РегистрыРасчета.Содержит(ОбъектМетаданных.Родитель())
|
||
И ОбъектМетаданных.Родитель().Перерасчеты.Найти(ОбъектМетаданных.Имя) = ОбъектМетаданных Тогда
|
||
Возврат "Перерасчеты";
|
||
|
||
ИначеЕсли Метаданные.Обработки.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "Обработки";
|
||
|
||
ИначеЕсли Метаданные.Отчеты.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "Отчеты";
|
||
|
||
ИначеЕсли Метаданные.Подсистемы.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "Подсистемы";
|
||
|
||
ИначеЕсли Метаданные.ОбщиеМодули.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ОбщиеМодули";
|
||
|
||
ИначеЕсли Метаданные.ПараметрыСеанса.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ПараметрыСеанса";
|
||
|
||
ИначеЕсли Метаданные.Роли.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "Роли";
|
||
|
||
ИначеЕсли Метаданные.ОбщиеРеквизиты.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ОбщиеРеквизиты";
|
||
|
||
ИначеЕсли Метаданные.КритерииОтбора.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "КритерииОтбора";
|
||
|
||
ИначеЕсли Метаданные.ПодпискиНаСобытия.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ПодпискиНаСобытия";
|
||
|
||
ИначеЕсли Метаданные.ФункциональныеОпции.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ФункциональныеОпции";
|
||
|
||
ИначеЕсли Метаданные.ПараметрыФункциональныхОпций.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ПараметрыФункциональныхОпций";
|
||
|
||
ИначеЕсли Метаданные.ХранилищаНастроек.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ХранилищаНастроек";
|
||
|
||
ИначеЕсли Метаданные.ОбщиеФормы.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ОбщиеФормы";
|
||
|
||
ИначеЕсли Метаданные.ОбщиеКоманды.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ОбщиеКоманды";
|
||
|
||
ИначеЕсли Метаданные.ГруппыКоманд.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ГруппыКоманд";
|
||
|
||
ИначеЕсли Метаданные.ОбщиеМакеты.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ОбщиеМакеты";
|
||
|
||
ИначеЕсли Метаданные.ОбщиеКартинки.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ОбщиеКартинки";
|
||
|
||
ИначеЕсли Метаданные.ПакетыXDTO.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ПакетыXDTO";
|
||
|
||
ИначеЕсли Метаданные.WebСервисы.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "WebСервисы";
|
||
|
||
ИначеЕсли Метаданные.WSСсылки.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "WSСсылки";
|
||
|
||
ИначеЕсли Метаданные.Стили.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "Стили";
|
||
|
||
ИначеЕсли Метаданные.Языки.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "Языки";
|
||
|
||
ИначеЕсли Метаданные.ВнешниеИсточникиДанных.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат "ВнешниеИсточникиДанных";
|
||
|
||
Иначе
|
||
|
||
Возврат "";
|
||
|
||
КонецЕсли;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает менеджер объекта по полному имени объекта метаданных.
|
||
// Ограничение: не обрабатываются точки маршрутов бизнес-процессов.
|
||
//
|
||
// Параметры:
|
||
// ПолноеИмя - Строка - полное имя объекта метаданных. Пример: "Справочник.Организации".
|
||
//
|
||
// Возвращаемое значение:
|
||
// СправочникМенеджер, ДокументМенеджер, ОбработкаМенеджер, РегистрСведенийМенеджер, ПланВидовХарактеристикМенеджер
|
||
//
|
||
// Пример:
|
||
// МенеджерСправочника = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени("Справочник.Организации");
|
||
// ПустаяСсылка = МенеджерСправочника.ПустаяСсылка();
|
||
//
|
||
Функция МенеджерОбъектаПоПолномуИмени(ПолноеИмя) Экспорт
|
||
|
||
Перем КлассОМ, ИмяОМ, Менеджер;
|
||
|
||
ЧастиИмени = СтрРазделить(ПолноеИмя, ".");
|
||
|
||
Если ЧастиИмени.Количество() >= 2 Тогда
|
||
КлассОМ = ЧастиИмени[0];
|
||
ИмяОМ = ЧастиИмени[1];
|
||
Иначе
|
||
Менеджер = Неопределено;
|
||
КонецЕсли;
|
||
|
||
Если ВРег(КлассОМ) = "ПЛАНОБМЕНА" Тогда
|
||
Менеджер = ПланыОбмена;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "СПРАВОЧНИК" Тогда
|
||
Менеджер = Справочники;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "ДОКУМЕНТ" Тогда
|
||
Менеджер = Документы;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "ЖУРНАЛДОКУМЕНТОВ" Тогда
|
||
Менеджер = ЖурналыДокументов;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "ПЕРЕЧИСЛЕНИЕ" Тогда
|
||
Менеджер = Перечисления;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "ОТЧЕТ" Тогда
|
||
Менеджер = Отчеты;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "ОБРАБОТКА" Тогда
|
||
Менеджер = Обработки;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "ПЛАНВИДОВХАРАКТЕРИСТИК" Тогда
|
||
Менеджер = ПланыВидовХарактеристик;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "ПЛАНСЧЕТОВ" Тогда
|
||
Менеджер = ПланыСчетов;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "ПЛАНВИДОВРАСЧЕТА" Тогда
|
||
Менеджер = ПланыВидовРасчета;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "РЕГИСТРСВЕДЕНИЙ" Тогда
|
||
Менеджер = РегистрыСведений;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "РЕГИСТРНАКОПЛЕНИЯ" Тогда
|
||
Менеджер = РегистрыНакопления;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "РЕГИСТРБУХГАЛТЕРИИ" Тогда
|
||
Менеджер = РегистрыБухгалтерии;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "РЕГИСТРРАСЧЕТА" Тогда
|
||
|
||
Если ЧастиИмени.Количество() = 2 Тогда
|
||
Менеджер = РегистрыРасчета;
|
||
|
||
ИначеЕсли ЧастиИмени.Количество() = 4 Тогда
|
||
КлассПодчиненногоОМ = ЧастиИмени[2];
|
||
ИмяПодчиненногоОМ = ЧастиИмени[3];
|
||
|
||
Если ВРег(КлассПодчиненногоОМ) = "ПЕРЕРАСЧЕТ" Тогда
|
||
Менеджер = РегистрыРасчета[ИмяОМ].Перерасчеты;
|
||
ИмяОм = ИмяПодчиненногоОМ;
|
||
|
||
Иначе
|
||
Менеджер = Неопределено;
|
||
КонецЕсли;
|
||
|
||
Иначе
|
||
Менеджер = Неопределено;
|
||
КонецЕсли;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "БИЗНЕСПРОЦЕСС" Тогда
|
||
Менеджер = БизнесПроцессы;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "ЗАДАЧА" Тогда
|
||
Менеджер = Задачи;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "КОНСТАНТА" Тогда
|
||
Менеджер = Константы;
|
||
|
||
ИначеЕсли ВРег(КлассОМ) = "ПОСЛЕДОВАТЕЛЬНОСТЬ" Тогда
|
||
Менеджер = Последовательности;
|
||
|
||
Иначе
|
||
Менеджер = Неопределено;
|
||
КонецЕсли;
|
||
|
||
Если Менеджер = Неопределено Тогда
|
||
ПроверитьОбъектМетаданныхСуществует(ПолноеИмя);
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверное значение параметра %1 функции %2. У объекта метаданных ""%3"" нет менеджера объекта.'"),
|
||
"ПолноеИмя", "ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени", ПолноеИмя),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
Попытка
|
||
Возврат Менеджер[ИмяОМ];
|
||
Исключение
|
||
ПроверитьОбъектМетаданныхСуществует(ПолноеИмя);
|
||
ВызватьИсключение;
|
||
КонецПопытки;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает менеджер объекта по ссылке на объект.
|
||
// Ограничение: не обрабатываются точки маршрутов бизнес-процессов.
|
||
// См. также ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени.
|
||
//
|
||
// Параметры:
|
||
// Ссылка - ЛюбаяСсылка - объект, менеджер которого требуется получить.
|
||
//
|
||
// Возвращаемое значение:
|
||
// СправочникМенеджер, ДокументМенеджер, ОбработкаМенеджер, РегистрСведенийМенеджер - менеджер объекта.
|
||
//
|
||
// Пример:
|
||
// МенеджерСправочника = ОбщегоНазначения.МенеджерОбъектаПоСсылке(СсылкаНаОрганизацию);
|
||
// ПустаяСсылка = МенеджерСправочника.ПустаяСсылка();
|
||
//
|
||
Функция МенеджерОбъектаПоСсылке(Ссылка) Экспорт
|
||
|
||
ИмяОбъекта = Ссылка.Метаданные().Имя;
|
||
ТипСсылки = ТипЗнч(Ссылка);
|
||
|
||
Если Справочники.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
|
||
Возврат Справочники[ИмяОбъекта];
|
||
|
||
ИначеЕсли Документы.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
|
||
Возврат Документы[ИмяОбъекта];
|
||
|
||
ИначеЕсли БизнесПроцессы.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
|
||
Возврат БизнесПроцессы[ИмяОбъекта];
|
||
|
||
ИначеЕсли ПланыВидовХарактеристик.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
|
||
Возврат ПланыВидовХарактеристик[ИмяОбъекта];
|
||
|
||
ИначеЕсли ПланыСчетов.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
|
||
Возврат ПланыСчетов[ИмяОбъекта];
|
||
|
||
ИначеЕсли ПланыВидовРасчета.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
|
||
Возврат ПланыВидовРасчета[ИмяОбъекта];
|
||
|
||
ИначеЕсли Задачи.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
|
||
Возврат Задачи[ИмяОбъекта];
|
||
|
||
ИначеЕсли ПланыОбмена.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
|
||
Возврат ПланыОбмена[ИмяОбъекта];
|
||
|
||
ИначеЕсли Перечисления.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
|
||
Возврат Перечисления[ИмяОбъекта];
|
||
Иначе
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
|
||
КонецФункции
|
||
|
||
// Проверка того, что переданный тип является ссылочным типом данных.
|
||
// Для типа Неопределено возвращается Ложь.
|
||
//
|
||
// Параметры:
|
||
// ПроверяемыйТип - Тип - для проверки на ссылочный тип данных.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если это ссылка.
|
||
//
|
||
Функция ЭтоСсылка(ПроверяемыйТип) Экспорт
|
||
|
||
Возврат ПроверяемыйТип <> Тип("Неопределено") И ОписаниеТипаВсеСсылки().СодержитТип(ПроверяемыйТип);
|
||
|
||
КонецФункции
|
||
|
||
// Проверяет физическое наличие записи в информационной базе данных о переданном значении ссылки.
|
||
//
|
||
// Параметры:
|
||
// ПроверяемаяСсылка - ЛюбаяСсылка - значение любой ссылки информационной базы данных.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если существует.
|
||
//
|
||
Функция СсылкаСуществует(ПроверяемаяСсылка) Экспорт
|
||
|
||
ТекстЗапроса =
|
||
"ВЫБРАТЬ ПЕРВЫЕ 1
|
||
| 1 КАК Поле1
|
||
|ИЗ
|
||
| &ИмяТаблицы КАК Таблица
|
||
|ГДЕ
|
||
| Таблица.Ссылка = &Ссылка";
|
||
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ИмяТаблицы", ИмяТаблицыПоСсылке(ПроверяемаяСсылка));
|
||
|
||
Запрос = Новый Запрос;
|
||
Запрос.Текст = ТекстЗапроса;
|
||
Запрос.УстановитьПараметр("Ссылка", ПроверяемаяСсылка);
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
Возврат НЕ Запрос.Выполнить().Пустой();
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает имя вида объектов метаданных по ссылке на объект.
|
||
// Ограничение: не обрабатываются точки маршрутов бизнес-процессов.
|
||
// См. так же ВидОбъектаПоТипу.
|
||
//
|
||
// Параметры:
|
||
// Ссылка - ЛюбаяСсылка - объект, вид которого требуется получить.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - имя вида объектов метаданных. Например: "Справочник", "Документ".
|
||
//
|
||
Функция ВидОбъектаПоСсылке(Ссылка) Экспорт
|
||
|
||
Возврат ВидОбъектаПоТипу(ТипЗнч(Ссылка));
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает имя вида объектов метаданных по типу объекта.
|
||
// Ограничение: не обрабатываются точки маршрутов бизнес-процессов.
|
||
// См. так же ВидОбъектаПоСсылке.
|
||
//
|
||
// Параметры:
|
||
// ТипОбъекта - Тип - тип прикладного объекта, определенный в конфигурации.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - имя вида объектов метаданных. Например: "Справочник", "Документ".
|
||
//
|
||
Функция ВидОбъектаПоТипу(ТипОбъекта) Экспорт
|
||
|
||
Если Справочники.ТипВсеСсылки().СодержитТип(ТипОбъекта) Тогда
|
||
Возврат "Справочник";
|
||
|
||
ИначеЕсли Документы.ТипВсеСсылки().СодержитТип(ТипОбъекта) Тогда
|
||
Возврат "Документ";
|
||
|
||
ИначеЕсли БизнесПроцессы.ТипВсеСсылки().СодержитТип(ТипОбъекта) Тогда
|
||
Возврат "БизнесПроцесс";
|
||
|
||
ИначеЕсли ПланыВидовХарактеристик.ТипВсеСсылки().СодержитТип(ТипОбъекта) Тогда
|
||
Возврат "ПланВидовХарактеристик";
|
||
|
||
ИначеЕсли ПланыСчетов.ТипВсеСсылки().СодержитТип(ТипОбъекта) Тогда
|
||
Возврат "ПланСчетов";
|
||
|
||
ИначеЕсли ПланыВидовРасчета.ТипВсеСсылки().СодержитТип(ТипОбъекта) Тогда
|
||
Возврат "ПланВидовРасчета";
|
||
|
||
ИначеЕсли Задачи.ТипВсеСсылки().СодержитТип(ТипОбъекта) Тогда
|
||
Возврат "Задача";
|
||
|
||
ИначеЕсли ПланыОбмена.ТипВсеСсылки().СодержитТип(ТипОбъекта) Тогда
|
||
Возврат "ПланОбмена";
|
||
|
||
ИначеЕсли Перечисления.ТипВсеСсылки().СодержитТип(ТипОбъекта) Тогда
|
||
Возврат "Перечисление";
|
||
|
||
Иначе
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверный тип значения параметра %1 функции %2: %3.'"), Строка(ТипОбъекта)),
|
||
"ТипОбъекта", "ОбщегоНазначения.ВидОбъектаПоТипу", КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает полное имя объекта метаданных по переданному значению ссылки.
|
||
//
|
||
// Параметры:
|
||
// Ссылка - ЛюбаяСсылка - объект, для которого необходимо получить имя таблицы ИБ.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - полное имя объекта метаданных для указанного объекта. Например: "Справочник.Номенклатура".
|
||
//
|
||
Функция ИмяТаблицыПоСсылке(Ссылка) Экспорт
|
||
|
||
Возврат Ссылка.Метаданные().ПолноеИмя();
|
||
|
||
КонецФункции
|
||
|
||
// Проверяет, что переданное значение имеет ссылочный тип данных.
|
||
//
|
||
// Параметры:
|
||
// Значение - Произвольный - проверяемое значение.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если тип значения ссылочный.
|
||
//
|
||
Функция ЗначениеСсылочногоТипа(Значение) Экспорт
|
||
|
||
Возврат ЭтоСсылка(ТипЗнч(Значение));
|
||
|
||
КонецФункции
|
||
|
||
// Проверяет, является ли элемент справочника или плана видов характеристик группой элементов.
|
||
//
|
||
// Параметры:
|
||
// Объект - СправочникСсылка
|
||
// - ПланВидовХарактеристикСсылка
|
||
// - СправочникОбъект
|
||
// - ПланВидовХарактеристикОбъект - проверяемый объект.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево
|
||
//
|
||
Функция ОбъектЯвляетсяГруппой(Объект) Экспорт
|
||
|
||
Если ЗначениеСсылочногоТипа(Объект) Тогда
|
||
Ссылка = Объект;
|
||
Иначе
|
||
Ссылка = Объект.Ссылка;
|
||
КонецЕсли;
|
||
|
||
МетаданныеОбъекта = Ссылка.Метаданные();
|
||
Если ЭтоСправочник(МетаданныеОбъекта) Тогда
|
||
Если Не МетаданныеОбъекта.Иерархический
|
||
Или МетаданныеОбъекта.ВидИерархии <> Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
ИначеЕсли Не ЭтоПланВидовХарактеристик(МетаданныеОбъекта) Или Не МетаданныеОбъекта.Иерархический Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
Если Ссылка <> Объект Тогда
|
||
Возврат Объект.ЭтоГруппа;
|
||
КонецЕсли;
|
||
|
||
Возврат ЗначениеРеквизитаОбъекта(Ссылка, "ЭтоГруппа") = Истина;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает ссылку, соответствующую объекту метаданных, для использования в базе данных.
|
||
// См. также ОбщегоНазначения.ИдентификаторыОбъектовМетаданных.
|
||
//
|
||
// Ссылки возвращаются для следующих объектов метаданных:
|
||
// - Подсистемы (см. также ОбщегоНазначенияПереопределяемый.ПриДобавленииПереименованийОбъектовМетаданных);
|
||
// - Роли (см. также ОбщегоНазначенияПереопределяемый.ПриДобавленииПереименованийОбъектовМетаданных);
|
||
// - ПланыОбмена;
|
||
// - Константы;
|
||
// - Справочники;
|
||
// - Документы;
|
||
// - ЖурналыДокументов;
|
||
// - Отчеты;
|
||
// - Обработки;
|
||
// - ПланыВидовХарактеристик;
|
||
// - ПланыСчетов;
|
||
// - ПланыВидовРасчета;
|
||
// - РегистрыСведений;
|
||
// - РегистрыНакопления;
|
||
// - РегистрыБухгалтерии;
|
||
// - РегистрыРасчета;
|
||
// - БизнесПроцессы;
|
||
// - Задачи.
|
||
//
|
||
// Параметры:
|
||
// ОписаниеОбъектаМетаданных - ОбъектМетаданных - объект метаданных конфигурации;
|
||
// - Тип - тип, который можно использовать в функции Метаданные.НайтиПоТипу;
|
||
// - Строка - полное имя объекта метаданных, которое можно
|
||
// использовать в функции Метаданные.НайтиПоПолномуИмени.
|
||
//
|
||
// ВызыватьИсключение - Булево - если Ложь, то вместо вызова исключения возвращается Null для несуществующего
|
||
// или неподдерживаемого объекта метаданных.
|
||
//
|
||
// Возвращаемое значение:
|
||
// СправочникСсылка.ИдентификаторыОбъектовМетаданных
|
||
// СправочникСсылка.ИдентификаторыОбъектовРасширений
|
||
// Null
|
||
//
|
||
// Пример:
|
||
// Идентификатор = ОбщегоНазначения.ИдентификаторОбъектаМетаданных(ТипЗнч(Ссылка));
|
||
// Идентификатор = ОбщегоНазначения.ИдентификаторОбъектаМетаданных(ОбъектМетаданных);
|
||
// Идентификатор = ОбщегоНазначения.ИдентификаторОбъектаМетаданных("Справочник.Организации");
|
||
//
|
||
Функция ИдентификаторОбъектаМетаданных(ОписаниеОбъектаМетаданных, ВызыватьИсключение = Истина) Экспорт
|
||
|
||
Возврат Справочники.ИдентификаторыОбъектовМетаданных.ИдентификаторОбъектаМетаданных(
|
||
ОписаниеОбъектаМетаданных, ВызыватьИсключение);
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает ссылки, соответствующие объектам метаданных, для использования в базе данных.
|
||
// См. также ОбщегоНазначения.ИдентификаторОбъектаМетаданных.
|
||
//
|
||
// Ссылки возвращаются для следующих объектов метаданных:
|
||
// - Подсистемы (см. также ОбщегоНазначенияПереопределяемый.ПриДобавленииПереименованийОбъектовМетаданных);
|
||
// - Роли (см. также ОбщегоНазначенияПереопределяемый.ПриДобавленииПереименованийОбъектовМетаданных);
|
||
// - ПланыОбмена.
|
||
// - Константы.
|
||
// - Справочники.
|
||
// - Документы.
|
||
// - ЖурналыДокументов.
|
||
// - Отчеты.
|
||
// - Обработки.
|
||
// - ПланыВидовХарактеристик.
|
||
// - ПланыСчетов.
|
||
// - ПланыВидовРасчета.
|
||
// - РегистрыСведений.
|
||
// - РегистрыНакопления.
|
||
// - РегистрыБухгалтерии.
|
||
// - РегистрыРасчета.
|
||
// - БизнесПроцессы.
|
||
// - Задачи.
|
||
//
|
||
// Параметры:
|
||
// ОписаниеОбъектовМетаданных - Массив из ОбъектМетаданных - объекты метаданных конфигурации;
|
||
// - Массив из Строка - полные имена объектов метаданных, которые можно использовать
|
||
// в функции Метаданные.НайтиПоПолномуИмени;
|
||
// - Массив из Тип - типы, которые можно использовать в функции Метаданные.НайтиПоТипу.
|
||
// ВызыватьИсключение - Булево - если Ложь, то несуществующие и неподдерживаемые объекты метаданных
|
||
// будут пропущены в возвращаемом значении.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Соответствие из КлючИЗначение:
|
||
// * Ключ - Строка - полное имя указанного объекта метаданных.
|
||
// * Значение - СправочникСсылка.ИдентификаторыОбъектовМетаданных
|
||
// - СправочникСсылка.ИдентификаторыОбъектовРасширений - найденный идентификатор.
|
||
//
|
||
// Пример:
|
||
// ПолныеИмена = Новый Массив;
|
||
// ПолныеИмена.Добавить(Метаданные.Справочники.Валюты.ПолноеИмя());
|
||
// ПолныеИмена.Добавить(Метаданные.РегистрыСведений.КурсыВалют.ПолноеИмя());
|
||
// Идентификаторы = ОбщегоНазначения.ИдентификаторыОбъектовМетаданных(ПолныеИмена);
|
||
//
|
||
Функция ИдентификаторыОбъектовМетаданных(ОписаниеОбъектовМетаданных, ВызыватьИсключение = Истина) Экспорт
|
||
|
||
Возврат Справочники.ИдентификаторыОбъектовМетаданных.ИдентификаторыОбъектовМетаданных(
|
||
ОписаниеОбъектовМетаданных, ВызыватьИсключение);
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает объект метаданных по переданному идентификатору.
|
||
//
|
||
// Параметры:
|
||
// Идентификатор - СправочникСсылка.ИдентификаторыОбъектовМетаданных
|
||
// - СправочникСсылка.ИдентификаторыОбъектовРасширений - идентификатор
|
||
// объекта метаданных конфигурации или расширения конфигурации.
|
||
//
|
||
// ВызыватьИсключение - Булево - если Ложь, тогда в случае, когда объект метаданных
|
||
// не существует или недоступен, возвращает соответственно
|
||
// Null или Неопределено вместо вызова исключения.
|
||
//
|
||
// Возвращаемое значение:
|
||
// ОбъектМетаданных - объект метаданных, соответствующий идентификатору.
|
||
//
|
||
// Null - возвращается, когда ВызыватьИсключение = Ложь. Обозначает, что
|
||
// для указанного идентификатора объект метаданных не существует (идентификатор устарел).
|
||
//
|
||
// Неопределено - возвращается, когда ВызыватьИсключение = Ложь. Обозначает,
|
||
// что идентификатор действующий, но в текущем сеансе ОбъектМетаданных не может быть получен.
|
||
// Для расширений конфигурации это значит, что расширение установлено, но не подключено,
|
||
// либо потому что перезапуск еще не выполнен, либо при подключении произошла ошибка.
|
||
// Для конфигурации это значит, что в новом сеансе (новом динамическом поколении) объект
|
||
// метаданных имеется, а в текущем (старом) сеансе нет.
|
||
//
|
||
Функция ОбъектМетаданныхПоИдентификатору(Идентификатор, ВызыватьИсключение = Истина) Экспорт
|
||
|
||
Возврат Справочники.ИдентификаторыОбъектовМетаданных.ОбъектМетаданныхПоИдентификатору(
|
||
Идентификатор, ВызыватьИсключение);
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает объекты метаданных по переданным идентификаторам.
|
||
//
|
||
// Параметры:
|
||
// Идентификаторы - Массив - со значениями:
|
||
// * Значение - СправочникСсылка.ИдентификаторыОбъектовМетаданных
|
||
// - СправочникСсылка.ИдентификаторыОбъектовРасширений - идентификаторы
|
||
// объектов метаданных конфигурации или расширений конфигурации.
|
||
//
|
||
// ВызыватьИсключение - Булево - если Ложь, тогда в случае, когда объект метаданных
|
||
// не существует или недоступен, возвращает соответственно
|
||
// Null или Неопределено вместо вызова исключения.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Соответствие из КлючИЗначение:
|
||
// * Ключ - СправочникСсылка.ИдентификаторыОбъектовМетаданных
|
||
// - СправочникСсылка.ИдентификаторыОбъектовРасширений - переданный идентификатор.
|
||
// * Значение - ОбъектМетаданных - объект метаданных, соответствующий идентификатору.
|
||
// - Null - возвращается, когда ВызыватьИсключение = Ложь. Обозначает, что
|
||
// для указанного идентификатора объект метаданных не существует (идентификатор устарел).
|
||
// - Неопределено - возвращается, когда ВызыватьИсключение = Ложь. Обозначает,
|
||
// что идентификатор действующий, но в текущем сеансе ОбъектМетаданных не может быть получен.
|
||
// Для расширений конфигурации это значит, что расширение установлено, но не подключено,
|
||
// либо потому что перезапуск еще не выполнен, либо при подключении произошла ошибка.
|
||
// Для конфигурации это значит, что в новом сеансе (новом динамическом поколении) объект
|
||
// метаданных имеется, а в текущем (старом) сеансе нет.
|
||
//
|
||
Функция ОбъектыМетаданныхПоИдентификаторам(Идентификаторы, ВызыватьИсключение = Истина) Экспорт
|
||
|
||
Возврат Справочники.ИдентификаторыОбъектовМетаданных.ОбъектыМетаданныхПоИдентификаторам(
|
||
Идентификаторы, ВызыватьИсключение);
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает ОбъектМетаданных, быстро найденный по полному имени.
|
||
// Более производительный аналог метода платформы Метаданные.НайтиПоПолномуИмени
|
||
// для корневых объектов метаданных.
|
||
//
|
||
// Параметры:
|
||
// ПолноеИмя - Строка - полное имя объекта метаданных, например, Справочник.Организации
|
||
//
|
||
// Возвращаемое значение:
|
||
// ОбъектМетаданных - когда найден
|
||
// Неопределено - когда не найден
|
||
//
|
||
Функция ОбъектМетаданныхПоПолномуИмени(ПолноеИмя) Экспорт
|
||
|
||
ПозицияТочки = СтрНайти(ПолноеИмя, ".");
|
||
ИмяБазовогоТипа = Лев(ПолноеИмя, ПозицияТочки - 1);
|
||
|
||
ИменаКоллекций = СтандартныеПодсистемыПовтИсп.ИменаКоллекцийПоИменамБазовыхТипов();
|
||
Коллекция = ИменаКоллекций.Получить(ВРег(ИмяБазовогоТипа));
|
||
|
||
Если Коллекция <> Неопределено Тогда
|
||
Если Коллекция <> "Подсистемы" Тогда
|
||
ИмяОбъекта = Сред(ПолноеИмя, ПозицияТочки + 1);
|
||
ОбъектМетаданных = Метаданные[Коллекция].Найти(ИмяОбъекта);
|
||
Иначе
|
||
ИменаПодсистем = СтрРазделить(ВРег(ПолноеИмя), ".");
|
||
Количество = ИменаПодсистем.Количество();
|
||
Подсистема = Метаданные;
|
||
ОбъектМетаданных = Неопределено;
|
||
Индекс = 0;
|
||
Пока Истина Цикл
|
||
Индекс = Индекс + 1;
|
||
Если Индекс >= Количество Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
ИмяПодсистемы = ИменаПодсистем[Индекс];
|
||
Подсистема = Подсистема.Подсистемы.Найти(ИмяПодсистемы);
|
||
Если Подсистема = Неопределено Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
Индекс = Индекс + 1;
|
||
Если Индекс = Количество Тогда
|
||
ОбъектМетаданных = Подсистема;
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Если ОбъектМетаданных = Неопределено Тогда
|
||
ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(ПолноеИмя);
|
||
КонецЕсли;
|
||
|
||
Возврат ОбъектМетаданных;
|
||
|
||
КонецФункции
|
||
|
||
// Определяет доступность объекта метаданных по функциональным опциям.
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных
|
||
// - Строка - проверяемый объект метаданных.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если объект доступен.
|
||
//
|
||
Функция ОбъектМетаданныхДоступенПоФункциональнымОпциям(Знач ОбъектМетаданных) Экспорт
|
||
Если ОбъектМетаданных = Неопределено Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
Если ТипЗнч(ОбъектМетаданных) <> Тип("Строка") Тогда
|
||
ПолноеИмя = ОбъектМетаданных.ПолноеИмя();
|
||
Иначе
|
||
ПолноеИмя = ОбъектМетаданных;
|
||
КонецЕсли;
|
||
Возврат СтандартныеПодсистемыПовтИсп.ДоступностьОбъектовПоОпциям().Получить(ПолноеИмя) <> Ложь;
|
||
КонецФункции
|
||
|
||
// Добавляет описание переименования объекта метаданных при переходе на указанную версию конфигурации.
|
||
// Добавление выполняется в структуру Итог, которая передается в
|
||
// процедуру ОбщегоНазначенияПереопределяемый.ПриДобавленииПереименованийОбъектовМетаданных.
|
||
//
|
||
// Параметры:
|
||
// Итог - см. ОбщегоНазначенияПереопределяемый.ПриДобавленииПереименованийОбъектовМетаданных.Итог
|
||
// ВерсияИБ - Строка - версия конечной конфигурации, при переходе на которую нужно
|
||
// выполнить переименование, например, "2.1.2.14".
|
||
// СтароеПолноеИмя - Строка - старое полное имя объекта метаданных, которое нужно переименовать,
|
||
// например "Подсистема.СлужебныеПодсистемы".
|
||
// НовоеПолноеИмя - Строка - новое полное имя объекта метаданных, на которое нужно переименовать,
|
||
// например "Подсистема.СервисныеПодсистемы".
|
||
// ИдентификаторБиблиотеки - Строка - внутренний идентификатор библиотеки, к которой относится ВерсияИБ.
|
||
// Для основной конфигурации не требуется.
|
||
// Например, "СтандартныеПодсистемы" - как указано
|
||
// в ОбновлениеИнформационнойБазыБСП.ПриДобавленииПодсистемы.
|
||
// Пример:
|
||
// ОбщегоНазначения.ДобавитьПереименование(Итог, "2.1.2.14",
|
||
// "Подсистема.СлужебныеПодсистемы",
|
||
// "Подсистема.СервисныеПодсистемы");
|
||
//
|
||
Процедура ДобавитьПереименование(Итог, ВерсияИБ, СтароеПолноеИмя, НовоеПолноеИмя, ИдентификаторБиблиотеки = "") Экспорт
|
||
|
||
Справочники.ИдентификаторыОбъектовМетаданных.ДобавитьПереименование(Итог,
|
||
ВерсияИБ, СтароеПолноеИмя, НовоеПолноеИмя, ИдентификаторБиблиотеки);
|
||
|
||
КонецПроцедуры
|
||
|
||
// Возвращает строковое представление типа, например, "СправочникСсылка.ИмяОбъекта", "ДокументСсылка.ИмяОбъекта".
|
||
// Для остальных типов приводит тип к строке, например "Число".
|
||
//
|
||
// Параметры:
|
||
// Тип - Тип - для которого надо получить представление.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка
|
||
//
|
||
Функция СтроковоеПредставлениеТипа(Тип) Экспорт
|
||
|
||
Представление = "";
|
||
|
||
Если ЭтоСсылка(Тип) Тогда
|
||
|
||
ПолноеИмя = Метаданные.НайтиПоТипу(Тип).ПолноеИмя();
|
||
ИмяОбъекта = СтрРазделить(ПолноеИмя, ".")[1];
|
||
|
||
Если Справочники.ТипВсеСсылки().СодержитТип(Тип) Тогда
|
||
Представление = "СправочникСсылка";
|
||
|
||
ИначеЕсли Документы.ТипВсеСсылки().СодержитТип(Тип) Тогда
|
||
Представление = "ДокументСсылка";
|
||
|
||
ИначеЕсли БизнесПроцессы.ТипВсеСсылки().СодержитТип(Тип) Тогда
|
||
Представление = "БизнесПроцессСсылка";
|
||
|
||
ИначеЕсли БизнесПроцессы.ТипВсеСсылкиТочекМаршрутаБизнесПроцессов().СодержитТип(Тип) Тогда
|
||
Представление = "ТочкаМаршрутаБизнесПроцессаСсылка";
|
||
|
||
ИначеЕсли ПланыВидовХарактеристик.ТипВсеСсылки().СодержитТип(Тип) Тогда
|
||
Представление = "ПланВидовХарактеристикСсылка";
|
||
|
||
ИначеЕсли ПланыСчетов.ТипВсеСсылки().СодержитТип(Тип) Тогда
|
||
Представление = "ПланСчетовСсылка";
|
||
|
||
ИначеЕсли ПланыВидовРасчета.ТипВсеСсылки().СодержитТип(Тип) Тогда
|
||
Представление = "ПланВидовРасчетаСсылка";
|
||
|
||
ИначеЕсли Задачи.ТипВсеСсылки().СодержитТип(Тип) Тогда
|
||
Представление = "ЗадачаСсылка";
|
||
|
||
ИначеЕсли ПланыОбмена.ТипВсеСсылки().СодержитТип(Тип) Тогда
|
||
Представление = "ПланОбменаСсылка";
|
||
|
||
ИначеЕсли Перечисления.ТипВсеСсылки().СодержитТип(Тип) Тогда
|
||
Представление = "ПеречислениеСсылка";
|
||
|
||
КонецЕсли;
|
||
|
||
Результат = ?(Представление = "", Представление, Представление + "." + ИмяОбъекта);
|
||
|
||
ИначеЕсли Тип = Тип("Неопределено") Тогда
|
||
Результат = "Неопределено";
|
||
|
||
ИначеЕсли Тип = Тип("Строка") Тогда
|
||
Результат = "Строка";
|
||
|
||
ИначеЕсли Тип = Тип("Число") Тогда
|
||
Результат = "Число";
|
||
|
||
ИначеЕсли Тип = Тип("Булево") Тогда
|
||
Результат = "Булево";
|
||
|
||
ИначеЕсли Тип = Тип("Дата") Тогда
|
||
Результат = "Дата";
|
||
|
||
Иначе
|
||
|
||
Результат = Строка(Тип);
|
||
|
||
КонецЕсли;
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает таблицу значений с описанием требуемых свойств всех реквизитов объекта метаданных.
|
||
// Получает значения свойств стандартных реквизитов и пользовательских реквизитов (созданных в режиме конфигуратора).
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - объект, для которого необходимо получить значение свойств реквизитов.
|
||
// Например: Метаданные.Документ.РеализацияТоваровИУслуг
|
||
// Свойства - Строка - свойства реквизитов, перечисленные через запятую, значение которых необходимо получить.
|
||
// Например: "Имя, Тип, Синоним, Подсказка".
|
||
//
|
||
// Возвращаемое значение:
|
||
// ТаблицаЗначений - описание требуемых свойств всех реквизитов объекта метаданных.
|
||
//
|
||
Функция ОписаниеСвойствОбъекта(ОбъектМетаданных, Свойства) Экспорт
|
||
|
||
МассивСвойств = СтрРазделить(Свойства, ",");
|
||
|
||
// Возвращаемое значение функции.
|
||
ТаблицаОписанияСвойствОбъекта = Новый ТаблицаЗначений;
|
||
|
||
// Добавляем в таблицу поля согласно именам переданных свойств.
|
||
Для Каждого ИмяСвойства Из МассивСвойств Цикл
|
||
ТаблицаОписанияСвойствОбъекта.Колонки.Добавить(СокрЛП(ИмяСвойства));
|
||
КонецЦикла;
|
||
|
||
// Заполняем строку таблицы свойствами реквизитов объекта метаданных.
|
||
Для Каждого Реквизит Из ОбъектМетаданных.Реквизиты Цикл
|
||
ЗаполнитьЗначенияСвойств(ТаблицаОписанияСвойствОбъекта.Добавить(), Реквизит);
|
||
КонецЦикла;
|
||
|
||
// Заполняем строку таблицы свойствами стандартных реквизитов объекта метаданных.
|
||
Для Каждого Реквизит Из ОбъектМетаданных.СтандартныеРеквизиты Цикл
|
||
ЗаполнитьЗначенияСвойств(ТаблицаОписанияСвойствОбъекта.Добавить(), Реквизит);
|
||
КонецЦикла;
|
||
|
||
Возврат ТаблицаОписанияСвойствОбъекта;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает признак того, что реквизит входит в подмножество стандартных реквизитов.
|
||
//
|
||
// Параметры:
|
||
// СтандартныеРеквизиты - ОписанияСтандартныхРеквизитов - тип и значение, описывающие коллекцию настроек различных
|
||
// стандартных реквизитов;
|
||
// ИмяРеквизита - Строка - реквизит, который необходимо проверить на принадлежность множеству стандартных
|
||
// реквизитов.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если реквизит входит в подмножество стандартных реквизитов.
|
||
//
|
||
Функция ЭтоСтандартныйРеквизит(СтандартныеРеквизиты, ИмяРеквизита) Экспорт
|
||
|
||
Для Каждого Реквизит Из СтандартныеРеквизиты Цикл
|
||
Если Реквизит.Имя = ИмяРеквизита Тогда
|
||
Возврат Истина;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Возврат Ложь;
|
||
|
||
КонецФункции
|
||
|
||
// Позволяет определить, есть ли среди реквизитов объекта реквизит с переданным именем.
|
||
//
|
||
// Параметры:
|
||
// ИмяРеквизита - Строка - имя реквизита;
|
||
// МетаданныеОбъекта - ОбъектМетаданных - объект, в котором требуется проверить наличие реквизита.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если есть.
|
||
//
|
||
Функция ЕстьРеквизитОбъекта(ИмяРеквизита, МетаданныеОбъекта) Экспорт
|
||
|
||
Реквизиты = МетаданныеОбъекта.Реквизиты; // КоллекцияОбъектовМетаданных
|
||
Возврат НЕ (Реквизиты.Найти(ИмяРеквизита) = Неопределено);
|
||
|
||
КонецФункции
|
||
|
||
// Проверить, что описание типа состоит из единственного типа значения и
|
||
// совпадает с нужным типом.
|
||
//
|
||
// Параметры:
|
||
// ОписаниеТипа - ОписаниеТипов - проверяемая коллекция типов;
|
||
// ТипЗначения - Тип - проверяемый тип.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если совпадает.
|
||
//
|
||
// Пример:
|
||
// Если ОбщегоНазначения.ОписаниеТипаСостоитИзТипа(ТипЗначенияСвойства, Тип("Булево") Тогда
|
||
// // Выводим поле в виде флажка.
|
||
// КонецЕсли;
|
||
//
|
||
Функция ОписаниеТипаСостоитИзТипа(ОписаниеТипа, ТипЗначения) Экспорт
|
||
|
||
Если ОписаниеТипа.Типы().Количество() = 1
|
||
И ОписаниеТипа.Типы().Получить(0) = ТипЗначения Тогда
|
||
Возврат Истина;
|
||
КонецЕсли;
|
||
|
||
Возврат Ложь;
|
||
|
||
КонецФункции
|
||
|
||
// Создает объект ОписаниеТипов, содержащий тип Строка.
|
||
//
|
||
// Параметры:
|
||
// ДлинаСтроки - Число - длина строки.
|
||
//
|
||
// Возвращаемое значение:
|
||
// ОписаниеТипов - описание типа Строка.
|
||
//
|
||
Функция ОписаниеТипаСтрока(ДлинаСтроки) Экспорт
|
||
|
||
Возврат Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(ДлинаСтроки));
|
||
|
||
КонецФункции
|
||
|
||
// Создает объект ОписаниеТипов, содержащий тип Число.
|
||
//
|
||
// Параметры:
|
||
// Разрядность - Число - общее количество разрядов числа (количество разрядов
|
||
// целой части плюс количество разрядов дробной части).
|
||
// РазрядностьДробнойЧасти - Число - число разрядов дробной части.
|
||
// ЗнакЧисла - ДопустимыйЗнак - допустимый знак числа.
|
||
//
|
||
// Возвращаемое значение:
|
||
// ОписаниеТипов - описание типа Число.
|
||
//
|
||
Функция ОписаниеТипаЧисло(Разрядность, РазрядностьДробнойЧасти = 0, Знач ЗнакЧисла = Неопределено) Экспорт
|
||
|
||
Если ЗнакЧисла = Неопределено Тогда
|
||
ЗнакЧисла = ДопустимыйЗнак.Любой;
|
||
КонецЕсли;
|
||
|
||
Возврат Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Разрядность, РазрядностьДробнойЧасти, ЗнакЧисла));
|
||
|
||
КонецФункции
|
||
|
||
// Создает объект ОписаниеТипов, содержащий тип Дата.
|
||
//
|
||
// Параметры:
|
||
// ЧастиДаты - ЧастиДаты - набор вариантов использования значений типа Дата.
|
||
//
|
||
// Возвращаемое значение:
|
||
// ОписаниеТипов - описание типа Дата.
|
||
//
|
||
Функция ОписаниеТипаДата(ЧастиДаты) Экспорт
|
||
|
||
Возврат Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты));
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает описание типа, включающего в себя все возможные ссылочные типы конфигурации.
|
||
//
|
||
// Возвращаемое значение:
|
||
// ОписаниеТипов - все ссылочные типы конфигурации.
|
||
//
|
||
Функция ОписаниеТипаВсеСсылки() Экспорт
|
||
|
||
Возврат СтандартныеПодсистемыПовтИсп.ОписаниеТипаВсеСсылки();
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает строковое представление списка, заданное в свойствах объекта метаданных.
|
||
// В зависимости от того, какие свойства объекта метаданных заполнены, функция возвращают одно из них в указанном
|
||
// порядке: Расширенное представление списка, Представление списка, Синоним или Имя.
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - произвольный объект.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - представление списка.
|
||
//
|
||
Функция ПредставлениеСписка(ОбъектМетаданных) Экспорт
|
||
|
||
СвойстваОбъекта = Новый Структура("РасширенноеПредставлениеСписка,ПредставлениеСписка");
|
||
ЗаполнитьЗначенияСвойств(СвойстваОбъекта, ОбъектМетаданных);
|
||
|
||
Если ЗначениеЗаполнено(СвойстваОбъекта.РасширенноеПредставлениеСписка) Тогда
|
||
Результат = СвойстваОбъекта.РасширенноеПредставлениеСписка;
|
||
ИначеЕсли ЗначениеЗаполнено(СвойстваОбъекта.ПредставлениеСписка) Тогда
|
||
Результат = СвойстваОбъекта.ПредставлениеСписка;
|
||
Иначе
|
||
Результат = ОбъектМетаданных.Представление();
|
||
КонецЕсли;
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает строковое представление объекта, заданное в свойствах объекта метаданных.
|
||
// В зависимости от того, какие свойства объекта метаданных заполнены, функция возвращают одно из них в указанном
|
||
// порядке: Расширенное представление объекта, Представление объекта, Синоним или Имя.
|
||
//
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных - произвольный объект.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - представление объекта.
|
||
//
|
||
Функция ПредставлениеОбъекта(ОбъектМетаданных) Экспорт
|
||
|
||
СвойстваОбъекта = Новый Структура("РасширенноеПредставлениеОбъекта,ПредставлениеОбъекта");
|
||
ЗаполнитьЗначенияСвойств(СвойстваОбъекта, ОбъектМетаданных);
|
||
|
||
Если ЗначениеЗаполнено(СвойстваОбъекта.РасширенноеПредставлениеОбъекта) Тогда
|
||
Результат = СвойстваОбъекта.РасширенноеПредставлениеОбъекта;
|
||
ИначеЕсли ЗначениеЗаполнено(СвойстваОбъекта.ПредставлениеОбъекта) Тогда
|
||
Результат = СвойстваОбъекта.ПредставлениеОбъекта;
|
||
Иначе
|
||
Результат = ОбъектМетаданных.Представление();
|
||
КонецЕсли;
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область ХранилищеНастроек
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
// Сохранение, чтение и удаление настроек из хранилищ.
|
||
|
||
// Сохраняет настройку в хранилище общих настроек, как метод платформы Сохранить,
|
||
// объектов СтандартноеХранилищеНастроекМенеджер или ХранилищеНастроекМенеджер.<Имя хранилища>,
|
||
// но с поддержкой длины ключа настроек более 128 символов путем хеширования части,
|
||
// которая превышает 96 символов.
|
||
// Если нет права СохранениеДанныхПользователя, сохранение пропускается без ошибки.
|
||
//
|
||
// Параметры:
|
||
// КлючОбъекта - Строка - см. синтакс-помощник платформы.
|
||
// КлючНастроек - Строка - см. синтакс-помощник платформы.
|
||
// Настройки - Произвольный - см. синтакс-помощник платформы.
|
||
// ОписаниеНастроек - ОписаниеНастроек - см. синтакс-помощник платформы.
|
||
// ИмяПользователя - Строка - см. синтакс-помощник платформы.
|
||
// ОбновитьПовторноИспользуемыеЗначения - Булево - выполнить одноименный метод платформы.
|
||
//
|
||
Процедура ХранилищеОбщихНастроекСохранить(КлючОбъекта, КлючНастроек, Настройки,
|
||
ОписаниеНастроек = Неопределено,
|
||
ИмяПользователя = Неопределено,
|
||
ОбновитьПовторноИспользуемыеЗначения = Ложь) Экспорт
|
||
|
||
ХранилищеСохранить(ХранилищеОбщихНастроек,
|
||
КлючОбъекта,
|
||
КлючНастроек,
|
||
Настройки,
|
||
ОписаниеНастроек,
|
||
ИмяПользователя,
|
||
ОбновитьПовторноИспользуемыеЗначения);
|
||
|
||
КонецПроцедуры
|
||
|
||
// Сохраняет несколько настроек в хранилище общих настроек, как метод платформы Сохранить,
|
||
// объектов СтандартноеХранилищеНастроекМенеджер или ХранилищеНастроекМенеджер.<Имя хранилища>,
|
||
// но с поддержкой длины ключа настроек более 128 символов путем хеширования части,
|
||
// которая превышает 96 символов.
|
||
// Если нет права СохранениеДанныхПользователя, сохранение пропускается без ошибки.
|
||
//
|
||
// Параметры:
|
||
// НесколькоНастроек - Массив - со значениями:
|
||
// * Значение - Структура:
|
||
// * Объект - Строка - см. параметр КлючОбъекта в синтакс-помощнике платформы.
|
||
// * Настройка - Строка - см. параметр КлючНастроек в синтакс-помощнике платформы.
|
||
// * Значение - Произвольный - см. параметр Настройки в синтакс-помощнике платформы.
|
||
//
|
||
// ОбновитьПовторноИспользуемыеЗначения - Булево - выполнить одноименный метод платформы.
|
||
//
|
||
Процедура ХранилищеОбщихНастроекСохранитьМассив(НесколькоНастроек,
|
||
ОбновитьПовторноИспользуемыеЗначения = Ложь) Экспорт
|
||
|
||
Если Не ПравоДоступа("СохранениеДанныхПользователя", Метаданные) Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
Для Каждого Элемент Из НесколькоНастроек Цикл
|
||
ХранилищеОбщихНастроек.Сохранить(Элемент.Объект, КлючНастроек(Элемент.Настройка), Элемент.Значение);
|
||
КонецЦикла;
|
||
|
||
Если ОбновитьПовторноИспользуемыеЗначения Тогда
|
||
ОбновитьПовторноИспользуемыеЗначения();
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Загружает настройку из хранилища общих настроек, как метод платформы Загрузить,
|
||
// объектов СтандартноеХранилищеНастроекМенеджер или ХранилищеНастроекМенеджер.<Имя хранилища>,
|
||
// но с поддержкой длины ключа настроек более 128 символов путем хеширования части,
|
||
// которая превышает 96 символов.
|
||
// Кроме того, возвращает указанное значение по умолчанию, если настройки не существуют.
|
||
// Если нет права СохранениеДанныхПользователя, возвращается значение по умолчанию без ошибки.
|
||
//
|
||
// В возвращаемом значении очищаются ссылки на несуществующий объект в базе данных, а именно
|
||
// - возвращаемая ссылка заменяется на указанное значение по умолчанию;
|
||
// - из данных типа Массив ссылки удаляются;
|
||
// - у данных типа Структура и Соответствие ключ не меняется, а значение устанавливается Неопределено;
|
||
// - анализ значений в данных типа Массив, Структура, Соответствие выполняется рекурсивно.
|
||
//
|
||
// Параметры:
|
||
// КлючОбъекта - Строка - см. синтакс-помощник платформы.
|
||
// КлючНастроек - Строка - см. синтакс-помощник платформы.
|
||
// ЗначениеПоУмолчанию - Произвольный - значение, которое возвращается, если настройки не существуют.
|
||
// Если не указано, возвращается значение Неопределено.
|
||
// ОписаниеНастроек - ОписаниеНастроек - см. синтакс-помощник платформы.
|
||
// ИмяПользователя - Строка - см. синтакс-помощник платформы.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Произвольный - см. синтакс-помощник платформы.
|
||
//
|
||
Функция ХранилищеОбщихНастроекЗагрузить(КлючОбъекта, КлючНастроек, ЗначениеПоУмолчанию = Неопределено,
|
||
ОписаниеНастроек = Неопределено, ИмяПользователя = Неопределено) Экспорт
|
||
|
||
Возврат ХранилищеЗагрузить(ХранилищеОбщихНастроек,
|
||
КлючОбъекта,
|
||
КлючНастроек,
|
||
ЗначениеПоУмолчанию,
|
||
ОписаниеНастроек,
|
||
ИмяПользователя);
|
||
|
||
КонецФункции
|
||
|
||
// Удаляет настройку из хранилища общих настроек, как метод платформы Удалить,
|
||
// объектов СтандартноеХранилищеНастроекМенеджер или ХранилищеНастроекМенеджер.<Имя хранилища>,
|
||
// но с поддержкой длины ключа настроек более 128 символов путем хеширования части,
|
||
// которая превышает 96 символов.
|
||
// Если нет права СохранениеДанныхПользователя, удаление пропускается без ошибки.
|
||
//
|
||
// Параметры:
|
||
// КлючОбъекта - Строка
|
||
// - Неопределено - см. синтакс-помощник платформы.
|
||
// КлючНастроек - Строка
|
||
// - Неопределено - см. синтакс-помощник платформы.
|
||
// ИмяПользователя - Строка
|
||
// - Неопределено - см. синтакс-помощник платформы.
|
||
//
|
||
Процедура ХранилищеОбщихНастроекУдалить(КлючОбъекта, КлючНастроек, ИмяПользователя) Экспорт
|
||
|
||
ХранилищеУдалить(ХранилищеОбщихНастроек,
|
||
КлючОбъекта,
|
||
КлючНастроек,
|
||
ИмяПользователя);
|
||
|
||
КонецПроцедуры
|
||
|
||
// Сохраняет настройку в хранилище системных настроек, как метод платформы Сохранить
|
||
// объекта СтандартноеХранилищеНастроекМенеджер, но с поддержкой длины ключа настроек
|
||
// более 128 символов путем хеширования части, которая превышает 96 символов.
|
||
// Если нет права СохранениеДанныхПользователя, сохранение пропускается без ошибки.
|
||
//
|
||
// Параметры:
|
||
// КлючОбъекта - Строка - см. синтакс-помощник платформы.
|
||
// КлючНастроек - Строка - см. синтакс-помощник платформы.
|
||
// Настройки - Произвольный - см. синтакс-помощник платформы.
|
||
// ОписаниеНастроек - ОписаниеНастроек - см. синтакс-помощник платформы.
|
||
// ИмяПользователя - Строка - см. синтакс-помощник платформы.
|
||
// ОбновитьПовторноИспользуемыеЗначения - Булево - выполнить одноименный метод платформы.
|
||
//
|
||
Процедура ХранилищеСистемныхНастроекСохранить(КлючОбъекта, КлючНастроек, Настройки,
|
||
ОписаниеНастроек = Неопределено,
|
||
ИмяПользователя = Неопределено,
|
||
ОбновитьПовторноИспользуемыеЗначения = Ложь) Экспорт
|
||
|
||
ХранилищеСохранить(ХранилищеСистемныхНастроек,
|
||
КлючОбъекта,
|
||
КлючНастроек,
|
||
Настройки,
|
||
ОписаниеНастроек,
|
||
ИмяПользователя,
|
||
ОбновитьПовторноИспользуемыеЗначения);
|
||
|
||
КонецПроцедуры
|
||
|
||
// Загружает настройку из хранилища системных настроек, как метод платформы Загрузить,
|
||
// объекта СтандартноеХранилищеНастроекМенеджер, но с поддержкой длины ключа настроек
|
||
// более 128 символов путем хеширования части, которая превышает 96 символов.
|
||
// Кроме того, возвращает указанное значение по умолчанию, если настройки не существуют.
|
||
// Если нет права СохранениеДанныхПользователя, возвращается значение по умолчанию без ошибки.
|
||
//
|
||
// В возвращаемом значении очищаются ссылки на несуществующий объект в базе данных, а именно:
|
||
// - возвращаемая ссылка заменяется на указанное значение по умолчанию;
|
||
// - из данных типа Массив ссылки удаляются;
|
||
// - у данных типа Структура и Соответствие ключ не меняется, а значение устанавливается Неопределено;
|
||
// - анализ значений в данных типа Массив, Структура, Соответствие выполняется рекурсивно.
|
||
//
|
||
// Параметры:
|
||
// КлючОбъекта - Строка - см. синтакс-помощник платформы.
|
||
// КлючНастроек - Строка - см. синтакс-помощник платформы.
|
||
// ЗначениеПоУмолчанию - Произвольный - значение, которое возвращается, если настройки не существуют.
|
||
// Если не указано, возвращается значение Неопределено.
|
||
// ОписаниеНастроек - ОписаниеНастроек - см. синтакс-помощник платформы.
|
||
// ИмяПользователя - Строка - см. синтакс-помощник платформы.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Произвольный - см. синтакс-помощник платформы.
|
||
//
|
||
Функция ХранилищеСистемныхНастроекЗагрузить(КлючОбъекта, КлючНастроек, ЗначениеПоУмолчанию = Неопределено,
|
||
ОписаниеНастроек = Неопределено, ИмяПользователя = Неопределено) Экспорт
|
||
|
||
Возврат ХранилищеЗагрузить(ХранилищеСистемныхНастроек,
|
||
КлючОбъекта,
|
||
КлючНастроек,
|
||
ЗначениеПоУмолчанию,
|
||
ОписаниеНастроек,
|
||
ИмяПользователя);
|
||
|
||
КонецФункции
|
||
|
||
// Удаляет настройку из хранилища системных настроек, как метод платформы Удалить,
|
||
// объекта СтандартноеХранилищеНастроекМенеджер, но с поддержкой длины ключа настроек
|
||
// более 128 символов путем хеширования части, которая превышает 96 символов.
|
||
// Если нет права СохранениеДанныхПользователя, удаление пропускается без ошибки.
|
||
//
|
||
// Параметры:
|
||
// КлючОбъекта - Строка
|
||
// - Неопределено - см. синтакс-помощник платформы.
|
||
// КлючНастроек - Строка
|
||
// - Неопределено - см. синтакс-помощник платформы.
|
||
// ИмяПользователя - Строка
|
||
// - Неопределено - см. синтакс-помощник платформы.
|
||
//
|
||
Процедура ХранилищеСистемныхНастроекУдалить(КлючОбъекта, КлючНастроек, ИмяПользователя) Экспорт
|
||
|
||
ХранилищеУдалить(ХранилищеСистемныхНастроек,
|
||
КлючОбъекта,
|
||
КлючНастроек,
|
||
ИмяПользователя);
|
||
|
||
КонецПроцедуры
|
||
|
||
// Сохраняет настройку в хранилище настроек данных форм, как метод платформы Сохранить,
|
||
// объектов СтандартноеХранилищеНастроекМенеджер или ХранилищеНастроекМенеджер.<Имя хранилища>,
|
||
// но с поддержкой длины ключа настроек более 128 символов путем хеширования части,
|
||
// которая превышает 96 символов.
|
||
// Если нет права СохранениеДанныхПользователя, сохранение пропускается без ошибки.
|
||
//
|
||
// Параметры:
|
||
// КлючОбъекта - Строка - см. синтакс-помощник платформы.
|
||
// КлючНастроек - Строка - см. синтакс-помощник платформы.
|
||
// Настройки - Произвольный - см. синтакс-помощник платформы.
|
||
// ОписаниеНастроек - ОписаниеНастроек - см. синтакс-помощник платформы.
|
||
// ИмяПользователя - Строка - см. синтакс-помощник платформы.
|
||
// ОбновитьПовторноИспользуемыеЗначения - Булево - выполнить одноименный метод платформы.
|
||
//
|
||
Процедура ХранилищеНастроекДанныхФормСохранить(КлючОбъекта, КлючНастроек, Настройки,
|
||
ОписаниеНастроек = Неопределено,
|
||
ИмяПользователя = Неопределено,
|
||
ОбновитьПовторноИспользуемыеЗначения = Ложь) Экспорт
|
||
|
||
ХранилищеСохранить(ХранилищеНастроекДанныхФорм,
|
||
КлючОбъекта,
|
||
КлючНастроек,
|
||
Настройки,
|
||
ОписаниеНастроек,
|
||
ИмяПользователя,
|
||
ОбновитьПовторноИспользуемыеЗначения);
|
||
|
||
КонецПроцедуры
|
||
|
||
// Загружает настройку из хранилища настроек данных форм, как метод платформы Загрузить,
|
||
// объектов СтандартноеХранилищеНастроекМенеджер или ХранилищеНастроекМенеджер.<Имя хранилища>,
|
||
// но с поддержкой длины ключа настроек более 128 символов путем хеширования части,
|
||
// которая превышает 96 символов.
|
||
// Кроме того, возвращает указанное значение по умолчанию, если настройки не существуют.
|
||
// Если нет права СохранениеДанныхПользователя, возвращается значение по умолчанию без ошибки.
|
||
//
|
||
// В возвращаемом значении очищаются ссылки на несуществующий объект в базе данных, а именно
|
||
// - возвращаемая ссылка заменяется на указанное значение по умолчанию;
|
||
// - из данных типа Массив ссылки удаляются;
|
||
// - у данных типа Структура и Соответствие ключ не меняется, а значение устанавливается Неопределено;
|
||
// - анализ значений в данных типа Массив, Структура, Соответствие выполняется рекурсивно.
|
||
//
|
||
// Параметры:
|
||
// КлючОбъекта - Строка - см. синтакс-помощник платформы.
|
||
// КлючНастроек - Строка - см. синтакс-помощник платформы.
|
||
// ЗначениеПоУмолчанию - Произвольный - значение, которое возвращается, если настройки не существуют.
|
||
// Если не указано, возвращается значение Неопределено.
|
||
// ОписаниеНастроек - ОписаниеНастроек - см. синтакс-помощник платформы.
|
||
// ИмяПользователя - Строка - см. синтакс-помощник платформы.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Произвольный - см. синтакс-помощник платформы.
|
||
//
|
||
Функция ХранилищеНастроекДанныхФормЗагрузить(КлючОбъекта, КлючНастроек, ЗначениеПоУмолчанию = Неопределено,
|
||
ОписаниеНастроек = Неопределено, ИмяПользователя = Неопределено) Экспорт
|
||
|
||
Возврат ХранилищеЗагрузить(ХранилищеНастроекДанныхФорм,
|
||
КлючОбъекта,
|
||
КлючНастроек,
|
||
ЗначениеПоУмолчанию,
|
||
ОписаниеНастроек,
|
||
ИмяПользователя);
|
||
|
||
КонецФункции
|
||
|
||
// Удаляет настройку из хранилища настроек данных форм, как метод платформы Удалить,
|
||
// объектов СтандартноеХранилищеНастроекМенеджер или ХранилищеНастроекМенеджер.<Имя хранилища>,
|
||
// но с поддержкой длины ключа настроек более 128 символов путем хеширования части,
|
||
// которая превышает 96 символов.
|
||
// Если нет права СохранениеДанныхПользователя, удаление пропускается без ошибки.
|
||
//
|
||
// Параметры:
|
||
// КлючОбъекта - Строка
|
||
// - Неопределено - см. синтакс-помощник платформы.
|
||
// КлючНастроек - Строка
|
||
// - Неопределено - см. синтакс-помощник платформы.
|
||
// ИмяПользователя - Строка
|
||
// - Неопределено - см. синтакс-помощник платформы.
|
||
//
|
||
Процедура ХранилищеНастроекДанныхФормУдалить(КлючОбъекта, КлючНастроек, ИмяПользователя) Экспорт
|
||
|
||
ХранилищеУдалить(ХранилищеНастроекДанныхФорм,
|
||
КлючОбъекта,
|
||
КлючНастроек,
|
||
ИмяПользователя);
|
||
|
||
КонецПроцедуры
|
||
|
||
#КонецОбласти
|
||
|
||
#Область СериализацияXML
|
||
|
||
// Преобразует (сериализует) любое значение в XML-строку.
|
||
// Преобразованы в могут быть только те объекты, для которых в синтакс-помощнике указано, что они сериализуются.
|
||
// См. также ЗначениеИзСтрокиXML.
|
||
//
|
||
// Параметры:
|
||
// Значение - Произвольный - значение, которое необходимо сериализовать в XML-строку.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - XML-строка.
|
||
//
|
||
Функция ЗначениеВСтрокуXML(Значение) Экспорт
|
||
|
||
ЗаписьXML = Новый ЗаписьXML;
|
||
ЗаписьXML.УстановитьСтроку();
|
||
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Значение, НазначениеТипаXML.Явное);
|
||
|
||
Возврат ЗаписьXML.Закрыть();
|
||
КонецФункции
|
||
|
||
// Выполняет преобразование (десериализацию) XML-строки в значение.
|
||
// См. также ЗначениеВСтрокуXML.
|
||
//
|
||
// Параметры:
|
||
// СтрокаXML - Строка - XML-строка, с сериализованным объектом..
|
||
//
|
||
// Возвращаемое значение:
|
||
// Произвольный - значение, полученное из переданной XML-строки.
|
||
//
|
||
Функция ЗначениеИзСтрокиXML(СтрокаXML) Экспорт
|
||
|
||
ЧтениеXML = Новый ЧтениеXML;
|
||
ЧтениеXML.УстановитьСтроку(СтрокаXML);
|
||
|
||
Возврат СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
|
||
КонецФункции
|
||
|
||
// Возвращает XML-представление XDTO-объекта.
|
||
//
|
||
// Параметры:
|
||
// ОбъектXDTO - ОбъектXDTO - объект, для которого требуется сформировать XML-представление.
|
||
// Фабрика - ФабрикаXDTO - фабрика, с использованием которой требуется формировать XML-представление.
|
||
// Если параметр не указан - будет использоваться глобальная фабрика XDTO.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - XML-представление XDTO-объекта.
|
||
//
|
||
Функция ОбъектXDTOВСтрокуXML(Знач ОбъектXDTO, Знач Фабрика = Неопределено) Экспорт
|
||
|
||
ОбъектXDTO.Проверить();
|
||
|
||
Если Фабрика = Неопределено Тогда
|
||
Фабрика = ФабрикаXDTO;
|
||
КонецЕсли;
|
||
|
||
Запись = Новый ЗаписьXML();
|
||
Запись.УстановитьСтроку();
|
||
Фабрика.ЗаписатьXML(Запись, ОбъектXDTO, , , , НазначениеТипаXML.Явное);
|
||
|
||
Возврат Запись.Закрыть();
|
||
|
||
КонецФункции
|
||
|
||
// Формирует XDTO-объект по XML-представлению.
|
||
//
|
||
// Параметры:
|
||
// СтрокаXML - Строка - XML-представление XDTO-объекта,
|
||
// Фабрика - ФабрикаXDTO - фабрика, с использованием которой требуется формировать XDTO-объект.
|
||
// Если параметр не указан - будет использоваться глобальная фабрика XDTO.
|
||
//
|
||
// Возвращаемое значение:
|
||
// ОбъектXDTO - XDTO-объект.
|
||
//
|
||
Функция ОбъектXDTOИзСтрокиXML(Знач СтрокаXML, Знач Фабрика = Неопределено) Экспорт
|
||
|
||
Если Фабрика = Неопределено Тогда
|
||
Фабрика = ФабрикаXDTO;
|
||
КонецЕсли;
|
||
|
||
Чтение = Новый ЧтениеXML();
|
||
Чтение.УстановитьСтроку(СтрокаXML);
|
||
|
||
Возврат Фабрика.ПрочитатьXML(Чтение);
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область СериализацияJSON
|
||
|
||
// Преобразует значение в строку JSON при помощи метода глобального контекста ЗаписатьJSON.
|
||
// Допускаются не все типы значений, подробности см. в синтакс-помощнике.
|
||
// Даты преобразуются в формат ISO (YYYY-MM-DDThh:mm:ssZ).
|
||
//
|
||
// Параметры:
|
||
// Значение - Произвольный
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка
|
||
//
|
||
Функция ЗначениеВJSON(Знач Значение) Экспорт
|
||
|
||
ЗаписьJSON = Новый ЗаписьJSON;
|
||
ЗаписьJSON.УстановитьСтроку();
|
||
ЗаписатьJSON(ЗаписьJSON, Значение);
|
||
|
||
Возврат ЗаписьJSON.Закрыть();
|
||
|
||
КонецФункции
|
||
|
||
// Преобразует строку в формате JSON в значение при помощи метода глобального контекста ПрочитатьJSON.
|
||
// См. ограничения в синтакс-помощнике.
|
||
// Объекты JSON по умолчанию преобразует в значения типа Соответствие.
|
||
// Имена свойств со значением типа Дата необходимо явно указывать, чтобы было выполнено преобразование.
|
||
// Ожидаемый формат дат - ISO (YYYY-MM-DDThh:mm:ssZ).
|
||
//
|
||
// Параметры:
|
||
// Строка - Строка - значение в формате JSON.
|
||
// ИменаСвойствСоЗначениямиДата - Строка - имя свойства, содержащее значение типа Дата. Допустимо указывать несколько
|
||
// свойств через запятую.
|
||
// - Массив из Строка
|
||
// ПрочитатьВСоответствие - Булево - если Ложь, то объекты JSON будут преобразованы в значение типа Структура.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Произвольный
|
||
//
|
||
Функция JSONВЗначение(Знач Строка, Знач ИменаСвойствСоЗначениямиДата = Неопределено, Знач ПрочитатьВСоответствие = Истина) Экспорт
|
||
|
||
Если ТипЗнч(ИменаСвойствСоЗначениямиДата) = Тип("Строка") Тогда
|
||
ИменаСвойствСоЗначениямиДата = СтрРазделить(ИменаСвойствСоЗначениямиДата, ", " + Символы.ПС, Ложь);
|
||
КонецЕсли;
|
||
|
||
ЧтениеJSON = Новый ЧтениеJSON;
|
||
ЧтениеJSON.УстановитьСтроку(Строка);
|
||
|
||
Возврат ПрочитатьJSON(ЧтениеJSON, ПрочитатьВСоответствие, ИменаСвойствСоЗначениямиДата);
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область ВебСервисы
|
||
|
||
// Возвращает структуру параметров для функции СоздатьWSПрокси.
|
||
//
|
||
// Возвращаемое значение:
|
||
// см. СоздатьWSПрокси.ПараметрыПодключенияWSПрокси
|
||
//
|
||
Функция ПараметрыПодключенияWSПрокси() Экспорт
|
||
Результат = Новый Структура;
|
||
Результат.Вставить("АдресWSDL");
|
||
Результат.Вставить("URIПространстваИмен");
|
||
Результат.Вставить("ИмяСервиса");
|
||
Результат.Вставить("ИмяТочкиПодключения", "");
|
||
Результат.Вставить("ИмяПользователя");
|
||
Результат.Вставить("Пароль");
|
||
Результат.Вставить("Таймаут", 0);
|
||
Результат.Вставить("Местоположение");
|
||
Результат.Вставить("ИспользоватьАутентификациюОС", Ложь);
|
||
Результат.Вставить("ДелатьКонтрольныйВызов", Ложь);
|
||
Результат.Вставить("ЗащищенноеСоединение", Неопределено);
|
||
Результат.Вставить("ПроверятьДоставкуПакетовПриОшибке", Истина);
|
||
Возврат Результат;
|
||
КонецФункции
|
||
|
||
// Конструктор объекта WSПрокси с дополнительными возможностями по сравнению с конструктором Новый WSПрокси:
|
||
// - создает WSОпределения;
|
||
// - кэширует файл WSDL для ускорения работы с веб-сервисом;
|
||
// - не требуется указание ИнтернетПрокси (используется автоматически, если настроен);
|
||
// - позволяет делать быструю проверку доступности сервиса с помощью операции Ping.
|
||
//
|
||
// Параметры:
|
||
// ПараметрыПодключенияWSПрокси - Структура:
|
||
// * АдресWSDL - Строка - месторасположение wsdl, например, "http://webservice.net/webservice.asmx?wsdl".
|
||
// * URIПространстваИмен - Строка - URI пространства имен web-сервиса, например, "http://www.webservice.net/WebService/1.0.0.1".
|
||
// * ИмяСервиса - Строка - имя сервиса, например, "WebService_1_0_0_1".
|
||
// * ИмяТочкиПодключения - Строка - необязательный параметр. Если не задано, образуется как "<ИмяСервиса>Soap".
|
||
// * ИмяПользователя - Строка - необязательный параметр. Имя пользователя для входа на сервер.
|
||
// * Пароль - Строка - необязательный параметр. Пароль пользователя.
|
||
// * Таймаут - Число - необязательный параметр. Таймаут на операции веб-сервиса, выполняемые
|
||
// через прокси. В секундах.
|
||
// * Местоположение - Строка - необязательный параметр. Фактический адрес сервиса. Используется, если
|
||
// адрес реального расположения сервиса отличается от адреса, который указан
|
||
// в WSDL-файле.
|
||
// * ИспользоватьАутентификациюОС - Булево - необязательный параметр. Включает использование авторизации NTLM или
|
||
// Negotiate на сервере.
|
||
// * ДелатьКонтрольныйВызов - Булево - необязательный параметр. Выполнять проверку доступности сервиса (требуется
|
||
// поддержка команды Ping в веб-сервисе). По умолчанию, Ложь.
|
||
// * ЗащищенноеСоединение - ЗащищенноеСоединениеOpenSSL
|
||
// - Неопределено - необязательные параметры защищенного соединения.
|
||
// * ПроверятьДоставкуПакетовПриОшибке - см. ПолучениеФайловИзИнтернета.ДиагностикаСоединения.ПроверятьДоставкуПакетов.
|
||
//
|
||
// Возвращаемое значение:
|
||
// WSПрокси
|
||
//
|
||
// Пример:
|
||
// ПараметрыПодключения = ОбщегоНазначения.ПараметрыПодключенияWSПрокси();
|
||
// ПараметрыПодключения.АдресWSDL = "http://webservice.net/webservice.asmx?wsdl";
|
||
// ПараметрыПодключения.URIПространстваИмен = "http://www.webservice.net/WebService/1.0.0.1";
|
||
// ПараметрыПодключения.ИмяСервиса = "WebService_1_0_0_1";
|
||
// ПараметрыПодключения.Таймаут = 20;
|
||
// Прокси = ОбщегоНазначения.СоздатьWSПрокси(ПараметрыПодключения);
|
||
//
|
||
Функция СоздатьWSПрокси(Знач ПараметрыПодключенияWSПрокси) Экспорт
|
||
|
||
ОбщегоНазначенияКлиентСервер.ПроверитьПараметр("СоздатьWSПрокси", "Параметры", ПараметрыПодключенияWSПрокси, Тип("Структура"),
|
||
Новый Структура("АдресWSDL,URIПространстваИмен,ИмяСервиса", Тип("Строка"), Тип("Строка"), Тип("Строка")));
|
||
|
||
ПараметрыПодключения = ПараметрыПодключенияWSПрокси();
|
||
ЗаполнитьЗначенияСвойств(ПараметрыПодключения, ПараметрыПодключенияWSПрокси);
|
||
|
||
ДелатьКонтрольныйВызов = ПараметрыПодключения.ДелатьКонтрольныйВызов;
|
||
Таймаут = ПараметрыПодключения.Таймаут;
|
||
|
||
Если ДелатьКонтрольныйВызов И Таймаут <> Неопределено И Таймаут > 20 Тогда
|
||
ПараметрыПодключения.Таймаут = 7;
|
||
WSПроксиPing = РегистрыСведений.КэшПрограммныхИнтерфейсов.ВнутренняяWSПрокси(ПараметрыПодключения);
|
||
Попытка
|
||
WSПроксиPing.Ping();
|
||
Исключение
|
||
АдресТочкиПодключения = WSПроксиPing.ТочкаПодключения.Местоположение;
|
||
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Не удалось проверить доступность web-сервиса
|
||
|%1
|
||
|по причине:
|
||
|%2'"),
|
||
ПараметрыПодключения.АдресWSDL,
|
||
ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.ПолучениеФайловИзИнтернета") Тогда
|
||
МодульПолучениеФайловИзИнтернета = ОбщийМодуль("ПолучениеФайловИзИнтернета");
|
||
РезультатДиагностики = МодульПолучениеФайловИзИнтернета.ДиагностикаСоединения(АдресТочкиПодключения,,
|
||
ПараметрыПодключения.ПроверятьДоставкуПакетовПриОшибке);
|
||
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = '%1
|
||
|Результат диагностики:
|
||
|%2'"),
|
||
ТекстОшибки,
|
||
РезультатДиагностики.ОписаниеОшибки);
|
||
КонецЕсли;
|
||
|
||
ВызватьИсключение(ТекстОшибки, КатегорияОшибки.ОшибкаСети);
|
||
КонецПопытки;
|
||
ПараметрыПодключения.Таймаут = Таймаут;
|
||
КонецЕсли;
|
||
|
||
Возврат РегистрыСведений.КэшПрограммныхИнтерфейсов.ВнутренняяWSПрокси(ПараметрыПодключения);
|
||
|
||
КонецФункции
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////
|
||
// Версионирование программных интерфейсов.
|
||
|
||
// Возвращает номера версий программных интерфейсов удаленной системы, доступной через веб-сервис.
|
||
// Позволяет обеспечивать полную обратную совместимость при изменениях в программных интерфейсах
|
||
// с помощью их явного версионирования. Например, если программный интерфейс выше определенной версии,
|
||
// то только в этом случае допустимо вызывать у него новую функцию.
|
||
//
|
||
// В целях экономии трафика при интенсивном взаимодействии между вызывающей и вызываемой сторонами
|
||
// сведения о версиях кэшируются на одни сутки. Если для целей отладки требуется сбросить кэш раньше этого времени,
|
||
// следует удалить соответствующие записи из регистра сведений КэшПрограммныхИнтерфейсов.
|
||
//
|
||
// Параметры:
|
||
// Адрес - Строка - адрес веб-сервиса версионирования интерфейсов InterfaceVersion;
|
||
// Пользователь - Строка - имя пользователя веб-сервиса;
|
||
// Пароль - Строка - пароль пользователя веб-сервиса;
|
||
// Интерфейс - Строка - имя запрашиваемого программного интерфейса, например, "СервисПередачиФайлов";
|
||
// ПроверятьДоставкуПакетовПриОшибке - см. ПолучениеФайловИзИнтернета.ДиагностикаСоединения.ПроверятьДоставкуПакетов
|
||
//
|
||
// Возвращаемое значение:
|
||
// ФиксированныйМассив - массив строк, каждая строка является представлением номера версии интерфейса.
|
||
// Например, "1.0.2.1".
|
||
//
|
||
// Пример:
|
||
// Версии = ПолучитьВерсииИнтерфейса("http://vsrvx/sm", "ivanov",, "СервисПередачиФайлов");
|
||
//
|
||
// Также для обратной совместимости поддерживается устаревший вариант вызова:
|
||
// ПараметрыПодключения = Новый Структура;
|
||
// ПараметрыПодключения.Вставить("URL", "http://vsrvx/sm");
|
||
// ПараметрыПодключения.Вставить("UserName", "ivanov");
|
||
// ПараметрыПодключения.Вставить("Password", "");
|
||
// Версии = ПолучитьВерсииИнтерфейса(ПараметрыПодключения, "СервисПередачиФайлов");
|
||
//
|
||
Функция ПолучитьВерсииИнтерфейса(Знач Адрес, Знач Пользователь, Знач Пароль = Неопределено,
|
||
Знач Интерфейс = Неопределено, Знач ПроверятьДоставкуПакетовПриОшибке = Истина) Экспорт
|
||
|
||
Если ТипЗнч(Адрес) = Тип("Структура") Тогда // для обратной совместимости
|
||
ПараметрыПодключения = Адрес;
|
||
ИмяИнтерфейса = Пользователь;
|
||
Иначе
|
||
ПараметрыПодключения = Новый Структура;
|
||
ПараметрыПодключения.Вставить("URL", Адрес);
|
||
ПараметрыПодключения.Вставить("UserName", Пользователь);
|
||
ПараметрыПодключения.Вставить("Password", Пароль);
|
||
ИмяИнтерфейса = Интерфейс;
|
||
КонецЕсли;
|
||
|
||
ПараметрыПодключения.Вставить("ПроверятьДоставкуПакетовПриОшибке", ПроверятьДоставкуПакетовПриОшибке);
|
||
|
||
Если Не ПараметрыПодключения.Свойство("URL")
|
||
Или Не ЗначениеЗаполнено(ПараметрыПодключения.URL) Тогда
|
||
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверное значение параметра %1 функции %2. Не задан URL сервиса.'"),
|
||
"ПараметрыПодключения", "ОбщегоНазначения.ПолучитьВерсииИнтерфейса"), КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
ПараметрыПолучения = Новый Массив;
|
||
ПараметрыПолучения.Добавить(ПараметрыПодключения);
|
||
ПараметрыПолучения.Добавить(ИмяИнтерфейса);
|
||
|
||
Возврат РегистрыСведений.КэшПрограммныхИнтерфейсов.ДанныеКэшаВерсий(
|
||
РегистрыСведений.КэшПрограммныхИнтерфейсов.ИдентификаторЗаписиКэшаВерсий(ПараметрыПодключения.URL, ИмяИнтерфейса),
|
||
Перечисления.ТипыДанныхКэшаПрограммныхИнтерфейсов.ВерсииИнтерфейса,
|
||
ПараметрыПолучения,
|
||
Истина);
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает номера версий программных интерфейсов удаленной системы, подключенной через внешнее соединение.
|
||
// Позволяет обеспечивать полную обратную совместимость при изменениях в программных интерфейсах
|
||
// с помощью их явного версионирования. Например, если программный интерфейс выше определенной версии,
|
||
// то только в этом случае допустимо вызывать у него новую функцию.
|
||
//
|
||
// Параметры:
|
||
// ВнешнееСоединение - COMОбъект - внешнее соединение, которое используется для работы с удаленной системой.
|
||
// ИмяИнтерфейса - Строка - имя запрашиваемого программного интерфейса, например "СервисПередачиФайлов".
|
||
//
|
||
// Возвращаемое значение:
|
||
// ФиксированныйМассив - массив строк, каждая строка является представлением номера версии интерфейса.
|
||
// Например "1.0.2.1".
|
||
//
|
||
// Пример:
|
||
// Версии = ОбщегоНазначения.ПолучитьВерсииИнтерфейсаЧерезВнешнееСоединение(ВнешнееСоединение, "СервисПередачиФайлов");
|
||
//
|
||
Функция ПолучитьВерсииИнтерфейсаЧерезВнешнееСоединение(ВнешнееСоединение, Знач ИмяИнтерфейса) Экспорт
|
||
Попытка
|
||
ВерсииИнтерфейсаXML = ВнешнееСоединение.СтандартныеПодсистемыСервер.ПоддерживаемыеВерсии(ИмяИнтерфейса);
|
||
Исключение
|
||
СтрокаСообщения = НСтр("ru = 'Корреспондент не поддерживает версионирование программных интерфейсов.
|
||
|Описание ошибки: %1'");
|
||
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
|
||
ЗаписьЖурналаРегистрации(НСтр("ru = 'Получение версий интерфейса'", КодОсновногоЯзыка()),
|
||
УровеньЖурналаРегистрации.Ошибка, , , СтрокаСообщения);
|
||
|
||
Возврат Новый ФиксированныйМассив(Новый Массив);
|
||
КонецПопытки;
|
||
|
||
Возврат Новый ФиксированныйМассив(ЗначениеИзСтрокиXML(ВерсииИнтерфейсаXML));
|
||
КонецФункции
|
||
|
||
// Удаляет записи кэша версий программных интерфейсов, содержащих в идентификаторе указанную подстроку.
|
||
// В качестве подстроки может использоваться, например, имя интерфейса, более не используемого в конфигурации.
|
||
//
|
||
// Параметры:
|
||
// ПодстрокаПоискаИдентификаторов - Строка - подстрока поиска идентификаторов.
|
||
// Не может содержать символов %, _ и [.
|
||
//
|
||
Процедура УдалитьЗаписиКэшаВерсий(Знач ПодстрокаПоискаИдентификаторов) Экспорт
|
||
|
||
НачатьТранзакцию();
|
||
Попытка
|
||
|
||
Блокировка = Новый БлокировкаДанных;
|
||
Блокировка.Добавить("РегистрСведений.КэшПрограммныхИнтерфейсов");
|
||
Блокировка.Заблокировать();
|
||
|
||
ТекстЗапроса =
|
||
"ВЫБРАТЬ
|
||
| ТаблицаКэша.Идентификатор КАК Идентификатор,
|
||
| ТаблицаКэша.ТипДанных КАК ТипДанных
|
||
|ИЗ
|
||
| РегистрСведений.КэшПрограммныхИнтерфейсов КАК ТаблицаКэша
|
||
|ГДЕ
|
||
| ТаблицаКэша.Идентификатор ПОДОБНО ""%ПодстрокаПоиска%"" СПЕЦСИМВОЛ ""~""";
|
||
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПодстрокаПоиска",
|
||
СформироватьСтрокуДляПоискаВЗапросе(ПодстрокаПоискаИдентификаторов));
|
||
Запрос = Новый Запрос(ТекстЗапроса);
|
||
Результат = Запрос.Выполнить();
|
||
Выборка = Результат.Выбрать();
|
||
Пока Выборка.Следующий() Цикл
|
||
Запись = РегистрыСведений.КэшПрограммныхИнтерфейсов.СоздатьМенеджерЗаписи();
|
||
Запись.Идентификатор = Выборка.Идентификатор;
|
||
Запись.ТипДанных = Выборка.ТипДанных;
|
||
Запись.Удалить();
|
||
КонецЦикла;
|
||
|
||
ЗафиксироватьТранзакцию();
|
||
Исключение
|
||
ОтменитьТранзакцию();
|
||
ВызватьИсключение;
|
||
КонецПопытки;
|
||
|
||
КонецПроцедуры
|
||
|
||
#КонецОбласти
|
||
|
||
#Область БезопасноеХранилище
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
// Процедуры и функции для работы с хранилищем паролей.
|
||
|
||
// Записывает конфиденциальные данные в безопасное хранилище.
|
||
// Вызывающий код должен самостоятельно устанавливать привилегированный режим.
|
||
//
|
||
// Безопасное хранилище недоступно для чтения пользователям (кроме администраторов),
|
||
// а доступно только коду, который делает обращения только к своей части данных и
|
||
// в том контексте, который предполагает чтение или запись конфиденциальных данных.
|
||
//
|
||
// Параметры:
|
||
// Владелец - ПланОбменаСсылка
|
||
// - СправочникСсылка
|
||
// - Строка - ссылка на объект информационной базы,
|
||
// представляющий объект-владелец сохраняемого пароля или строка до 128 символов.
|
||
// Для объектов других типов в качестве владельца рекомендуется использовать ссылку на
|
||
// элемент метаданных этого типа в справочнике ИдентификаторыОбъектовМетаданных
|
||
// или ключ в виде строки с учетом имен подсистем.
|
||
// Например, для БСП:
|
||
// Владелец = ОбщегоНазначения.ИдентификаторОбъектаМетаданных("РегистрСведений.АдресныеОбъекты");
|
||
// если нужно 1 хранилище на подсистему БСП:
|
||
// Владелец = "СтандартныеПодсистемы.УправлениеДоступом";
|
||
// если нужно более 1 хранилища на подсистему БСП:
|
||
// Владелец = "СтандартныеПодсистемы.УправлениеДоступом.<Уточнение>";
|
||
// Данные - Произвольный - данные помещаемые в безопасное хранилище. Неопределенно - удаляет все данные.
|
||
// Для удаления данных по ключу следует использовать процедуру УдалитьДанныеИзБезопасногоХранилища.
|
||
// - Структура - если параметр Ключ содержит Неопределено. Подробнее см. описание параметра Ключ
|
||
// Ключ - Строка - ключ сохраняемых настроек, по умолчанию "Пароль".
|
||
// Ключ должен соответствовать правилам имен идентификаторов:
|
||
// 1. Первым символом ключа должна быть буква или символ подчеркивания (_).
|
||
// 2. Каждый из последующих символов может быть буквой, цифрой или символом подчеркивания (_).
|
||
// Неопределено - для добавления набора данных структурой, где ключ структуры - это имя ключа данных,
|
||
// а значение - сохраняемые данные. Пример использования см. ниже.
|
||
//
|
||
// Пример:
|
||
//
|
||
// Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
|
||
// Если ТекущийПользовательМожетИзменятьПароль Тогда
|
||
// УстановитьПривилегированныйРежим(Истина);
|
||
// ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ТекущийОбъект.Ссылка, Логин, "Логин");
|
||
// ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ТекущийОбъект.Ссылка, Пароль);
|
||
// УстановитьПривилегированныйРежим(Ложь);
|
||
// КонецЕсли;
|
||
// КонецПроцедуры
|
||
//
|
||
// Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
|
||
// Если ТекущийПользовательМожетИзменятьПароль Тогда
|
||
// ЛогинИПароль = Новый Структура;
|
||
// ЛогинИПароль.Вставить("Логин", Логин);
|
||
// ЛогинИПароль.Вставить("Пароль", Пароль);
|
||
// УстановитьПривилегированныйРежим(Истина);
|
||
// ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(ТекущийОбъект.Ссылка, ЛогинИПароль, Неопределено);
|
||
// УстановитьПривилегированныйРежим(Ложь);
|
||
// КонецЕсли;
|
||
// КонецПроцедуры
|
||
//
|
||
Процедура ЗаписатьДанныеВБезопасноеХранилище(Владелец, Данные, Ключ = "Пароль") Экспорт
|
||
|
||
ОбщегоНазначенияКлиентСервер.Проверить(ЗначениеЗаполнено(Владелец),
|
||
СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Недопустимое значение параметра %1 в %2.
|
||
|параметр должен содержать ссылку; передано значение: %3 (тип %4).'"),
|
||
"Владелец", "ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище", Владелец, ТипЗнч(Владелец)));
|
||
|
||
Если ЗначениеЗаполнено(Ключ) Тогда
|
||
|
||
ОбщегоНазначенияКлиентСервер.Проверить(ТипЗнч(Ключ) = Тип("Строка"),
|
||
СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Недопустимое значение параметра %1 в %2.
|
||
|параметр должен содержать строку; передано значение: %3 (тип %4).'"),
|
||
"Ключ", "ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище", Ключ, ТипЗнч(Ключ)));
|
||
|
||
Иначе
|
||
|
||
ОбщегоНазначенияКлиентСервер.Проверить(ТипЗнч(Данные) = Тип("Структура"),
|
||
СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Недопустимое значение параметра %1 в %2.
|
||
|Если Ключ = Неопределено, то параметр должен содержать структуру; передано значение: %3 (тип %4).'"),
|
||
"Данные", "ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище", Данные, ТипЗнч(Данные)));
|
||
|
||
КонецЕсли;
|
||
|
||
ЭтоОбластьДанных = РазделениеВключено() И ДоступноИспользованиеРазделенныхДанных();
|
||
Если ЭтоОбластьДанных Тогда
|
||
БезопасноеХранилищеДанных = РегистрыСведений.БезопасноеХранилищеДанныхОбластейДанных.СоздатьМенеджерЗаписи();
|
||
Иначе
|
||
БезопасноеХранилищеДанных = РегистрыСведений.БезопасноеХранилищеДанных.СоздатьМенеджерЗаписи();
|
||
КонецЕсли;
|
||
|
||
БезопасноеХранилищеДанных.Владелец = Владелец;
|
||
БезопасноеХранилищеДанных.Прочитать();
|
||
|
||
Если Данные <> Неопределено Тогда
|
||
|
||
Если БезопасноеХранилищеДанных.Выбран() Тогда
|
||
|
||
ДанныеДляСохранения = БезопасноеХранилищеДанных.Данные.Получить();
|
||
|
||
Если ТипЗнч(ДанныеДляСохранения) <> Тип("Структура") Тогда
|
||
ДанныеДляСохранения = Новый Структура();
|
||
КонецЕсли;
|
||
|
||
Если ЗначениеЗаполнено(Ключ) Тогда
|
||
ДанныеДляСохранения.Вставить(Ключ, Данные);
|
||
Иначе
|
||
ОбщегоНазначенияКлиентСервер.ДополнитьСтруктуру(ДанныеДляСохранения, Данные, Истина);
|
||
КонецЕсли;
|
||
|
||
ДанныеДляХранилищеЗначения = Новый ХранилищеЗначения(ДанныеДляСохранения, Новый СжатиеДанных(6));
|
||
БезопасноеХранилищеДанных.Данные = ДанныеДляХранилищеЗначения;
|
||
БезопасноеХранилищеДанных.Записать();
|
||
|
||
Иначе
|
||
|
||
ДанныеДляСохранения = ?(ЗначениеЗаполнено(Ключ), Новый Структура(Ключ, Данные), Данные);
|
||
ДанныеДляХранилищеЗначения = Новый ХранилищеЗначения(ДанныеДляСохранения, Новый СжатиеДанных(6));
|
||
|
||
БезопасноеХранилищеДанных.Данные = ДанныеДляХранилищеЗначения;
|
||
БезопасноеХранилищеДанных.Владелец = Владелец;
|
||
БезопасноеХранилищеДанных.Записать();
|
||
|
||
КонецЕсли;
|
||
Иначе
|
||
|
||
БезопасноеХранилищеДанных.Удалить();
|
||
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Возвращает данные из безопасного хранилища.
|
||
// Вызывающий код должен самостоятельно устанавливать привилегированный режим.
|
||
//
|
||
// Безопасное хранилище недоступно для чтения пользователям (кроме администраторов),
|
||
// а доступно только коду, который делает обращения только к своей части данных и
|
||
// в том контексте, который предполагает чтение или запись конфиденциальных данных.
|
||
//
|
||
// Параметры:
|
||
// Владельцы - Массив из ПланОбменаСсылка
|
||
// - Массив из СправочникСсылка
|
||
// - Массив из Строка - ссылки на объекты информационной базы,
|
||
// представляющих объекты-владельцы или уникальные строки(до 128 символов) владельцев данных.
|
||
// Ключи - Строка - содержит имя ключа данных или список имен ключей, указанных через запятую.
|
||
// - Неопределено - будут возвращены все сохраненные данные переданных владельцев.
|
||
// ОбщиеДанные - Булево - Истина, если требуется в модели сервиса получить данные из общих данных в разделенном режиме.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Соответствие из КлючИЗначение:
|
||
// * Ключ - ПланОбменаСсылка
|
||
// - СправочникСсылка
|
||
// - Строка - ссылка на объект информационной базы
|
||
// или строка до 128 символов идентифицирующая владельца данных.
|
||
// * Значение - Произвольный - если в параметре Ключи указан один ключ,
|
||
// то возвращается его значение произвольного типа.
|
||
// - Структура - если в параметре Ключи указано несколько ключей или Неопределено,
|
||
// где ключ структуры - это имя ключа сохраненных данных,
|
||
// а значение - данные произвольного типа. Когда для ключа отсутствуют данные,
|
||
// то значение содержит Неопределено.
|
||
// - Неопределено - если данные по ключу отсутствуют.
|
||
//
|
||
// Пример:
|
||
// Процедура РассылкаПриглашений(Пользователи)
|
||
//
|
||
// УстановитьПривилегированныйРежим(Истина);
|
||
// ДанныеАвторизации = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(Пользователи, "Логин, Пароль");
|
||
// УстановитьПривилегированныйРежим(Ложь);
|
||
//
|
||
// Для каждого Пользователь Из Пользователи Цикл
|
||
// ОтправитьПриглашение(Пользователь, ДанныеАвторизации[Пользователь]);
|
||
// КонецЦикла;
|
||
//
|
||
// КонецПроцедуры
|
||
//
|
||
Функция ПрочитатьДанныеВладельцевИзБезопасногоХранилища(Владельцы, Ключи = "Пароль", ОбщиеДанные = Неопределено) Экспорт
|
||
|
||
ОбщегоНазначенияКлиентСервер.Проверить(ТипЗнч(Владельцы) = Тип("Массив"),
|
||
СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Недопустимое значение параметра %1 в %2.
|
||
|параметр должен содержать массив; передано значение: %3 (тип %4).'"),
|
||
"Владельцы", "ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища", Владельцы, ТипЗнч(Владельцы)));
|
||
|
||
Результат = ДанныеИзБезопасногоХранилища(Владельцы, Ключи, ОбщиеДанные);
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает данные из безопасного хранилища.
|
||
// Вызывающий код должен самостоятельно устанавливать привилегированный режим.
|
||
//
|
||
// Безопасное хранилище недоступно для чтения пользователям (кроме администраторов),
|
||
// а доступно только коду, который делает обращения только к своей части данных и
|
||
// в том контексте, который предполагает чтение или запись конфиденциальных данных.
|
||
//
|
||
// Параметры:
|
||
// Владелец - ПланОбменаСсылка
|
||
// - СправочникСсылка
|
||
// - Строка - ссылка на объект информационной базы,
|
||
// представляющий объект-владелец сохраняемого пароля или уникальная строка(до 128 символов).
|
||
// Ключи - Строка - содержит список имен сохраненных данных, указанных через запятую.
|
||
// - Неопределено - будут возвращены все сохраненные данные владельца.
|
||
// ОбщиеДанные - Булево - Истина, если требуется в модели сервиса получить данные из общих данных в разделенном режиме.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Произвольный, Структура, Неопределено - данные из безопасного хранилища. Если указан один ключ,
|
||
// то возвращается его значение, иначе структура.
|
||
// Если данные отсутствуют - Неопределенно.
|
||
//
|
||
// Пример:
|
||
// Если ТекущийПользовательМожетИзменятьПароль Тогда
|
||
// УстановитьПривилегированныйРежим(Истина);
|
||
// Логин = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(ТекущийОбъект.Ссылка, "Логин");
|
||
// Пароль = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(ТекущийОбъект.Ссылка);
|
||
// УстановитьПривилегированныйРежим(Ложь);
|
||
// Иначе
|
||
// Элементы.ГруппаЛогинИПароль.Видимость = Ложь;
|
||
// КонецЕсли;
|
||
//
|
||
// УстановитьПривилегированныйРежим(Истина);
|
||
// ЛогинИПароль = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(ТекущийОбъект.Ссылка, Неопределено);
|
||
//
|
||
Функция ПрочитатьДанныеИзБезопасногоХранилища(Владелец, Ключи = "Пароль", ОбщиеДанные = Неопределено) Экспорт
|
||
|
||
Владельцы = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Владелец);
|
||
ДанныеВладельца = ПрочитатьДанныеВладельцевИзБезопасногоХранилища(Владельцы, Ключи, ОбщиеДанные);
|
||
|
||
Результат = ДанныеВладельца[Владелец];
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Удаляет конфиденциальные данные в безопасное хранилище.
|
||
// Вызывающий код должен самостоятельно устанавливать привилегированный режим.
|
||
//
|
||
// Безопасное хранилище недоступно для чтения пользователям (кроме администраторов),
|
||
// а доступно только коду, который делает обращения только к своей части данных и
|
||
// в том контексте, который предполагает чтение или запись конфиденциальных данных.
|
||
//
|
||
// Параметры:
|
||
// Владелец - ПланОбменаСсылка
|
||
// - СправочникСсылка
|
||
// - Строка - ссылка на объект информационной базы,
|
||
// представляющий объект-владелец сохраняемого пароля или уникальная строка(до 128 символов).
|
||
// - Массив - ссылки на объекты информационной базы для удаления данным по нескольким владельцам.
|
||
// Ключи - Строка - содержит список имен удаляемых данных, указанных через запятую.
|
||
// Неопределено - удаляет все данные.
|
||
//
|
||
// Пример:
|
||
// Процедура ПередУдалением(Отказ)
|
||
//
|
||
// // Проверка значения свойства ОбменДанными.Загрузка отсутствует, так как удалять данные
|
||
// // из безопасного хранилища нужно даже при удалении объекта при обмене данными.
|
||
//
|
||
// УстановитьПривилегированныйРежим(Истина);
|
||
// ОбщегоНазначения.УдалитьДанныеИзБезопасногоХранилища(Ссылка);
|
||
// УстановитьПривилегированныйРежим(Ложь);
|
||
//
|
||
// КонецПроцедуры
|
||
//
|
||
Процедура УдалитьДанныеИзБезопасногоХранилища(Владелец, Ключи = Неопределено) Экспорт
|
||
|
||
ОбщегоНазначенияКлиентСервер.Проверить(ЗначениеЗаполнено(Владелец),
|
||
СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Недопустимое значение параметра %1 в %2.
|
||
|параметр должен содержать ссылку; передано значение: %3 (тип %4).'"),
|
||
"Владелец", "ОбщегоНазначения.УдалитьДанныеИзБезопасногоХранилища", Владелец, ТипЗнч(Владелец)));
|
||
|
||
Если РазделениеВключено() И ДоступноИспользованиеРазделенныхДанных() Тогда
|
||
БезопасноеХранилищеДанных = РегистрыСведений.БезопасноеХранилищеДанныхОбластейДанных.СоздатьМенеджерЗаписи();
|
||
Иначе
|
||
БезопасноеХранилищеДанных = РегистрыСведений.БезопасноеХранилищеДанных.СоздатьМенеджерЗаписи();
|
||
КонецЕсли;
|
||
|
||
Владельцы = ?(ТипЗнч(Владелец) = Тип("Массив"), Владелец, ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Владелец));
|
||
|
||
Для Каждого ВладелецДанных Из Владельцы Цикл
|
||
|
||
БезопасноеХранилищеДанных.Владелец = ВладелецДанных;
|
||
БезопасноеХранилищеДанных.Прочитать();
|
||
Если ТипЗнч(БезопасноеХранилищеДанных.Данные) = Тип("ХранилищеЗначения") Тогда
|
||
ДанныеДляСохранения = БезопасноеХранилищеДанных.Данные.Получить();
|
||
Если Ключи <> Неопределено И ТипЗнч(ДанныеДляСохранения) = Тип("Структура") Тогда
|
||
СписокКлючей = СтрРазделить(Ключи, ",", Ложь);
|
||
Если БезопасноеХранилищеДанных.Выбран() И СписокКлючей.Количество() > 0 Тогда
|
||
Для каждого КлючДляУдаления Из СписокКлючей Цикл
|
||
Если ДанныеДляСохранения.Свойство(КлючДляУдаления) Тогда
|
||
ДанныеДляСохранения.Удалить(КлючДляУдаления);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
ДанныеДляХранилищеЗначения = Новый ХранилищеЗначения(ДанныеДляСохранения, Новый СжатиеДанных(6));
|
||
БезопасноеХранилищеДанных.Данные = ДанныеДляХранилищеЗначения;
|
||
БезопасноеХранилищеДанных.Записать();
|
||
Возврат;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
БезопасноеХранилищеДанных.Удалить();
|
||
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
#КонецОбласти
|
||
|
||
#Область БуферОбмена
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
// Процедуры и функции для работы с внутренним буфером обмена.
|
||
|
||
// Помещает выделенные строки табличной части во внутренний буфер обмена
|
||
// откуда их можно получить с помощью СтрокиИзБуфераОбмена.
|
||
//
|
||
// Параметры:
|
||
// ТабличнаяЧасть - ДанныеФормыКоллекция - табличная часть, строки которой
|
||
// необходимо поместить во внутренний буфер обмена.
|
||
// ВыделенныеСтроки - Массив - массив идентификаторов выделенных строк.
|
||
// Источник - Строка - произвольный строковый идентификатор, например, имя объекта,
|
||
// строки табличной части которого помещаются во внутренний буфер обмена.
|
||
//
|
||
Процедура СкопироватьСтрокиВБуферОбмена(ТабличнаяЧасть, ВыделенныеСтроки, Источник = Неопределено) Экспорт
|
||
|
||
Если ВыделенныеСтроки = Неопределено Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
ТаблицаЗначений = ТабличнаяЧасть.Выгрузить();
|
||
ТаблицаЗначений.Очистить();
|
||
|
||
УдаляемыеКолонки = Новый Массив;
|
||
УдаляемыеКолонки.Добавить("ИсходныйНомерСтроки");
|
||
УдаляемыеКолонки.Добавить("НомерСтроки");
|
||
|
||
Для Каждого ИмяКолонки Из УдаляемыеКолонки Цикл
|
||
Колонка = ТаблицаЗначений.Колонки.Найти(ИмяКолонки);
|
||
Если Колонка = Неопределено Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
|
||
ТаблицаЗначений.Колонки.Удалить(Колонка);
|
||
КонецЦикла;
|
||
|
||
Для Каждого ИдентификаторСтроки Из ВыделенныеСтроки Цикл
|
||
КопируемаяСтрока = ТабличнаяЧасть.НайтиПоИдентификатору(ИдентификаторСтроки);
|
||
ЗаполнитьЗначенияСвойств(ТаблицаЗначений.Добавить(), КопируемаяСтрока);
|
||
КонецЦикла;
|
||
|
||
СкопироватьВБуферОбмена(ТаблицаЗначений, Источник);
|
||
|
||
КонецПроцедуры
|
||
|
||
// Помещает произвольные данные во внутренний буфер обмена, откуда их можно получить с помощью СтрокиИзБуфераОбмена.
|
||
//
|
||
// Параметры:
|
||
// Данные - Произвольный - данные, которые необходимо поместить в внутренний буфер обмена.
|
||
// Источник - Строка - произвольный строковый идентификатор, например, имя объекта,
|
||
// строки табличной части которого помещаются во внутренний буфер обмена.
|
||
//
|
||
Процедура СкопироватьВБуферОбмена(Данные, Источник = Неопределено) Экспорт
|
||
|
||
ТекущийБуферОбмена = ПараметрыСеанса.БуферОбмена;
|
||
|
||
Если ЗначениеЗаполнено(ТекущийБуферОбмена.Данные) Тогда
|
||
Адрес = ТекущийБуферОбмена.Данные;
|
||
Иначе
|
||
Адрес = Новый УникальныйИдентификатор;
|
||
КонецЕсли;
|
||
|
||
ДанныеВХранилище = ПоместитьВоВременноеХранилище(Данные, Адрес);
|
||
|
||
СтруктураБуфераОбмена = Новый Структура;
|
||
СтруктураБуфераОбмена.Вставить("Источник", Источник);
|
||
СтруктураБуфераОбмена.Вставить("Данные", ДанныеВХранилище);
|
||
|
||
ПараметрыСеанса.БуферОбмена = Новый ФиксированнаяСтруктура(СтруктураБуфераОбмена);
|
||
|
||
КонецПроцедуры
|
||
|
||
// Получает строки табличной части, помещенные во внутренний буфер обмена с помощью СкопироватьСтрокиВБуферОбмена.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Структура:
|
||
// * Данные - Произвольный - данные из внутреннего буфера обмена.
|
||
// Например, ТаблицаЗначений при вызове СкопироватьСтрокиВБуферОбмена.
|
||
// * Источник - Строка - объект, к которому относятся данные.
|
||
// Если при помещении во внутренний буфер не был указан, то Неопределено.
|
||
//
|
||
Функция СтрокиИзБуфераОбмена() Экспорт
|
||
|
||
Результат = Новый Структура;
|
||
Результат.Вставить("Источник", Неопределено);
|
||
Результат.Вставить("Данные", Неопределено);
|
||
|
||
Если ПустойБуферОбмена() Тогда
|
||
Возврат Результат;
|
||
КонецЕсли;
|
||
|
||
ТекущийБуферОбмена = ПараметрыСеанса.БуферОбмена; // см. СтрокиИзБуфераОбмена
|
||
Результат.Источник = ТекущийБуферОбмена.Источник;
|
||
Результат.Данные = ПолучитьИзВременногоХранилища(ТекущийБуферОбмена.Данные);
|
||
|
||
Возврат Результат;
|
||
КонецФункции
|
||
|
||
// Проверяет наличие сохраненных данных во внутренний буфере обмена.
|
||
//
|
||
// Параметры:
|
||
// Источник - Строка - если передан, то проверяется наличие данных
|
||
// в внутреннем буфере обмена с этим ключом.
|
||
// По умолчанию - Неопределено.
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если пустой.
|
||
//
|
||
Функция ПустойБуферОбмена(Источник = Неопределено) Экспорт
|
||
|
||
ТекущийБуферОбмена = ПараметрыСеанса.БуферОбмена; // см. СтрокиИзБуфераОбмена
|
||
ИсточникСовпадает = Истина;
|
||
Если Источник <> Неопределено Тогда
|
||
ИсточникСовпадает = (Источник = ТекущийБуферОбмена.Источник);
|
||
КонецЕсли;
|
||
Возврат (Не ИсточникСовпадает Или Не ЗначениеЗаполнено(ТекущийБуферОбмена.Данные));
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область БезопасноеВыполнениеВнешнегоКода
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
// Функции для поддержки работы конфигурации с профилем безопасности, в котором
|
||
// запрещено подключение внешних модулей без установки безопасного режима.
|
||
//
|
||
|
||
// Выполнить экспортную процедуру по имени с уровнем привилегий конфигурации.
|
||
// При включении профилей безопасности для вызова оператора Выполнить() используется
|
||
// переход в безопасный режим с профилем безопасности, используемым для информационной базы
|
||
// (если выше по стеку не был установлен другой безопасный режим).
|
||
//
|
||
// Параметры:
|
||
// ИмяМетода - Строка - имя экспортной процедуры в формате
|
||
// <имя объекта>.<имя процедуры>, где <имя объекта> - это
|
||
// общий модуль или модуль менеджера объекта.
|
||
// Параметры - Массив - параметры передаются в процедуру <ИмяЭкспортнойПроцедуры>
|
||
// в порядке расположения элементов массива.
|
||
//
|
||
// Пример:
|
||
// Параметры = Новый Массив();
|
||
// Параметры.Добавить("1");
|
||
// ОбщегоНазначения.ВыполнитьМетодКонфигурации("МойОбщийМодуль.МояПроцедура", Параметры);
|
||
//
|
||
Процедура ВыполнитьМетодКонфигурации(Знач ИмяМетода, Знач Параметры = Неопределено) Экспорт
|
||
|
||
ПроверитьИмяПроцедурыКонфигурации(ИмяМетода);
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.ПрофилиБезопасности") Тогда
|
||
МодульРаботаВБезопасномРежиме = ОбщийМодуль("РаботаВБезопасномРежиме");
|
||
Если МодульРаботаВБезопасномРежиме.ИспользуютсяПрофилиБезопасности()
|
||
И Не МодульРаботаВБезопасномРежиме.УстановленБезопасныйРежим() Тогда
|
||
|
||
ПрофильИнформационнойБазы = МодульРаботаВБезопасномРежиме.ПрофильБезопасностиИнформационнойБазы();
|
||
Если ЗначениеЗаполнено(ПрофильИнформационнойБазы) Тогда
|
||
|
||
УстановитьБезопасныйРежим(ПрофильИнформационнойБазы);
|
||
Если БезопасныйРежим() = Истина Тогда
|
||
УстановитьБезопасныйРежим(Ложь);
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
ПараметрыСтрока = "";
|
||
Если Параметры <> Неопределено И Параметры.Количество() > 0 Тогда
|
||
Для Индекс = 0 По Параметры.ВГраница() Цикл
|
||
ПараметрыСтрока = ПараметрыСтрока + "Параметры[" + XMLСтрока(Индекс) + "],";
|
||
КонецЦикла;
|
||
ПараметрыСтрока = Сред(ПараметрыСтрока, 1, СтрДлина(ПараметрыСтрока) - 1);
|
||
КонецЕсли;
|
||
|
||
Выполнить ИмяМетода + "(" + ПараметрыСтрока + ")";
|
||
|
||
КонецПроцедуры
|
||
|
||
// Выполнить экспортную процедуру объекта встроенного языка по имени.
|
||
// При включении профилей безопасности для вызова оператора Выполнить() используется
|
||
// переход в безопасный режим с профилем безопасности, используемым для информационной базы
|
||
// (если выше по стеку не был установлен другой безопасный режим).
|
||
//
|
||
// Параметры:
|
||
// Объект - Произвольный - объект встроенного языка 1С:Предприятия, содержащий методы (например, ОбработкаОбъект).
|
||
// ИмяМетода - Строка - имя экспортной процедуры модуля объекта обработки.
|
||
// Параметры - Массив - параметры передаются в процедуру <ИмяПроцедуры>
|
||
// в порядке расположения элементов массива.
|
||
//
|
||
Процедура ВыполнитьМетодОбъекта(Знач Объект, Знач ИмяМетода, Знач Параметры = Неопределено) Экспорт
|
||
|
||
// Проверка имени метода на корректность.
|
||
Попытка
|
||
Тест = Новый Структура(ИмяМетода, ИмяМетода);
|
||
Если Тест = Неопределено Тогда
|
||
ВызватьИсключение НСтр("ru = 'Проверка имени метода на корректность.'");
|
||
КонецЕсли;
|
||
Исключение
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Некорректное значение параметра %1 (%2) в %3.'"),
|
||
"ИмяМетода", ИмяМетода, "ОбщегоНазначения.ВыполнитьМетодОбъекта"),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецПопытки;
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.ПрофилиБезопасности") Тогда
|
||
МодульРаботаВБезопасномРежиме = ОбщийМодуль("РаботаВБезопасномРежиме");
|
||
Если МодульРаботаВБезопасномРежиме.ИспользуютсяПрофилиБезопасности()
|
||
И Не МодульРаботаВБезопасномРежиме.УстановленБезопасныйРежим() Тогда
|
||
|
||
МодульРаботаВБезопасномРежиме = ОбщийМодуль("РаботаВБезопасномРежиме");
|
||
ПрофильИнформационнойБазы = МодульРаботаВБезопасномРежиме.ПрофильБезопасностиИнформационнойБазы();
|
||
|
||
Если ЗначениеЗаполнено(ПрофильИнформационнойБазы) Тогда
|
||
|
||
УстановитьБезопасныйРежим(ПрофильИнформационнойБазы);
|
||
Если БезопасныйРежим() = Истина Тогда
|
||
УстановитьБезопасныйРежим(Ложь);
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
ПараметрыСтрока = "";
|
||
Если Параметры <> Неопределено И Параметры.Количество() > 0 Тогда
|
||
Для Индекс = 0 По Параметры.ВГраница() Цикл
|
||
ПараметрыСтрока = ПараметрыСтрока + "Параметры[" + XMLСтрока(Индекс) + "],";
|
||
КонецЦикла;
|
||
ПараметрыСтрока = Сред(ПараметрыСтрока, 1, СтрДлина(ПараметрыСтрока) - 1);
|
||
КонецЕсли;
|
||
|
||
Выполнить "Объект." + ИмяМетода + "(" + ПараметрыСтрока + ")";
|
||
|
||
КонецПроцедуры
|
||
|
||
// Выполняет произвольный алгоритм на встроенном языке 1С:Предприятия, предварительно устанавливая
|
||
// безопасный режим выполнения кода и безопасный режим разделения данных для всех разделителей,
|
||
// присутствующих в составе конфигурации.
|
||
//
|
||
// Параметры:
|
||
// Алгоритм - Строка - алгоритм на встроенном языке "1С:Предприятия".
|
||
// Параметры - Произвольный - контекст, который требуется для выполнения алгоритма.
|
||
// В тексте алгоритма обращение к контексту должно происходить по имени "Параметры".
|
||
// Например, выражение "Параметры.Значение1 = Параметры.Значение2" обращается к значениям
|
||
// "Значение1" и "Значение2", переданным в Параметры, как свойства.
|
||
//
|
||
// Пример:
|
||
//
|
||
// Параметры = Новый Структура;
|
||
// Параметры.Вставить("Значение1", 1);
|
||
// Параметры.Вставить("Значение2", 10);
|
||
// ОбщегоНазначения.ВыполнитьВБезопасномРежиме("Параметры.Значение1 = Параметры.Значение2", Параметры);
|
||
//
|
||
Процедура ВыполнитьВБезопасномРежиме(Знач Алгоритм, Знач Параметры = Неопределено) Экспорт
|
||
|
||
УстановитьБезопасныйРежим(Истина);
|
||
|
||
Если ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
|
||
МодульРаботаВМоделиСервиса = ОбщийМодуль("РаботаВМоделиСервиса");
|
||
МассивРазделителей = МодульРаботаВМоделиСервиса.РазделителиКонфигурации();
|
||
Иначе
|
||
МассивРазделителей = Новый Массив;
|
||
КонецЕсли;
|
||
|
||
Для Каждого ИмяРазделителя Из МассивРазделителей Цикл
|
||
|
||
УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина);
|
||
|
||
КонецЦикла;
|
||
|
||
Выполнить Алгоритм;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Вычисляет переданное выражение, предварительно устанавливая безопасный режим выполнения кода
|
||
// и безопасный режим разделения данных для всех разделителей, присутствующих в составе конфигурации.
|
||
//
|
||
// Параметры:
|
||
// Выражение - Строка - выражение на встроенном языке 1С:Предприятия.
|
||
// Параметры - Произвольный - контекст, который требуется для вычисления выражения.
|
||
// В тексте выражения обращение к контексту должно происходить по имени "Параметры".
|
||
// Например, выражение "Параметры.Значение1 = Параметры.Значение2" обращается к значениям
|
||
// "Значение1" и "Значение2" переданные в Параметры, как свойства.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Произвольный - результат вычисления выражения.
|
||
//
|
||
// Пример:
|
||
//
|
||
// // Пример 1
|
||
// Параметры = Новый Структура;
|
||
// Параметры.Вставить("Значение1", 1);
|
||
// Параметры.Вставить("Значение2", 10);
|
||
// Результат = ОбщегоНазначения.ВычислитьВБезопасномРежиме("Параметры.Значение1 = Параметры.Значение2", Параметры);
|
||
//
|
||
// // Пример 2
|
||
// Результат = ОбщегоНазначения.ВычислитьВБезопасномРежиме("СтандартныеПодсистемыСервер.ВерсияБиблиотеки()");
|
||
//
|
||
Функция ВычислитьВБезопасномРежиме(Знач Выражение, Знач Параметры = Неопределено) Экспорт
|
||
|
||
УстановитьБезопасныйРежим(Истина);
|
||
|
||
Если ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
|
||
МодульРаботаВМоделиСервиса = ОбщийМодуль("РаботаВМоделиСервиса");
|
||
МассивРазделителей = МодульРаботаВМоделиСервиса.РазделителиКонфигурации();
|
||
Иначе
|
||
МассивРазделителей = Новый Массив;
|
||
КонецЕсли;
|
||
|
||
Для Каждого ИмяРазделителя Из МассивРазделителей Цикл
|
||
|
||
УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина);
|
||
|
||
КонецЦикла;
|
||
|
||
Возврат Вычислить(Выражение);
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает описание защиты от опасных действий с отключенными предупреждениями.
|
||
//
|
||
// Возвращаемое значение:
|
||
// ОписаниеЗащитыОтОпасныхДействий - со свойством ПредупреждатьОбОпасныхДействиях = Ложь.
|
||
//
|
||
Функция ОписаниеЗащитыБезПредупреждений() Экспорт
|
||
|
||
ОписаниеЗащиты = Новый ОписаниеЗащитыОтОпасныхДействий;
|
||
ОписаниеЗащиты.ПредупреждатьОбОпасныхДействиях = Ложь;
|
||
|
||
Возврат ОписаниеЗащиты;
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область Запросы
|
||
|
||
// Подготавливает строку для использования в качестве шаблона поиска в запросе с оператором ПОДОБНО.
|
||
// Экранирует служебные символы, если они есть в строке.
|
||
//
|
||
// Параметры:
|
||
// СтрокаПоиска - Строка - произвольная строка.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка
|
||
//
|
||
// Пример:
|
||
// ВЫБРАТЬ
|
||
// Номенклатура.Ссылка КАК Ссылка
|
||
// ИЗ
|
||
// Справочник.Номенклатура КАК Номенклатура
|
||
// ГДЕ
|
||
// Номенклатура.Наименование ПОДОБНО &Шаблон СПЕЦСИМВОЛ "~"
|
||
//
|
||
// Запрос.УстановитьПараметр("Шаблон", ОбщегоНазначения.СформироватьСтрокуДляПоискаВЗапросе(ИскомыйТекст));
|
||
//
|
||
Функция СформироватьСтрокуДляПоискаВЗапросе(Знач СтрокаПоиска) Экспорт
|
||
|
||
Результат = СтрокаПоиска;
|
||
Результат = СтрЗаменить(Результат, "~", "~~");
|
||
Результат = СтрЗаменить(Результат, "%", "~%");
|
||
Результат = СтрЗаменить(Результат, "_", "~_");
|
||
Результат = СтрЗаменить(Результат, "[", "~[");
|
||
Результат = СтрЗаменить(Результат, "]", "~]");
|
||
Результат = СтрЗаменить(Результат, "^", "~^");
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает фрагмент текста запроса, отделяющего один запрос от другого.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - разделитель запросов.
|
||
//
|
||
Функция РазделительПакетаЗапросов() Экспорт
|
||
|
||
Возврат "
|
||
|;
|
||
|
|
||
|////////////////////////////////////////////////////////////////////////////////
|
||
|";
|
||
|
||
КонецФункции
|
||
|
||
// Возвращает фрагмент текста запроса, объединяющего результаты запросов в один запрос.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка
|
||
//
|
||
Функция ТекстОбъединитьВсе() Экспорт
|
||
|
||
Возврат
|
||
"
|
||
|
|
||
|ОБЪЕДИНИТЬ ВСЕ
|
||
|
|
||
|";
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область Прочее
|
||
|
||
// Выполняет проверки перед выполнением обработчика регламентного задания и прерывает выполнение,
|
||
// если его запуск в данный момент невозможен, например:
|
||
// - еще не завершено обновление программы;
|
||
// - запуск через консоль или другим способом, минуя включение функциональной опции
|
||
// (если регламентное задание зависит от функциональных опций);
|
||
// - попытка выполнения задания, работающего с внешними ресурсами в копии информационной базы.
|
||
//
|
||
// Параметры:
|
||
// РегламентноеЗадание - ОбъектМетаданныхРегламентноеЗадание - регламентное задание,
|
||
// из которого вызывается данная процедура.
|
||
//
|
||
// Пример:
|
||
// ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.<ИмяРегламентногоЗадания>);
|
||
//
|
||
Процедура ПриНачалеВыполненияРегламентногоЗадания(РегламентноеЗадание = Неопределено) Экспорт
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
Если РегистрыСведений.ПараметрыРаботыПрограммы.НеобходимоОбновление() Тогда
|
||
Текст = НСтр("ru = 'Вход в приложение временно невозможен в связи с обновлением на новую версию.
|
||
|Рекомендуется запрещать выполнение регламентных заданий на время обновления.'");
|
||
РегламентныеЗаданияСервер.ОтменитьВыполнениеЗадания(РегламентноеЗадание, Текст);
|
||
ВызватьИсключение Текст;
|
||
КонецЕсли;
|
||
|
||
Если Не РазделениеВключено()
|
||
И ПланыОбмена.ГлавныйУзел() = Неопределено
|
||
И ЗначениеЗаполнено(Константы.ГлавныйУзел.Получить()) Тогда
|
||
|
||
Текст = НСтр("ru = 'Вход в приложение временно невозможен до восстановления связи с главным узлом.
|
||
|Рекомендуется запрещать выполнение регламентных заданий на время восстановления.'");
|
||
РегламентныеЗаданияСервер.ОтменитьВыполнениеЗадания(РегламентноеЗадание, Текст);
|
||
ВызватьИсключение Текст;
|
||
КонецЕсли;
|
||
|
||
Если РегламентноеЗадание <> Неопределено
|
||
И ПодсистемаСуществует("СтандартныеПодсистемы.РегламентныеЗадания") Тогда
|
||
|
||
МодульБлокировкаРаботыСВнешнимиРесурсами = ОбщийМодуль("БлокировкаРаботыСВнешнимиРесурсами");
|
||
МодульБлокировкаРаботыСВнешнимиРесурсами.ПриНачалеВыполненияРегламентногоЗадания(РегламентноеЗадание);
|
||
|
||
МодульРегламентныеЗаданияСлужебный = ОбщийМодуль("РегламентныеЗаданияСлужебный");
|
||
Доступно = МодульРегламентныеЗаданияСлужебный.РегламентноеЗаданиеДоступноПоФункциональнымОпциям(РегламентноеЗадание);
|
||
|
||
Если Не Доступно Тогда
|
||
Задания = РегламентныеЗаданияСервер.НайтиЗадания(Новый Структура("Метаданные", РегламентноеЗадание));
|
||
Для Каждого Задание Из Задания Цикл
|
||
РегламентныеЗаданияСервер.ИзменитьЗадание(Задание.УникальныйИдентификатор,
|
||
Новый Структура("Использование", Ложь));
|
||
КонецЦикла;
|
||
Текст = НСтр("ru = 'Регламентное задание недоступно по функциональным опциям или
|
||
|не поддерживает работу в текущем режиме работы.
|
||
|Выполнение прервано. Задание отключено.'");
|
||
РегламентныеЗаданияСервер.ОтменитьВыполнениеЗадания(РегламентноеЗадание, Текст);
|
||
ВызватьИсключение Текст;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Если СтандартныеПодсистемыСервер.ТребуетсяУстановкаРегиональныхНастроекИнформационнойБазы() Тогда
|
||
Текст = НСтр("ru = 'Регламентное задание недоступно до установки начальных региональных настроек приложения.
|
||
|Выполнение прервано.'");
|
||
РегламентныеЗаданияСервер.ОтменитьВыполнениеЗадания(РегламентноеЗадание, Текст);
|
||
ВызватьИсключение Текст;
|
||
КонецЕсли;
|
||
|
||
Справочники.ВерсииРасширений.ЗарегистрироватьИспользованиеВерсииРасширений();
|
||
|
||
РегистрыСведений.ПараметрыРаботыВерсийРасширений.ПриУспешномНачалеВыполненияРегламентногоЗадания();
|
||
|
||
КонецПроцедуры
|
||
|
||
// Переводит параметры сеанса в состояние "Не установлено".
|
||
//
|
||
// Параметры:
|
||
// ПараметрыДляОчистки - Строка - имена параметров сеанса для очистки, разделенные ",".
|
||
// Исключения - Строка - имена параметров сеанса не предназначенные для очистки, разделенные ",".
|
||
//
|
||
Процедура ОчиститьПараметрыСеанса(ПараметрыДляОчистки = "", Исключения = "") Экспорт
|
||
|
||
МассивИсключений = СтрРазделить(Исключения, ",");
|
||
МассивПараметровДляОчистки = СтрРазделить(ПараметрыДляОчистки, ",", Ложь);
|
||
|
||
Если МассивПараметровДляОчистки.Количество() = 0 Тогда
|
||
Для Каждого ПараметрСеанса Из Метаданные.ПараметрыСеанса Цикл
|
||
Если МассивИсключений.Найти(ПараметрСеанса.Имя) = Неопределено Тогда
|
||
МассивПараметровДляОчистки.Добавить(ПараметрСеанса.Имя);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
Индекс = МассивПараметровДляОчистки.Найти("ПараметрыКлиентаНаСервере");
|
||
Если Индекс <> Неопределено Тогда
|
||
МассивПараметровДляОчистки.Удалить(Индекс);
|
||
КонецЕсли;
|
||
|
||
Индекс = МассивПараметровДляОчистки.Найти("ОсновнойЯзык");
|
||
Если Индекс <> Неопределено Тогда
|
||
МассивПараметровДляОчистки.Удалить(Индекс);
|
||
КонецЕсли;
|
||
|
||
Индекс = МассивПараметровДляОчистки.Найти("УстановленныеРасширения");
|
||
Если Индекс <> Неопределено Тогда
|
||
МассивПараметровДляОчистки.Удалить(Индекс);
|
||
КонецЕсли;
|
||
|
||
ПараметрыСеанса.Очистить(МассивПараметровДляОчистки);
|
||
|
||
КонецПроцедуры
|
||
|
||
// Проверяет, умещаются ли переданные табличные документы на страницу при печати.
|
||
//
|
||
// Параметры:
|
||
// ТабДокумент - ТабличныйДокумент - табличный документ.
|
||
// ВыводимыеОбласти - Массив
|
||
// - ТабличныйДокумент - массив из проверяемых таблиц или табличный документ.
|
||
// РезультатПриОшибке - Булево - какой возвращать результат при возникновении ошибки.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - умещаются или нет переданные документы.
|
||
//
|
||
Функция ПроверитьВыводТабличногоДокумента(ТабДокумент, ВыводимыеОбласти, РезультатПриОшибке = Истина) Экспорт
|
||
|
||
Попытка
|
||
Возврат ТабДокумент.ПроверитьВывод(ВыводимыеОбласти);
|
||
Исключение
|
||
Возврат РезультатПриОшибке;
|
||
КонецПопытки;
|
||
|
||
КонецФункции
|
||
|
||
// Сохраняет персональные настройки пользователя, относящиеся к подсистеме БазоваяФункциональность.
|
||
// Для получения настроек предусмотрены следующие функции:
|
||
// - ОбщегоНазначенияКлиент.ПредлагатьУстановкуРасширенияРаботыСФайлами(),
|
||
// - СтандартныеПодсистемыСервер.ЗапрашиватьПодтверждениеПриЗавершенииПрограммы(),
|
||
// - СтандартныеПодсистемыСервер.ПоказыватьПредупреждениеОбУстановленныхОбновленияхПрограммы().
|
||
//
|
||
// Параметры:
|
||
// Настройки - Структура:
|
||
// * НапоминатьОбУстановкеРасширенияРаботыСФайлами - Булево - признак необходимости
|
||
// напоминания об установке расширения.
|
||
// * ЗапрашиватьПодтверждениеПриЗавершенииПрограммы - Булево - запрашивать подтверждение по завершении работы.
|
||
// * ПоказыватьПредупреждениеОбУстановленныхОбновленияхПрограммы - Булево - показывать оповещение при
|
||
// динамическом обновлении программы.
|
||
//
|
||
Процедура СохранитьПерсональныеНастройки(Настройки) Экспорт
|
||
|
||
Если Настройки.Свойство("НапоминатьОбУстановкеРасширенияРаботыСФайлами") Тогда
|
||
Если ЭтоВебКлиент() Тогда
|
||
ИдентификаторКлиента = СтандартныеПодсистемыСервер.ПараметрыКлиентаНаСервере().Получить("ИдентификаторКлиента");
|
||
Если ИдентификаторКлиента = Неопределено Тогда
|
||
СистемнаяИнформация = Новый СистемнаяИнформация;
|
||
ИдентификаторКлиента = СистемнаяИнформация.ИдентификаторКлиента;
|
||
КонецЕсли;
|
||
ХранилищеОбщихНастроекСохранить(
|
||
"НастройкиПрограммы/ПредлагатьУстановкуРасширенияРаботыСФайлами",
|
||
ИдентификаторКлиента, Настройки.НапоминатьОбУстановкеРасширенияРаботыСФайлами);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Если Настройки.Свойство("ЗапрашиватьПодтверждениеПриЗавершенииПрограммы") Тогда
|
||
ХранилищеОбщихНастроекСохранить("ОбщиеНастройкиПользователя",
|
||
"ЗапрашиватьПодтверждениеПриЗавершенииПрограммы",
|
||
Настройки.ЗапрашиватьПодтверждениеПриЗавершенииПрограммы);
|
||
КонецЕсли;
|
||
|
||
Если Настройки.Свойство("ПоказыватьПредупреждениеОбУстановленныхОбновленияхПрограммы") Тогда
|
||
ХранилищеОбщихНастроекСохранить("ОбщиеНастройкиПользователя",
|
||
"ПоказыватьПредупреждениеОбУстановленныхОбновленияхПрограммы",
|
||
Настройки.ПоказыватьПредупреждениеОбУстановленныхОбновленияхПрограммы);
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Выполняет пропорциональное распределение суммы в соответствии
|
||
// с заданными коэффициентами распределения.
|
||
//
|
||
// Параметры:
|
||
// РаспределяемаяСумма - Число - сумма, которую надо распределить, если сумма равна 0 - то возвращается Неопределено;
|
||
// Если передана отрицательная - расчет по модулю и после инверсия знаков результата.
|
||
// Коэффициенты - Массив из Число - коэффициенты распределения, должны быть положительны или отрицательными
|
||
// одновременно.
|
||
// Точность - Число - точность округления при распределении.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Массив из Число - массив размерностью равный массиву коэффициентов, содержит
|
||
// суммы в соответствии с весом коэффициента (из массива коэффициентов).
|
||
// В случае, если распределить невозможно (кол-во коэффициентов = 0
|
||
// есть коэффициенты с отрицательным значением или суммарный вес коэффициентов = 0),
|
||
// тогда будет возвращено Неопределено.
|
||
//
|
||
// Пример:
|
||
//
|
||
// Коэффициенты = Новый Массив;
|
||
// Коэффициенты.Добавить(1);
|
||
// Коэффициенты.Добавить(2);
|
||
// Результат = ОбщегоНазначенияКлиентСервер.РаспределитьСуммуПропорциональноКоэффициентам(1, Коэффициенты);
|
||
// // Результат = [0.33, 0.67]
|
||
//
|
||
Функция РаспределитьСуммуПропорциональноКоэффициентам(
|
||
Знач РаспределяемаяСумма, Коэффициенты, Знач Точность = 2) Экспорт
|
||
|
||
Возврат ОбщегоНазначенияКлиентСервер.РаспределитьСуммуПропорциональноКоэффициентам(
|
||
РаспределяемаяСумма, Коэффициенты, Точность);
|
||
|
||
КонецФункции
|
||
|
||
// Процедура предназначена для заполнения реквизита формы типа ДанныеФормыДерево.
|
||
//
|
||
// Параметры:
|
||
// КоллекцияЭлементовДерева - ДанныеФормыКоллекцияЭлементовДерева - реквизит, который нужно заполнить.
|
||
// ДеревоЗначений - ДеревоЗначений - данные для заполнения.
|
||
//
|
||
Процедура ЗаполнитьКоллекциюЭлементовДереваДанныхФормы(КоллекцияЭлементовДерева, ДеревоЗначений) Экспорт
|
||
|
||
Для Каждого СтрокаТаблицы Из ДеревоЗначений.Строки Цикл
|
||
|
||
ЭлементДерева = КоллекцияЭлементовДерева.Добавить();
|
||
ЗаполнитьЗначенияСвойств(ЭлементДерева, СтрокаТаблицы);
|
||
Если СтрокаТаблицы.Строки.Количество() > 0 Тогда
|
||
ЗаполнитьКоллекциюЭлементовДереваДанныхФормы(ЭлементДерева.ПолучитьЭлементы(), СтрокаТаблицы);
|
||
КонецЕсли;
|
||
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Подключает внешнюю компоненту, выполненную по технологии Native API или COM,
|
||
// из макета конфигурации (хранится в виде ZIP-архива).
|
||
//
|
||
// Параметры:
|
||
// Идентификатор - Строка - идентификатор объекта внешней компоненты.
|
||
// ПолноеИмяМакета - Строка - полное имя макета конфигурации с ZIP-архивом.
|
||
// Изолированно - Булево - если Истина, компонента должна подключаться изолированно,
|
||
// в этом случае она загружается в отдельный процесс операционной системы.
|
||
// Если Ложь, то в этом случае компонента будет выполняться в том же процессе
|
||
// операционной системы, который выполняет код встроенного языка.
|
||
// - Неопределено - (по умолчанию Неопределено) соответствует поведению платформы:
|
||
// не изолированно - если компонентой поддерживается только этот режим,
|
||
// изолированно - в остальных случаях.
|
||
// См. https://its.1c.eu/db/v83doc#bookmark:dev:TI000001866
|
||
//
|
||
// Возвращаемое значение:
|
||
// - ОбъектВнешнейКомпоненты - экземпляр объекта внешней компоненты.
|
||
// - Неопределено - если не удалось создать.
|
||
//
|
||
// Пример:
|
||
//
|
||
// ПодключаемыйМодуль = ОбщегоНазначения.ПодключитьКомпонентуИзМакета(
|
||
// "QRCodeExtension",
|
||
// "ОбщийМакет.КомпонентаПечатиQRКода");
|
||
//
|
||
// Если ПодключаемыйМодуль <> Неопределено Тогда
|
||
// // ПодключаемыйМодуль содержит созданный экземпляр подключенной компоненты.
|
||
// КонецЕсли;
|
||
//
|
||
// ПодключаемыйМодуль = Неопределено;
|
||
//
|
||
Функция ПодключитьКомпонентуИзМакета(Знач Идентификатор, Знач ПолноеИмяМакета, Знач Изолированно = Null) Экспорт
|
||
|
||
РезультатПроверкиВнешнейКомпоненты = Неопределено;
|
||
|
||
Если Изолированно = Null Тогда
|
||
Изолированно = ТипПодключенияКомпонентыПоУмолчанию();
|
||
КонецЕсли;
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.ВнешниеКомпоненты") Тогда
|
||
МодульВнешниеКомпонентыСлужебный = ОбщийМодуль("ВнешниеКомпонентыСлужебный");
|
||
РезультатПроверкиВнешнейКомпоненты = МодульВнешниеКомпонентыСлужебный.ПроверитьПодключениеКомпоненты(Идентификатор);
|
||
РезультатПроверкиВнешнейКомпоненты.Вставить("Доступна",
|
||
Не ЗначениеЗаполнено(РезультатПроверкиВнешнейКомпоненты.ОписаниеОшибки));
|
||
КонецЕсли;
|
||
|
||
КомпонентаПоследнейВерсии = СтандартныеПодсистемыСервер.КомпонентаПоследнейВерсии(
|
||
Идентификатор, ПолноеИмяМакета, РезультатПроверкиВнешнейКомпоненты);
|
||
|
||
Результат = ПодключитьКомпонентуПоИдентификатору(Идентификатор,
|
||
КомпонентаПоследнейВерсии.Местоположение, Изолированно);
|
||
|
||
Возврат Результат.ПодключаемыйМодуль;
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область УстаревшиеПроцедурыИФункции
|
||
|
||
// Устарела. Следует использовать
|
||
// ОбщегоНазначения.РазделениеВключено И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево
|
||
//
|
||
Функция ИспользованиеРазделителяСеанса() Экспорт
|
||
|
||
Если Не РазделениеВключено() Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
Если ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
|
||
МодульРаботаВМоделиСервиса = ОбщийМодуль("РаботаВМоделиСервиса");
|
||
Возврат МодульРаботаВМоделиСервиса.ИспользованиеРазделителяСеанса();
|
||
КонецЕсли;
|
||
|
||
КонецФункции
|
||
|
||
// Устарела. Следует использовать ФайловаяСистема.СоздатьВременныйКаталог
|
||
// Создает временный каталог. После окончания работы с временным каталогом его необходимо удалить
|
||
// с помощью ОбщегоНазначения.УдалитьВременныйКаталог.
|
||
//
|
||
// Параметры:
|
||
// Расширение - Строка - расширение каталога, которое идентифицирует назначение временного каталога
|
||
// и подсистему, которая его создала.
|
||
// Рекомендуется указывать на английском языке.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - полный путь к каталогу с разделителем пути.
|
||
//
|
||
Функция СоздатьВременныйКаталог(Знач Расширение = "") Экспорт
|
||
|
||
Возврат ФайловаяСистема.СоздатьВременныйКаталог(Расширение);
|
||
|
||
КонецФункции
|
||
|
||
// Устарела. Следует использовать ФайловаяСистема.УдалитьВременныйКаталог
|
||
// Удаляет временный каталог вместе с его содержимым, если возможно.
|
||
// Если временный каталог не может быть удален (например, он занят каким-то процессом),
|
||
// то в журнал регистрации записывается соответствующее предупреждение, а процедура завершается.
|
||
//
|
||
// Для совместного использования с ОбщегоНазначения.СоздатьВременныйКаталог,
|
||
// после окончания работы с временным каталогом.
|
||
//
|
||
// Параметры:
|
||
// ПутьККаталогу - Строка - полный путь к временному каталогу.
|
||
//
|
||
Процедура УдалитьВременныйКаталог(Знач ПутьККаталогу) Экспорт
|
||
|
||
ФайловаяСистема.УдалитьВременныйКаталог(ПутьККаталогу);
|
||
|
||
КонецПроцедуры
|
||
|
||
// Устарела. Проверяет наличие механизма платформы, предупреждающего об опасных действиях.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - если Истина, тогда работает механизм предупреждений безопасности.
|
||
//
|
||
Функция ЕстьЗащитаОтОпасныхДействий() Экспорт
|
||
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
// Устарела. Создает и возвращает экземпляр отчета или обработки по полному имени объекта метаданных.
|
||
//
|
||
// Параметры:
|
||
// ПолноеИмя - Строка - полное имя объекта метаданных. Пример: "Отчет.БизнесПроцессы".
|
||
//
|
||
// Возвращаемое значение:
|
||
// ОтчетОбъект
|
||
// ОбработкаОбъект - экземпляр отчета или обработки.
|
||
//
|
||
Функция ОбъектПоПолномуИмени(ПолноеИмя) Экспорт
|
||
МассивСтрок = СтрРазделить(ПолноеИмя, ".");
|
||
|
||
Если МассивСтрок.Количество() >= 2 Тогда
|
||
Вид = ВРег(МассивСтрок[0]);
|
||
Имя = МассивСтрок[1];
|
||
Иначе
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверное значение параметра %1 в функции %2. Некорректное полное имя отчета или обработки ""%3"".'"),
|
||
"ПолноеИмя", "ОбщегоНазначения.ОбъектПоПолномуИмени", ПолноеИмя),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
Если Вид = "ОТЧЕТ" Тогда
|
||
Возврат Отчеты[Имя].Создать();
|
||
ИначеЕсли Вид = "ОБРАБОТКА" Тогда
|
||
Возврат Обработки[Имя].Создать();
|
||
Иначе
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверное значение параметра %1 в функции %2. ""%3"" не является отчетом или обработкой.'"),
|
||
"ПолноеИмя", "ОбщегоНазначения.ОбъектПоПолномуИмени", ПолноеИмя),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
КонецФункции
|
||
|
||
// Устарела. Следует использовать ОбщегоНазначения.ЭтоMacOSКлиент
|
||
// Возвращает Истина, если клиентское приложение запущено под управлением ОС X.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - если нет клиентского приложения, возвращается Ложь.
|
||
//
|
||
Функция ЭтоOSXКлиент() Экспорт
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
ЭтоMacOSКлиент = СтандартныеПодсистемыСервер.ПараметрыКлиентаНаСервере().Получить("ЭтоMacOSКлиент");
|
||
|
||
Если ЭтоMacOSКлиент = Неопределено Тогда
|
||
Возврат Ложь; // Нет клиентского приложения.
|
||
КонецЕсли;
|
||
|
||
Возврат ЭтоMacOSКлиент;
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#КонецЕсли
|
||
|
||
#КонецОбласти
|
||
|
||
#Если НЕ МобильныйАвтономныйСервер Тогда
|
||
|
||
#Область СлужебныйПрограммныйИнтерфейс
|
||
|
||
// Выгружает запрос в строку XML, которую можно вставить в Консоль запросов.
|
||
// Для переноса запроса и всех его параметров в Консоль запросов, необходимо вызвать функцию в окне.
|
||
// "Вычислить выражение" (Shift + F9), скопировать полученный XML в поле "Текст запроса"
|
||
// консоли запросов и выполнить команду "Заполнить из XML" из меню "Еще".
|
||
// Подробнее об использование функции смотрите в справке к консоли запросов.
|
||
//
|
||
// Параметры:
|
||
// Запрос - Запрос - запрос, который необходимо выгрузить в формат строки XML.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - строка в формате XML, которую можно извлечь при помощи метода "ОбщегоНазначения.ЗначениеИзСтрокиXML".
|
||
// После извлечения получится объект типа "Структура" с полями:
|
||
// * Текст - Строка - текст запроса.
|
||
// * Параметры - Структура - параметры запроса.
|
||
//
|
||
Функция ЗапросВСтрокуXML(Запрос) Экспорт // АПК:299 - используется при отладке запросов, см. описание функции.
|
||
Структура = Новый Структура("Текст, Параметры");
|
||
ЗаполнитьЗначенияСвойств(Структура, Запрос);
|
||
Возврат ЗначениеВСтрокуXML(Структура);
|
||
КонецФункции
|
||
|
||
Функция ПодключитьКомпонентуПоИдентификатору(Знач Идентификатор, Знач Местоположение, Знач Изолированно = Null) Экспорт
|
||
|
||
ПроверитьМестоположениеКомпоненты(Идентификатор, Местоположение);
|
||
|
||
Результат = Новый Структура;
|
||
Результат.Вставить("Подключено", Ложь);
|
||
Результат.Вставить("ПодключаемыйМодуль", Неопределено);
|
||
Результат.Вставить("ОписаниеОшибки", "");
|
||
|
||
Попытка
|
||
|
||
#Если МобильноеПриложениеСервер Тогда
|
||
РезультатПодключения = ПодключитьВнешнююКомпоненту(Местоположение, Идентификатор + "SymbolicName");
|
||
#Иначе
|
||
Если Изолированно = Null Тогда
|
||
Изолированно = ТипПодключенияКомпонентыПоУмолчанию();
|
||
КонецЕсли;
|
||
РезультатПодключения = ПодключитьВнешнююКомпоненту(Местоположение, Идентификатор + "SymbolicName",,
|
||
ОбщегоНазначенияСлужебныйКлиентСервер.ТипПодключенияКомпоненты(Изолированно));
|
||
#КонецЕсли
|
||
|
||
Исключение
|
||
ИнформацияОбОшибке = ИнформацияОбОшибке();
|
||
ЗаголовокОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Не удалось подключить внешнюю компоненту ""%1"" на сервере по причине:'"),
|
||
Идентификатор);
|
||
|
||
Результат.ОписаниеОшибки = ЗаголовокОшибки + Символы.ПС
|
||
+ ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
|
||
|
||
КомментарийДляЖурнала = ЗаголовокОшибки + Символы.ПС
|
||
+ ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке)
|
||
+ СистемнаяИнформацияДляЖурналаРегистрации();
|
||
|
||
ЗаписьЖурналаРегистрации(НСтр("ru = 'Подключение внешней компоненты на сервере'", КодОсновногоЯзыка()),
|
||
УровеньЖурналаРегистрации.Ошибка,,, КомментарийДляЖурнала);
|
||
Возврат Результат;
|
||
КонецПопытки;
|
||
|
||
Если Не РезультатПодключения Тогда
|
||
|
||
ОшибкаСовместимостиКомпонентыИзМакета = ОшибкаСовместимостиКомпонентыИзМакета(Местоположение);
|
||
|
||
Если ЗначениеЗаполнено(ОшибкаСовместимостиКомпонентыИзМакета) Тогда
|
||
Результат.ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Не удалось подключить внешнюю компоненту ""%1"" на сервере по причине:
|
||
|%2.
|
||
|Техническая информация:
|
||
|%3
|
||
|Метод %4 вернул Ложь.'"), Идентификатор, ОшибкаСовместимостиКомпонентыИзМакета, Местоположение,
|
||
"ПодключитьВнешнююКомпоненту");
|
||
Иначе
|
||
Результат.ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Не удалось подключить внешнюю компоненту ""%1"" на сервере.
|
||
|Техническая информация:
|
||
|%2
|
||
|Метод %3 вернул Ложь.'"), Идентификатор, Местоположение, "ПодключитьВнешнююКомпоненту");
|
||
КонецЕсли;
|
||
|
||
Попытка
|
||
ВызватьИсключение НСтр("ru = 'Стек вызовов:'")
|
||
Исключение
|
||
КомментарийДляЖурнала = Результат.ОписаниеОшибки + Символы.ПС + Символы.ПС
|
||
+ ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())
|
||
+ СистемнаяИнформацияДляЖурналаРегистрации();
|
||
КонецПопытки;
|
||
|
||
ЗаписьЖурналаРегистрации(НСтр("ru = 'Подключение внешней компоненты на сервере'", КодОсновногоЯзыка()),
|
||
УровеньЖурналаРегистрации.Ошибка,,, КомментарийДляЖурнала);
|
||
Возврат Результат;
|
||
КонецЕсли;
|
||
|
||
ПодключаемыйМодуль = Неопределено;
|
||
Попытка
|
||
ПодключаемыйМодуль = Новый("AddIn." + Идентификатор + "SymbolicName" + "." + Идентификатор);
|
||
Если ПодключаемыйМодуль = Неопределено Тогда
|
||
ВызватьИсключение НСтр("ru = 'Оператор Новый вернул Неопределено'");
|
||
КонецЕсли;
|
||
Исключение
|
||
ПодключаемыйМодуль = Неопределено;
|
||
ИнформацияОбОшибке = ИнформацияОбОшибке();
|
||
КонецПопытки;
|
||
|
||
Если ПодключаемыйМодуль = Неопределено Тогда
|
||
Результат.ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Не удалось создать объект внешней компоненты ""%1"", подключенной на сервере, по причине:
|
||
|%2'"),
|
||
Идентификатор, ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке));
|
||
|
||
КомментарийДляЖурнала = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Не удалось создать объект внешней компоненты ""%1"", подключенной на сервере, по причине:
|
||
|%2'"),
|
||
Идентификатор, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке)
|
||
+ СистемнаяИнформацияДляЖурналаРегистрации());
|
||
|
||
ЗаписьЖурналаРегистрации(НСтр("ru = 'Подключение внешней компоненты на сервере'", КодОсновногоЯзыка()),
|
||
УровеньЖурналаРегистрации.Ошибка,,, КомментарийДляЖурнала);
|
||
Возврат Результат;
|
||
КонецЕсли;
|
||
|
||
Результат.Подключено = Истина;
|
||
Результат.ПодключаемыйМодуль = ПодключаемыйМодуль;
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
Функция ТипПодключенияКомпонентыПоУмолчанию() Экспорт
|
||
|
||
#Если Не ВебКлиент И Не МобильныйКлиент И Не МобильноеПриложениеСервер Тогда
|
||
|
||
СистемнаяИнформация = Новый СистемнаяИнформация;
|
||
ВерсияПриложения = СистемнаяИнформация.ВерсияПриложения;
|
||
Если СтрНачинаетсяС(ВерсияПриложения, "8.3.24") И ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияПриложения, "8.3.24.1267") >= 0
|
||
Или СтрНачинаетсяС(ВерсияПриложения, "8.3.23") И ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияПриложения, "8.3.23.1947") >= 0
|
||
Или СтрНачинаетсяС(ВерсияПриложения, "8.3.22") И ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияПриложения, "8.3.22.2322") >= 0
|
||
Или СтрНачинаетсяС(ВерсияПриложения, "8.3.21") И ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияПриложения, "8.3.21.1930") >= 0 Тогда
|
||
Возврат Неопределено;
|
||
Иначе
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
#Иначе
|
||
|
||
Возврат Неопределено;
|
||
|
||
#КонецЕсли
|
||
|
||
КонецФункции
|
||
|
||
Функция СтрокаВВидеНСтр(Знач ПроверяемаяСтрока) Экспорт
|
||
|
||
ПроверяемаяСтрока = СтрЗаменить(ПроверяемаяСтрока, " ", "");
|
||
|
||
ВариантыСовпадений = Новый Массив;
|
||
Для каждого Язык Из Метаданные.Языки Цикл
|
||
ВариантыСовпадений.Добавить(Язык.КодЯзыка + "=");
|
||
КонецЦикла;
|
||
|
||
Для каждого ВариантСовпадения Из ВариантыСовпадений Цикл
|
||
Если СтрНайти(ПроверяемаяСтрока, ВариантСовпадения) > 0 Тогда
|
||
Возврат Истина;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат Ложь;
|
||
|
||
КонецФункции
|
||
|
||
// Устанавливает условное оформление списка выбора
|
||
//
|
||
// Параметры:
|
||
// Форма - ФормаКлиентскогоПриложения - форма, для которой устанавливается оформление.
|
||
// ИмяЭлемента - Строка - имя элемента, для которого устанавливается оформление.
|
||
// ИмяПоляКомпоновкиДанных - Строка - имя поля компоновки данных.
|
||
//
|
||
Процедура УстановитьУсловноеОформлениеСпискаВыбора(Форма, ИмяЭлемента, ИмяПоляКомпоновкиДанных) Экспорт
|
||
|
||
Элементы = Форма.Элементы;
|
||
УсловноеОформление = Форма.УсловноеОформление;
|
||
|
||
Для каждого ЭлементВыбора Из Элементы[ИмяЭлемента].СписокВыбора Цикл
|
||
|
||
Элемент = УсловноеОформление.Элементы.Добавить();
|
||
|
||
ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
|
||
ЭлементФормы = Элементы[ИмяЭлемента]; // ПолеФормы
|
||
ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(ЭлементФормы.Имя);
|
||
|
||
ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
|
||
ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ИмяПоляКомпоновкиДанных);
|
||
ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
|
||
ОтборЭлемента.ПравоеЗначение = ЭлементВыбора.Значение;
|
||
|
||
Элемент.Оформление.УстановитьЗначениеПараметра("Текст", ЭлементВыбора.Представление);
|
||
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Возвращает суффикс текущего языка для мультиязычных реквизитов.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - "Язык1" или "Язык2", если язык пользователя является дополнительным
|
||
// Пустая строка, если язык пользователя является основным.
|
||
// Неопределено - мультиязычное хранение данных не используется.
|
||
//
|
||
Функция СуффиксЯзыкаТекущегоПользователя() Экспорт
|
||
|
||
Результат = Новый Структура();
|
||
Результат.Вставить("СуффиксТекущегоЯзыка", "");
|
||
Результат.Вставить("ЭтоОсновнойЯзык", "");
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
|
||
МодульМультиязычностьСервер = ОбщийМодуль("МультиязычностьСервер");
|
||
СуффиксТекущегоЯзыка = МодульМультиязычностьСервер.СуффиксТекущегоЯзыка();
|
||
|
||
Если ЗначениеЗаполнено(СуффиксТекущегоЯзыка) Тогда
|
||
Возврат СуффиксТекущегоЯзыка;
|
||
КонецЕсли;
|
||
Иначе
|
||
СуффиксТекущегоЯзыка = "";
|
||
КонецЕсли;
|
||
|
||
Если ЭтоОсновнойЯзык() Тогда
|
||
Возврат СуффиксТекущегоЯзыка;
|
||
КонецЕсли;
|
||
|
||
Возврат Неопределено;
|
||
|
||
КонецФункции
|
||
|
||
// Сокращает имя файла с расширением, если оно превышает размер в 255 байт.
|
||
// При этом сокращается часть имени файла без расширения, в конец которой добавляется уникальное значение,
|
||
// вычисленное по алгоритму MD5.
|
||
//
|
||
// Параметры:
|
||
// ИмяФайла - Строка - имя файла с расширением
|
||
//
|
||
Процедура СократитьИмяФайла(ИмяФайла) Экспорт
|
||
|
||
ОграничениеВБайтах = 127;
|
||
Файл = Новый Файл(ИмяФайла);
|
||
|
||
Если РазмерСтрокиВБайтах(Файл.Имя) <= ОграничениеВБайтах Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
Строка = "";
|
||
ОстатокСтроки = "";
|
||
РазмерСтроки = 0;
|
||
МаксимальныйРазмерСтроки = ОграничениеВБайтах - 32;
|
||
|
||
РазмерРасширения = РазмерСтрокиВБайтах(Файл.Расширение);
|
||
СокращатьВместеСРасширением = РазмерРасширения > 32;
|
||
|
||
Если СокращатьВместеСРасширением Тогда
|
||
СокращаемоеИмя = Файл.Имя;
|
||
Иначе
|
||
СокращаемоеИмя = Файл.ИмяБезРасширения;
|
||
РазмерСтроки = РазмерРасширения;
|
||
КонецЕсли;
|
||
|
||
Для НомерСимвола = 1 По СтрДлина(СокращаемоеИмя) Цикл
|
||
Символ = Сред(СокращаемоеИмя, НомерСимвола, 1);
|
||
РазмерСимвола = РазмерСтрокиВБайтах(Символ);
|
||
|
||
Если РазмерСтроки + РазмерСимвола > МаксимальныйРазмерСтроки Тогда
|
||
ОстатокСтроки = Сред(СокращаемоеИмя, НомерСимвола);
|
||
Прервать;
|
||
КонецЕсли;
|
||
|
||
Строка = Строка + Символ;
|
||
РазмерСтроки = РазмерСтроки + РазмерСимвола;
|
||
КонецЦикла;
|
||
|
||
ИмяФайла = Строка;
|
||
|
||
ХешированиеДанных = Новый ХешированиеДанных(ХешФункция.MD5);
|
||
ХешированиеДанных.Добавить(ОстатокСтроки);
|
||
ХешСумма = СтрЗаменить(ХешированиеДанных.ХешСумма, " ", "");
|
||
|
||
ИмяФайла = Файл.Путь + ИмяФайла + ХешСумма + ?(СокращатьВместеСРасширением, "", Файл.Расширение);
|
||
|
||
КонецПроцедуры
|
||
|
||
// Служебные объекты и объекты при загрузке из резервной копии,
|
||
// должны записываться без какой-либо прикладной логики.
|
||
//
|
||
// Запись служебных объектов без отключения прикладной логики,
|
||
// может привести к зацикливанию, снижению производительности,
|
||
// а также избыточным изменениях, которые в некоторых случаях
|
||
// могут неожиданно повлиять на логику работы.
|
||
//
|
||
// Служебными являются объекты, которые обычно не участвуют
|
||
// в обмене данными, не зависят от других объектов, например:
|
||
// - кэши;
|
||
// - даты обновления кэшей и аналогичные признаки;
|
||
// - промежуточные данные для передачи параметров в фоновые задания;
|
||
// - вспомогательные служебные данные (например, ключи доступа,
|
||
// идентификаторы объектов метаданных).
|
||
//
|
||
// При использовании подсистемы Управление доступом, требуется
|
||
// отдельно вызывать процедуру ОтключитьОбновлениеКлючейДоступа
|
||
// общего модуля УправлениеДоступом.
|
||
//
|
||
// Процедура включает режим загрузки данных,
|
||
// отключает регистрацию объектов на планах обмена,
|
||
// отключает контроль механизма удаления помеченных объектов.
|
||
//
|
||
// Параметры:
|
||
// Объект - ПланОбменаОбъект
|
||
// - КонстантаМенеджерЗначения
|
||
// - СправочникОбъект
|
||
// - ДокументОбъект
|
||
// - ПоследовательностьНаборЗаписей
|
||
// - ПланВидовХарактеристикОбъект
|
||
// - ПланСчетовОбъект
|
||
// - ПланВидовРасчетаОбъект
|
||
// - БизнесПроцессОбъект
|
||
// - ЗадачаОбъект
|
||
// - УдалениеОбъекта
|
||
// - РегистрСведенийНаборЗаписей
|
||
// - РегистрНакопленияНаборЗаписей
|
||
// - РегистрБухгалтерииНаборЗаписей
|
||
// - РегистрРасчетаНаборЗаписей
|
||
// - ПерерасчетНаборЗаписей
|
||
//
|
||
// ЭтоУзелПланаОбмена - Булево
|
||
//
|
||
Процедура ОтключитьКонтрольЗаписи(Объект, ЭтоУзелПланаОбмена = Ложь) Экспорт
|
||
|
||
Объект.ДополнительныеСвойства.Вставить("НеВыполнятьКонтрольУдаляемых");
|
||
Объект.ДополнительныеСвойства.Вставить("ОтключитьМеханизмРегистрацииОбъектов");
|
||
Объект.ОбменДанными.Загрузка = Истина;
|
||
Если Не ЭтоУзелПланаОбмена Тогда
|
||
Объект.ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция МакетСуществует(ПолноеИмяМакета) Экспорт
|
||
|
||
Макет = Метаданные.НайтиПоПолномуИмени(ПолноеИмяМакета);
|
||
Если ТипЗнч(Макет) = Тип("ОбъектМетаданных") Тогда
|
||
|
||
Шаблон = Новый Структура("ТипМакета");
|
||
ЗаполнитьЗначенияСвойств(Шаблон, Макет);
|
||
ТипМакета = Неопределено;
|
||
Если Шаблон.Свойство("ТипМакета", ТипМакета) Тогда
|
||
Возврат ТипМакета <> Неопределено;
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
|
||
Возврат Ложь;
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область СлужебныеПроцедурыИФункции
|
||
|
||
#Область ДанныеВБазе
|
||
|
||
#Область ЗначенияРеквизитов
|
||
|
||
// Проверяет существование указанных реквизитов у объекта метаданных.
|
||
//
|
||
// Параметры:
|
||
// ПолноеИмяОбъектаМетаданных - Строка - полное имя проверяемого объекта.
|
||
// ПроверяемыеВыражения - Массив - имена полей или проверяемые выражения объекта метаданных.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Структура:
|
||
// * Ошибка - Булево - найдена ошибка.
|
||
// * ОписаниеОшибки - Строка - описание найденных ошибок.
|
||
//
|
||
// Пример:
|
||
//
|
||
// Реквизиты = Новый Массив;
|
||
// Реквизиты.Добавить("Номер");
|
||
// Реквизиты.Добавить("Валюта.НаименованиеПолное");
|
||
//
|
||
// Результат = ОбщегоНазначения.ПроверитьСуществованиеРеквизитовОбъекта("Документ.ЗаказПокупателя", Реквизиты);
|
||
//
|
||
// Если Результат.Ошибка Тогда
|
||
// ВызватьИсключение Результат.ОписаниеОшибки;
|
||
// КонецЕсли;
|
||
//
|
||
Функция ПроверитьСуществованиеРеквизитовОбъекта(ПолноеИмяОбъектаМетаданных, ПроверяемыеВыражения)
|
||
|
||
МетаданныеОбъекта = ОбъектМетаданныхПоПолномуИмени(ПолноеИмяОбъектаМетаданных);
|
||
Если МетаданныеОбъекта = Неопределено Тогда
|
||
Возврат Новый Структура("Ошибка, ОписаниеОшибки", Истина,
|
||
СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Несуществующий объект метаданных ""%1"".'"), ПолноеИмяОбъектаМетаданных));
|
||
КонецЕсли;
|
||
|
||
// Разрешение вызова из безопасного режима внешней обработки или расширения.
|
||
// Информация о доступности полей источника схемы при проверке метаданных не является секретной.
|
||
УстановитьОтключениеБезопасногоРежима(Истина);
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
Схема = Новый СхемаЗапроса;
|
||
Пакет = Схема.ПакетЗапросов.Добавить(Тип("ЗапросВыбораСхемыЗапроса"));
|
||
Оператор = Пакет.Операторы.Получить(0);
|
||
|
||
Источник = Оператор.Источники.Добавить(ПолноеИмяОбъектаМетаданных, "Таблица");
|
||
ТекстОшибки = "";
|
||
|
||
Для Каждого ТекущееВыражение Из ПроверяемыеВыражения Цикл
|
||
|
||
Если Не ПолеИсточникаСхемыЗапросаДоступно(Источник, ТекущееВыражение) Тогда
|
||
ТекстОшибки = ТекстОшибки + Символы.ПС + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Поле объекта ""%1"" не существует.'"), ТекущееВыражение);
|
||
КонецЕсли;
|
||
|
||
КонецЦикла;
|
||
|
||
Возврат Новый Структура("Ошибка, ОписаниеОшибки", Не ПустаяСтрока(ТекстОшибки), ТекстОшибки);
|
||
|
||
КонецФункции
|
||
|
||
// Используется в ПроверитьСуществованиеРеквизитовОбъекта.
|
||
// Выполняет проверку доступности поля проверяемого выражения в источнике оператора схемы запроса.
|
||
//
|
||
Функция ПолеИсточникаСхемыЗапросаДоступно(ИсточникОператора, ПроверяемоеВыражение)
|
||
|
||
ЧастиИмениПоля = СтрРазделить(ПроверяемоеВыражение, ".");
|
||
ДоступныеПоля = ИсточникОператора.Источник.ДоступныеПоля;
|
||
|
||
ТекущаяЧастьИмениПоля = 0;
|
||
Пока ТекущаяЧастьИмениПоля < ЧастиИмениПоля.Количество() Цикл
|
||
|
||
ТекущееПоле = ДоступныеПоля.Найти(ЧастиИмениПоля.Получить(ТекущаяЧастьИмениПоля));
|
||
|
||
Если ТекущееПоле = Неопределено Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
// Инкрементация следующей части имени поля и соответствующего списка доступности полей.
|
||
ТекущаяЧастьИмениПоля = ТекущаяЧастьИмениПоля + 1;
|
||
ДоступныеПоля = ТекущееПоле.Поля;
|
||
|
||
КонецЦикла;
|
||
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область ЗаменитьСсылки
|
||
|
||
Функция РазметитьМестаИспользования(Знач ПараметрыВыполнения, Знач Ссылка, Знач ЦелеваяСсылка, Знач ТаблицаПоиска)
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
// Устанавливаем порядок известных и проверяем наличие неопознанных объектов.
|
||
Результат = Новый Структура;
|
||
Результат.Вставить("МестаИспользования", ТаблицаПоиска.НайтиСтроки(Новый Структура("Ссылка", Ссылка)));
|
||
Результат.Вставить("ОшибкиРазметки", Новый Массив);
|
||
Результат.Вставить("Успех", Истина);
|
||
|
||
Для Каждого МестоИспользования Из Результат.МестаИспользования Цикл
|
||
Если МестоИспользования.ЭтоСлужебныеДанные Тогда
|
||
Продолжить; // Зависимые данные не обрабатываются.
|
||
КонецЕсли;
|
||
|
||
Информация = ИнформацияОТипе(МестоИспользования.Метаданные, ПараметрыВыполнения);
|
||
Если Информация.Вид = "КОНСТАНТА" Тогда
|
||
МестоИспользования.КлючЗамены = "Константа";
|
||
МестоИспользования.ЦелеваяСсылка = ЦелеваяСсылка;
|
||
|
||
ИначеЕсли Информация.Вид = "ПОСЛЕДОВАТЕЛЬНОСТЬ" Тогда
|
||
МестоИспользования.КлючЗамены = "Последовательность";
|
||
МестоИспользования.ЦелеваяСсылка = ЦелеваяСсылка;
|
||
|
||
ИначеЕсли Информация.Вид = "РЕГИСТРСВЕДЕНИЙ" Тогда
|
||
МестоИспользования.КлючЗамены = "РегистрСведений";
|
||
МестоИспользования.ЦелеваяСсылка = ЦелеваяСсылка;
|
||
|
||
ИначеЕсли Информация.Вид = "РЕГИСТРБУХГАЛТЕРИИ"
|
||
Или Информация.Вид = "РЕГИСТРНАКОПЛЕНИЯ"
|
||
Или Информация.Вид = "РЕГИСТРРАСЧЕТА" Тогда
|
||
МестоИспользования.КлючЗамены = "КлючЗаписи";
|
||
МестоИспользования.ЦелеваяСсылка = ЦелеваяСсылка;
|
||
|
||
ИначеЕсли Информация.Ссылочный Тогда
|
||
МестоИспользования.КлючЗамены = "Объект";
|
||
МестоИспользования.ЦелеваяСсылка = ЦелеваяСсылка;
|
||
|
||
Иначе
|
||
// Неизвестный объект для замены ссылок.
|
||
Результат.Успех = Ложь;
|
||
Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Замена ссылок в ""%1"" недоступна.'"), Информация.ПолноеИмя);
|
||
ОписаниеОшибки = Новый Структура("Объект, Текст", МестоИспользования.Данные, Текст);
|
||
Результат.ОшибкиРазметки.Добавить(ОписаниеОшибки);
|
||
КонецЕсли;
|
||
|
||
КонецЦикла;
|
||
|
||
Возврат Результат;
|
||
КонецФункции
|
||
|
||
// Параметры:
|
||
// ТаблицаПоиска - см. МестаИспользования
|
||
//
|
||
Процедура ЗаменитьСсылкиКороткимиТранзакциями(Результат, Знач ПараметрыВыполнения, Знач Дубль, Знач ТаблицаПоиска)
|
||
|
||
// Основной цикл обработки
|
||
ФильтрСсылок = Новый Структура("Ссылка, КлючЗамены");
|
||
|
||
Результат.ЕстьОшибки = Ложь;
|
||
|
||
ФильтрСсылок.Ссылка = Дубль;
|
||
ФильтрСсылок.КлючЗамены = "Константа";
|
||
|
||
МестаИспользования = ТаблицаПоиска.НайтиСтроки(ФильтрСсылок);
|
||
Для Каждого МестоИспользования Из МестаИспользования Цикл
|
||
ПроизвестиЗаменуВКонстанте(Результат, МестоИспользования, ПараметрыВыполнения);
|
||
КонецЦикла;
|
||
|
||
ФильтрСсылок.КлючЗамены = "Объект";
|
||
МестаИспользования = ТаблицаПоиска.НайтиСтроки(ФильтрСсылок);
|
||
Для Каждого МестоИспользования Из МестаИспользования Цикл
|
||
ПроизвестиЗаменуВОбъекте(Результат, МестоИспользования, ПараметрыВыполнения);
|
||
КонецЦикла;
|
||
|
||
ФильтрСсылок.КлючЗамены = "КлючЗаписи";
|
||
МестаИспользования = ТаблицаПоиска.НайтиСтроки(ФильтрСсылок);
|
||
Для Каждого МестоИспользования Из МестаИспользования Цикл
|
||
ПроизвестиЗаменуВНаборе(Результат, МестоИспользования, ПараметрыВыполнения);
|
||
КонецЦикла;
|
||
|
||
ФильтрСсылок.КлючЗамены = "Последовательность";
|
||
МестаИспользования = ТаблицаПоиска.НайтиСтроки(ФильтрСсылок);
|
||
Для Каждого МестоИспользования Из МестаИспользования Цикл
|
||
ПроизвестиЗаменуВНаборе(Результат, МестоИспользования, ПараметрыВыполнения);
|
||
КонецЦикла;
|
||
|
||
ФильтрСсылок.КлючЗамены = "РегистрСведений";
|
||
МестаИспользования = ТаблицаПоиска.НайтиСтроки(ФильтрСсылок);
|
||
Для Каждого МестоИспользования Из МестаИспользования Цикл
|
||
ПроизвестиЗаменуВРегистреСведений(Результат, МестоИспользования, ПараметрыВыполнения);
|
||
КонецЦикла;
|
||
|
||
ПроизводимыеЗамены = Новый Массив;
|
||
ПроизводимыеЗамены.Добавить(Дубль);
|
||
|
||
Если ПараметрыВыполнения.УдалятьНепосредственно
|
||
ИЛИ ПараметрыВыполнения.ПомечатьНаУдаление Тогда
|
||
|
||
УстановитьПометкуУдаленияДляОбъектов(Результат, ПроизводимыеЗамены, ПараметрыВыполнения);
|
||
Иначе
|
||
|
||
ТаблицаПовторногоПоиска = МестаИспользования(ПроизводимыеЗамены,, ПараметрыВыполнения.ПараметрыПоискаМестИспользования);
|
||
ДобавитьРезультатыЗаменыИзмененныхОбъектов(Результат, ТаблицаПовторногоПоиска);
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ПроизвестиЗаменуВКонстанте(Результат, Знач МестоИспользования, Знач ПараметрыЗаписи)
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
Данные = МестоИспользования.Данные;
|
||
МетаданныеКонстанты = МестоИспользования.Метаданные;
|
||
ПредставлениеДанных = Строка(Данные);
|
||
|
||
Фильтр = Новый Структура("Данные, КлючЗамены", Данные, "Константа");
|
||
ОбрабатываемыеСтроки = МестоИспользования.Владелец().НайтиСтроки(Фильтр); // см. МестаИспользования
|
||
Для Каждого СтрокаТаблицы Из ОбрабатываемыеСтроки Цикл
|
||
СтрокаТаблицы.КлючЗамены = "";
|
||
КонецЦикла;
|
||
|
||
СостояниеОперации = "";
|
||
НачатьТранзакцию();
|
||
|
||
Попытка
|
||
Блокировка = Новый БлокировкаДанных;
|
||
Блокировка.Добавить(МетаданныеКонстанты.ПолноеИмя());
|
||
Попытка
|
||
Блокировка.Заблокировать();
|
||
Исключение
|
||
СостояниеОперации = "ОшибкаБлокировки";
|
||
УточнениеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Не удалось заменить в константе ""%1"", т.к. данные редактируются в другом сеансе работы с приложением.
|
||
|Повторите попытку замены.'"),
|
||
ПредставлениеДанных);
|
||
ИнформацияОбОшибке = ИнформацияОбОшибке();
|
||
Уточнение = ОбщегоНазначенияКлиентСервер.УточнениеИсключения(ИнформацияОбОшибке, УточнениеОшибки);
|
||
ВызватьИсключение(Уточнение.Текст, Уточнение.Категория,,, ИнформацияОбОшибке);
|
||
КонецПопытки;
|
||
|
||
МенеджерКонстанты = Константы[МетаданныеКонстанты.Имя].СоздатьМенеджерЗначения();
|
||
МенеджерКонстанты.Прочитать();
|
||
|
||
ЗаменаПроизведена = Ложь;
|
||
Для Каждого СтрокаТаблицы Из ОбрабатываемыеСтроки Цикл
|
||
Если МенеджерКонстанты.Значение = СтрокаТаблицы.Ссылка Тогда
|
||
МенеджерКонстанты.Значение = СтрокаТаблицы.ЦелеваяСсылка;
|
||
ЗаменаПроизведена = Истина;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если Не ЗаменаПроизведена Тогда
|
||
ОтменитьТранзакцию();
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
// Пытаемся сохранить
|
||
Если Не ПараметрыЗаписи.ПривилегированнаяЗапись Тогда
|
||
УстановитьПривилегированныйРежим(Ложь);
|
||
КонецЕсли;
|
||
|
||
Попытка
|
||
ЗаписатьОбъект(МенеджерКонстанты, ПараметрыЗаписи);
|
||
Исключение
|
||
СостояниеОперации = "ОшибкаЗаписи";
|
||
ИнформацияОбОшибке = ИнформацияОбОшибке();
|
||
Уточнение = ОбщегоНазначенияКлиентСервер.УточнениеИсключения(ИнформацияОбОшибке,
|
||
НСтр("ru = 'Не удалось заменить по причине:'"));
|
||
ВызватьИсключение(Уточнение.Текст, Уточнение.Категория,,, ИнформацияОбОшибке);
|
||
КонецПопытки;
|
||
|
||
Если Не ПараметрыЗаписи.ПривилегированнаяЗапись Тогда
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
КонецЕсли;
|
||
|
||
ЗафиксироватьТранзакцию();
|
||
Исключение
|
||
ОтменитьТранзакцию();
|
||
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииЗаменыСсылок(), УровеньЖурналаРегистрации.Ошибка,
|
||
МетаданныеКонстанты,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
|
||
Если СостояниеОперации = "ОшибкаЗаписи" Тогда
|
||
Для Каждого СтрокаТаблицы Из ОбрабатываемыеСтроки Цикл
|
||
ЗарегистрироватьОшибкуЗамены(Результат, СтрокаТаблицы.Ссылка,
|
||
ОписаниеОшибкиЗамены("ОшибкаЗаписи", Данные, ПредставлениеДанных, ИнформацияОбОшибке()));
|
||
КонецЦикла;
|
||
Иначе
|
||
ЗарегистрироватьОшибкуЗамены(Результат, СтрокаТаблицы.Ссылка,
|
||
ОписаниеОшибкиЗамены(СостояниеОперации, Данные, ПредставлениеДанных, ИнформацияОбОшибке()));
|
||
КонецЕсли;
|
||
КонецПопытки;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ПроизвестиЗаменуВОбъекте(Результат, Знач МестоИспользования, Знач ПараметрыВыполнения)
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
Данные = МестоИспользования.Данные;
|
||
|
||
// Будем производить сразу все замены для этих данных.
|
||
Фильтр = Новый Структура("Данные, КлючЗамены", Данные, "Объект");
|
||
ОбрабатываемыеСтроки = МестоИспользования.Владелец().НайтиСтроки(Фильтр); // см. МестаИспользования
|
||
|
||
ПредставлениеДанных = ПредметСтрокой(Данные);
|
||
СостояниеОперации = "";
|
||
НачатьТранзакцию();
|
||
|
||
Попытка
|
||
|
||
Блокировка = Новый БлокировкаДанных;
|
||
ЗаблокироватьМестоИспользования(ПараметрыВыполнения, Блокировка, МестоИспользования);
|
||
Попытка
|
||
Блокировка.Заблокировать();
|
||
Исключение
|
||
СостояниеОперации = "ОшибкаБлокировки";
|
||
УточнениеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Не удалось заменить в ""%1"", т.к. данные редактируются в другом сеансе работы с приложением.
|
||
|Повторите попытку замены.'"),
|
||
ПредставлениеДанных);
|
||
ИнформацияОбОшибке = ИнформацияОбОшибке();
|
||
Уточнение = ОбщегоНазначенияКлиентСервер.УточнениеИсключения(ИнформацияОбОшибке, УточнениеОшибки);
|
||
ВызватьИсключение(Уточнение.Текст, Уточнение.Категория,,, ИнформацияОбОшибке);
|
||
КонецПопытки;
|
||
|
||
ОбъектыЗаписи = ИзмененныеОбъектыПриЗаменеВОбъекте(ПараметрыВыполнения, МестоИспользования, ОбрабатываемыеСтроки);
|
||
|
||
// Пытаемся сохранить, сам объект идет последним.
|
||
Если Не ПараметрыВыполнения.ПривилегированнаяЗапись Тогда
|
||
УстановитьПривилегированныйРежим(Ложь);
|
||
КонецЕсли;
|
||
|
||
Попытка
|
||
Если ПараметрыВыполнения.ВключатьБизнесЛогику Тогда
|
||
// Первая запись без контроля, чтобы устранить циклические ссылки.
|
||
НовыеПараметрыВыполнения = СкопироватьРекурсивно(ПараметрыВыполнения);
|
||
НовыеПараметрыВыполнения.ВключатьБизнесЛогику = Ложь;
|
||
Для Каждого КлючЗначение Из ОбъектыЗаписи Цикл
|
||
ЗаписатьОбъект(КлючЗначение.Ключ, НовыеПараметрыВыполнения);
|
||
КонецЦикла;
|
||
// Вторая запись c контролем.
|
||
НовыеПараметрыВыполнения.ВключатьБизнесЛогику = Истина;
|
||
Для Каждого КлючЗначение Из ОбъектыЗаписи Цикл
|
||
ЗаписатьОбъект(КлючЗначение.Ключ, НовыеПараметрыВыполнения);
|
||
КонецЦикла;
|
||
Иначе
|
||
// Запись без контроля бизнес-логики.
|
||
Для Каждого КлючЗначение Из ОбъектыЗаписи Цикл
|
||
ЗаписатьОбъект(КлючЗначение.Ключ, ПараметрыВыполнения);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
Исключение
|
||
СостояниеОперации = "ОшибкаЗаписи";
|
||
ИнформацияОбОшибке = ИнформацияОбОшибке();
|
||
Уточнение = ОбщегоНазначенияКлиентСервер.УточнениеИсключения(ИнформацияОбОшибке,
|
||
НСтр("ru = 'Не удалось заменить по причине:'"));
|
||
ВызватьИсключение(Уточнение.Текст, Уточнение.Категория,,, ИнформацияОбОшибке);
|
||
КонецПопытки;
|
||
|
||
ЗафиксироватьТранзакцию();
|
||
|
||
Исключение
|
||
ОтменитьТранзакцию();
|
||
Информация = ИнформацияОбОшибке();
|
||
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииЗаменыСсылок(), УровеньЖурналаРегистрации.Ошибка,
|
||
МестоИспользования.Метаданные,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(Информация));
|
||
Ошибка = ОписаниеОшибкиЗамены(СостояниеОперации, Данные, ПредставлениеДанных, ИнформацияОбОшибке());
|
||
Если СостояниеОперации = "ОшибкаЗаписи" Тогда
|
||
Для Каждого СтрокаТаблицы Из ОбрабатываемыеСтроки Цикл
|
||
ЗарегистрироватьОшибкуЗамены(Результат, СтрокаТаблицы.Ссылка, Ошибка);
|
||
КонецЦикла;
|
||
Иначе
|
||
ЗарегистрироватьОшибкуЗамены(Результат, МестоИспользования.Ссылка, Ошибка);
|
||
КонецЕсли;
|
||
КонецПопытки;
|
||
|
||
// Помечаем как обработанные
|
||
Для Каждого СтрокаТаблицы Из ОбрабатываемыеСтроки Цикл
|
||
СтрокаТаблицы.КлючЗамены = "";
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ПроизвестиЗаменуВНаборе(Результат, Знач МестоИспользования, Знач ПараметрыВыполнения)
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
Данные = МестоИспользования.Данные;
|
||
МетаданныеРегистра = МестоИспользования.Метаданные;
|
||
ПредставлениеДанных = Строка(Данные);
|
||
|
||
// Будем производить сразу все замены для этих данных.
|
||
Фильтр = Новый Структура("Данные, КлючЗамены");
|
||
ЗаполнитьЗначенияСвойств(Фильтр, МестоИспользования);
|
||
ОбрабатываемыеСтроки = МестоИспользования.Владелец().НайтиСтроки(Фильтр); // см. МестаИспользования
|
||
|
||
ОписаниеНабора = ОписаниеКлючаЗаписи(МетаданныеРегистра);
|
||
НаборЗаписей = ОписаниеНабора.НаборЗаписей; // РегистрСведенийНаборЗаписей
|
||
|
||
ПарыЗамен = Новый Соответствие;
|
||
Для Каждого СтрокаТаблицы Из ОбрабатываемыеСтроки Цикл
|
||
ПарыЗамен.Вставить(СтрокаТаблицы.Ссылка, СтрокаТаблицы.ЦелеваяСсылка);
|
||
КонецЦикла;
|
||
|
||
// Помечаем как обработанные
|
||
Для Каждого СтрокаТаблицы Из ОбрабатываемыеСтроки Цикл
|
||
СтрокаТаблицы.КлючЗамены = "";
|
||
КонецЦикла;
|
||
|
||
СостояниеОперации = "";
|
||
НачатьТранзакцию();
|
||
|
||
Попытка
|
||
|
||
// Блокировка и подготовка набора.
|
||
Блокировка = Новый БлокировкаДанных;
|
||
Для Каждого КлючЗначение Из ОписаниеНабора.СписокИзмерений Цикл
|
||
ТипИзмерения = КлючЗначение.Значение;
|
||
Имя = КлючЗначение.Ключ;
|
||
Значение = Данные[Имя];
|
||
|
||
Для Каждого СтрокаТаблицы Из ОбрабатываемыеСтроки Цикл
|
||
ТекущаяСсылка = СтрокаТаблицы.Ссылка;
|
||
Если ТипИзмерения.СодержитТип(ТипЗнч(ТекущаяСсылка)) Тогда
|
||
Блокировка.Добавить(ОписаниеНабора.ПространствоБлокировки).УстановитьЗначение(Имя, ТекущаяСсылка);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
НаборЗаписей.Отбор[Имя].Установить(Значение);
|
||
КонецЦикла;
|
||
|
||
Попытка
|
||
Блокировка.Заблокировать();
|
||
Исключение
|
||
СостояниеОперации = "ОшибкаБлокировки";
|
||
УточнениеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Не удалось заменить в регистре ""%1"", т.к. данные редактируются в другом сеансе работы с приложением.
|
||
|Повторите попытку замены.'"),
|
||
ПредставлениеДанных);
|
||
ИнформацияОбОшибке = ИнформацияОбОшибке();
|
||
Уточнение = ОбщегоНазначенияКлиентСервер.УточнениеИсключения(ИнформацияОбОшибке, УточнениеОшибки);
|
||
ВызватьИсключение(Уточнение.Текст, Уточнение.Категория,,, ИнформацияОбОшибке);
|
||
КонецПопытки;
|
||
|
||
НаборЗаписей.Прочитать();
|
||
ЗаменитьВКоллекцииСтрок("НаборЗаписей", "НаборЗаписей", НаборЗаписей, НаборЗаписей, ОписаниеНабора.СписокПолей, ПарыЗамен);
|
||
|
||
Если НаборЗаписей.Модифицированность() Тогда
|
||
ОтменитьТранзакцию();
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
Если Не ПараметрыВыполнения.ПривилегированнаяЗапись Тогда
|
||
УстановитьПривилегированныйРежим(Ложь);
|
||
КонецЕсли;
|
||
|
||
Попытка
|
||
ЗаписатьОбъект(НаборЗаписей, ПараметрыВыполнения);
|
||
Исключение
|
||
СостояниеОперации = "ОшибкаЗаписи";
|
||
ИнформацияОбОшибке = ИнформацияОбОшибке();
|
||
Уточнение = ОбщегоНазначенияКлиентСервер.УточнениеИсключения(ИнформацияОбОшибке,
|
||
НСтр("ru = 'Не удалось заменить по причине:'"));
|
||
ВызватьИсключение(Уточнение.Текст, Уточнение.Категория,,, ИнформацияОбОшибке);
|
||
КонецПопытки;
|
||
|
||
Если Не ПараметрыВыполнения.ПривилегированнаяЗапись Тогда
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
КонецЕсли;
|
||
|
||
ЗафиксироватьТранзакцию();
|
||
|
||
Исключение
|
||
ОтменитьТранзакцию();
|
||
Информация = ИнформацияОбОшибке();
|
||
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииЗаменыСсылок(), УровеньЖурналаРегистрации.Ошибка,
|
||
МетаданныеРегистра,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(Информация));
|
||
Ошибка = ОписаниеОшибкиЗамены(СостояниеОперации, Данные, ПредставлениеДанных, ИнформацияОбОшибке());
|
||
Если СостояниеОперации = "ОшибкаЗаписи" Тогда
|
||
Для Каждого СтрокаТаблицы Из ОбрабатываемыеСтроки Цикл
|
||
ЗарегистрироватьОшибкуЗамены(Результат, СтрокаТаблицы.Ссылка, Ошибка);
|
||
КонецЦикла;
|
||
Иначе
|
||
ЗарегистрироватьОшибкуЗамены(Результат, МестоИспользования.Ссылка, Ошибка);
|
||
КонецЕсли;
|
||
КонецПопытки;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ПроизвестиЗаменуВРегистреСведений(Результат, Знач МестоИспользования, Знач ПараметрыВыполнения)
|
||
|
||
Если МестоИспользования.Обработано Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
МестоИспользования.Обработано = Истина;
|
||
|
||
// В случае, если дубль указан в измерениях набора, тогда используется 2 набора записей:
|
||
// НаборЗаписейДубля - чтение старых значений (по старым измерениям) и удаление старых значений.
|
||
// НаборЗаписейОригинала - чтение актуальных значений (по новым измерениям) и запись новых значений.
|
||
// Данные дублей и оригиналов объединяются по правилам:
|
||
// Приоритет у данных оригинала.
|
||
// Если в оригинале нет данных, то берутся данные из дубля.
|
||
// Набор оригинала записывается, а набор дубля удаляется.
|
||
//
|
||
// В случае, если дубль не указан в измерениях набора, тогда используется 1 набор записей:
|
||
// НаборЗаписейДубля - чтение старых значений и запись новых значений.
|
||
//
|
||
// Замена ссылок в ресурсах и реквизитах производится в обоих случаях.
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
Дубль = МестоИспользования.Ссылка;
|
||
Оригинал = МестоИспользования.ЦелеваяСсылка;
|
||
|
||
МетаданныеРегистра = МестоИспользования.Метаданные;
|
||
КлючЗаписиРегистра = МестоИспользования.Данные;
|
||
|
||
Информация = ИнформацияОТипе(МетаданныеРегистра, ПараметрыВыполнения);
|
||
|
||
ТребуетсяДваНабора = Ложь;
|
||
Для Каждого КлючЗначение Из Информация.Измерения Цикл
|
||
ЗначениеИзмеренияДубля = КлючЗаписиРегистра[КлючЗначение.Ключ];
|
||
Если ЗначениеИзмеренияДубля = Дубль
|
||
Или ПараметрыВыполнения.УспешныеЗамены[ЗначениеИзмеренияДубля] = Дубль Тогда
|
||
ТребуетсяДваНабора = Истина; // Дубль указан в измерениях.
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Менеджер = МенеджерОбъектаПоПолномуИмени(Информация.ПолноеИмя);
|
||
НаборЗаписейДубля = Менеджер.СоздатьНаборЗаписей();
|
||
|
||
Если ТребуетсяДваНабора Тогда
|
||
ЗначенияИзмеренийОригинала = Новый Структура;
|
||
НаборЗаписейОригинала = Менеджер.СоздатьНаборЗаписей();
|
||
КонецЕсли;
|
||
|
||
НачатьТранзакцию();
|
||
|
||
Попытка
|
||
Блокировка = Новый БлокировкаДанных;
|
||
БлокировкаДубля = Блокировка.Добавить(Информация.ПолноеИмя);
|
||
Если ТребуетсяДваНабора Тогда
|
||
БлокировкаОригинала = Блокировка.Добавить(Информация.ПолноеИмя);
|
||
КонецЕсли;
|
||
|
||
Для Каждого КлючЗначение Из Информация.Измерения Цикл
|
||
ЗначениеИзмеренияДубля = КлючЗаписиРегистра[КлючЗначение.Ключ];
|
||
|
||
// Для решения проблемы уникальности
|
||
// выполняется замена старых значений измерений ключа записи на актуальные.
|
||
// Соответствие старых и актуальных обеспечивает соответствием УспешныеЗамены.
|
||
// Данные соответствия актуальны на текущий момент времени,
|
||
// т.к. пополняются только после успешной обработки очередной пары и фиксации транзакции.
|
||
НовоеЗначениеИзмеренияДубля = ПараметрыВыполнения.УспешныеЗамены[ЗначениеИзмеренияДубля];
|
||
Если НовоеЗначениеИзмеренияДубля <> Неопределено Тогда
|
||
ЗначениеИзмеренияДубля = НовоеЗначениеИзмеренияДубля;
|
||
КонецЕсли;
|
||
|
||
НаборЗаписейДубля.Отбор[КлючЗначение.Ключ].Установить(ЗначениеИзмеренияДубля);
|
||
|
||
// Замена в конкретной паре и блокировка на конкретную замену.
|
||
БлокировкаДубля.УстановитьЗначение(КлючЗначение.Ключ, ЗначениеИзмеренияДубля);
|
||
|
||
|
||
Если ТребуетсяДваНабора Тогда
|
||
Если ЗначениеИзмеренияДубля = Дубль Тогда
|
||
ЗначениеИзмеренияОригинала = Оригинал;
|
||
Иначе
|
||
ЗначениеИзмеренияОригинала = ЗначениеИзмеренияДубля;
|
||
КонецЕсли;
|
||
|
||
НаборЗаписейОригинала.Отбор[КлючЗначение.Ключ].Установить(ЗначениеИзмеренияОригинала);
|
||
ЗначенияИзмеренийОригинала.Вставить(КлючЗначение.Ключ, ЗначениеИзмеренияОригинала);
|
||
|
||
// Замена в конкретной паре и блокировка на конкретную замену.
|
||
БлокировкаОригинала.УстановитьЗначение(КлючЗначение.Ключ, ЗначениеИзмеренияОригинала);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Блокировка.Заблокировать();
|
||
|
||
НаборЗаписейДубля.Прочитать();
|
||
Если НаборЗаписейДубля.Количество() = 0 Тогда
|
||
ОтменитьТранзакцию();
|
||
Возврат;
|
||
КонецЕсли;
|
||
ЗаписьДубля = НаборЗаписейДубля[0];
|
||
|
||
Если ТребуетсяДваНабора Тогда
|
||
// Пишем в набор с другими измерениями.
|
||
НаборЗаписейОригинала.Прочитать();
|
||
Если НаборЗаписейОригинала.Количество() = 0 Тогда
|
||
ЗаписьОригинала = НаборЗаписейОригинала.Добавить();
|
||
ЗаполнитьЗначенияСвойств(ЗаписьОригинала, ЗаписьДубля);
|
||
ЗаполнитьЗначенияСвойств(ЗаписьОригинала, ЗначенияИзмеренийОригинала);
|
||
Иначе
|
||
ЗаписьОригинала = НаборЗаписейОригинала[0];
|
||
КонецЕсли;
|
||
Иначе
|
||
// Пишем туда же, откуда и читаем.
|
||
НаборЗаписейОригинала = НаборЗаписейДубля;
|
||
ЗаписьОригинала = ЗаписьДубля; // Ситуация с нулевым количеством записей в наборе обработана выше.
|
||
КонецЕсли;
|
||
|
||
// Замена дубля на оригинал в ресурсах и реквизитах.
|
||
Для Каждого КлючЗначение Из Информация.Ресурсы Цикл
|
||
ЗначениеРеквизитаВОригинале = ЗаписьОригинала[КлючЗначение.Ключ];
|
||
Если ЗначениеРеквизитаВОригинале = Дубль Тогда
|
||
ЗаписьОригинала[КлючЗначение.Ключ] = Оригинал;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Для Каждого КлючЗначение Из Информация.Реквизиты Цикл
|
||
ЗначениеРеквизитаВОригинале = ЗаписьОригинала[КлючЗначение.Ключ];
|
||
Если ЗначениеРеквизитаВОригинале = Дубль Тогда
|
||
ЗаписьОригинала[КлючЗначение.Ключ] = Оригинал;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если Не ПараметрыВыполнения.ПривилегированнаяЗапись Тогда
|
||
УстановитьПривилегированныйРежим(Ложь);
|
||
КонецЕсли;
|
||
|
||
// Удаление данных дубля.
|
||
Если ТребуетсяДваНабора Тогда
|
||
НаборЗаписейДубля.Очистить();
|
||
ЗаписатьОбъект(НаборЗаписейДубля, ПараметрыВыполнения);
|
||
КонецЕсли;
|
||
|
||
// Запись данных оригинала.
|
||
Если НаборЗаписейОригинала.Модифицированность() Тогда
|
||
ЗаписатьОбъект(НаборЗаписейОригинала, ПараметрыВыполнения);
|
||
КонецЕсли;
|
||
|
||
ЗафиксироватьТранзакцию();
|
||
Исключение
|
||
ОтменитьТранзакцию();
|
||
ЗарегистрироватьОшибкуВТаблицу(Результат, Дубль, Оригинал, КлючЗаписиРегистра, Информация,
|
||
"БлокировкаДляРегистра", ИнформацияОбОшибке());
|
||
КонецПопытки
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция ИзмененныеОбъектыПриЗаменеВОбъекте(ПараметрыВыполнения, МестоИспользования, ОбрабатываемыеСтроки)
|
||
Данные = МестоИспользования.Данные;
|
||
ОписаниеПоследовательностей = ОписаниеПоследовательностей(МестоИспользования.Метаданные);
|
||
ОписаниеДвижений = ОписаниеДвижений(МестоИспользования.Метаданные);
|
||
ОписаниеЗадач = ОписаниеЗадач(МестоИспользования.Метаданные);
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
// Возвращаем измененные обработанные объекты.
|
||
Измененные = Новый Соответствие;
|
||
|
||
// Считываем
|
||
Описание = ОписаниеОбъекта(Данные.Метаданные());
|
||
Попытка
|
||
Объект = Данные.ПолучитьОбъект();
|
||
Исключение
|
||
// Был уже обработан с ошибками.
|
||
Объект = Неопределено;
|
||
КонецПопытки;
|
||
|
||
Если Объект = Неопределено Тогда
|
||
Возврат Измененные;
|
||
КонецЕсли;
|
||
|
||
Для Каждого ОписаниеДвижения Из ОписаниеДвижений Цикл
|
||
ОписаниеДвижения.НаборЗаписей.Отбор.Регистратор.Установить(Данные);
|
||
ОписаниеДвижения.НаборЗаписей.Прочитать();
|
||
КонецЦикла;
|
||
|
||
Для Каждого ОписаниеПоследовательности Из ОписаниеПоследовательностей Цикл
|
||
ОписаниеПоследовательности.НаборЗаписей.Отбор.Регистратор.Установить(Данные);
|
||
ОписаниеПоследовательности.НаборЗаписей.Прочитать();
|
||
КонецЦикла;
|
||
|
||
// Заменяем сразу все варианты.
|
||
ПарыЗамен = Новый Соответствие;
|
||
Для Каждого МестоИспользования Из ОбрабатываемыеСтроки Цикл
|
||
ПарыЗамен.Вставить(МестоИспользования.Ссылка, МестоИспользования.ЦелеваяСсылка);
|
||
КонецЦикла;
|
||
|
||
ВыполнитьЗаменуВРеквизитахОбъекта(Объект, Описание, ПарыЗамен);
|
||
|
||
// Движения
|
||
Для Каждого ОписаниеДвижения Из ОписаниеДвижений Цикл
|
||
ЗаменитьВКоллекцииСтрок(
|
||
"Движения",
|
||
ОписаниеДвижения.ПространствоБлокировки,
|
||
ОписаниеДвижения.НаборЗаписей,
|
||
ОписаниеДвижения.НаборЗаписей,
|
||
ОписаниеДвижения.СписокПолей,
|
||
ПарыЗамен);
|
||
КонецЦикла;
|
||
|
||
// Последовательности
|
||
Для Каждого ОписаниеПоследовательности Из ОписаниеПоследовательностей Цикл
|
||
ЗаменитьВКоллекцииСтрок(
|
||
"Последовательности",
|
||
ОписаниеПоследовательности.ПространствоБлокировки,
|
||
ОписаниеПоследовательности.НаборЗаписей,
|
||
ОписаниеПоследовательности.НаборЗаписей,
|
||
ОписаниеПоследовательности.СписокПолей,
|
||
ПарыЗамен);
|
||
КонецЦикла;
|
||
|
||
Для Каждого ОписаниеДвижения Из ОписаниеДвижений Цикл
|
||
Если ОписаниеДвижения.НаборЗаписей.Модифицированность() Тогда
|
||
Измененные.Вставить(ОписаниеДвижения.НаборЗаписей, Ложь);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Для Каждого ОписаниеПоследовательности Из ОписаниеПоследовательностей Цикл
|
||
Если ОписаниеПоследовательности.НаборЗаписей.Модифицированность() Тогда
|
||
Измененные.Вставить(ОписаниеПоследовательности.НаборЗаписей, Ложь);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если ОписаниеЗадач <> Неопределено Тогда
|
||
|
||
ЗадачаПроцесса = ЗадачиПроцесса(Данные, ОписаниеЗадач.ПространствоБлокировки);
|
||
Пока ЗадачаПроцесса.Следующий() Цикл
|
||
|
||
ЗадачаОбъект = ЗадачаПроцесса.Ссылка.ПолучитьОбъект();
|
||
Фильтр = Новый Структура("Данные, КлючЗамены", ЗадачаПроцесса.Ссылка, "Объект");
|
||
ОбрабатываемыеСтрокиЗадачи = МестоИспользования.Владелец().НайтиСтроки(Фильтр); // см. МестаИспользования
|
||
Для каждого МестоИспользованияЗадачи Из ОбрабатываемыеСтрокиЗадачи Цикл
|
||
ПарыЗамен.Вставить(МестоИспользованияЗадачи.Ссылка, МестоИспользованияЗадачи.ЦелеваяСсылка);
|
||
КонецЦикла;
|
||
ВыполнитьЗаменуВРеквизитахОбъекта(ЗадачаОбъект, ОписаниеЗадач, ПарыЗамен);
|
||
|
||
Если ЗадачаОбъект.Модифицированность() Тогда
|
||
Измененные.Вставить(ЗадачаОбъект, Ложь);
|
||
КонецЕсли;
|
||
|
||
КонецЦикла;
|
||
|
||
КонецЕсли;
|
||
|
||
// Сам объект последний - для возможного перепроведения.
|
||
Если Объект.Модифицированность() Тогда
|
||
Измененные.Вставить(Объект, Описание.МожетБытьПроведен);
|
||
КонецЕсли;
|
||
|
||
Возврат Измененные;
|
||
КонецФункции
|
||
|
||
Функция ЗадачиПроцесса(БизнесПроцесс, ТипЗадач)
|
||
|
||
ТекстЗапроса = "ВЫБРАТЬ
|
||
| ИмяТаблицы.Ссылка
|
||
|ИЗ
|
||
| &ИмяТаблицы КАК ИмяТаблицы
|
||
|ГДЕ
|
||
| ИмяТаблицы.БизнесПроцесс = &БизнесПроцесс";
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ИмяТаблицы", ТипЗадач);
|
||
Запрос = Новый Запрос(ТекстЗапроса);
|
||
Запрос.УстановитьПараметр("БизнесПроцесс", БизнесПроцесс);
|
||
Возврат Запрос.Выполнить().Выбрать();
|
||
|
||
КонецФункции
|
||
|
||
Процедура ВыполнитьЗаменуВРеквизитахОбъекта(Объект, Описание, ПарыЗамен)
|
||
|
||
// Реквизиты
|
||
Для Каждого КлючЗначение Из Описание.Реквизиты Цикл
|
||
Имя = КлючЗначение.Ключ;
|
||
ЦелеваяСсылка = ПарыЗамен[ Объект[Имя] ];
|
||
Если ЦелеваяСсылка <> Неопределено Тогда
|
||
ЗарегистрироватьФактЗамены(Объект, Объект[Имя], ЦелеваяСсылка, "Реквизиты", Имя);
|
||
Объект[Имя] = ЦелеваяСсылка;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
// Стандартные реквизиты
|
||
Для Каждого КлючЗначение Из Описание.СтандартныеРеквизиты Цикл
|
||
Имя = КлючЗначение.Ключ;
|
||
ЦелеваяСсылка = ПарыЗамен[ Объект[Имя] ];
|
||
Если ЦелеваяСсылка <> Неопределено Тогда
|
||
ЗарегистрироватьФактЗамены(Объект, Объект[Имя], ЦелеваяСсылка, "СтандартныеРеквизиты", Имя);
|
||
Объект[Имя] = ЦелеваяСсылка;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
// Табличные части
|
||
Для Каждого Элемент Из Описание.ТабличныеЧасти Цикл
|
||
ЗаменитьВКоллекцииСтрок(
|
||
"ТабличныеЧасти",
|
||
Элемент.Имя,
|
||
Объект,
|
||
Объект[Элемент.Имя],
|
||
Элемент.СписокПолей,
|
||
ПарыЗамен);
|
||
КонецЦикла;
|
||
|
||
// Стандартные табличные части.
|
||
Для Каждого Элемент Из Описание.СтандартныеТабличныеЧасти Цикл
|
||
ЗаменитьВКоллекцииСтрок(
|
||
"СтандартныеТабличныеЧасти",
|
||
Элемент.Имя,
|
||
Объект,
|
||
Объект[Элемент.Имя],
|
||
Элемент.СписокПолей,
|
||
ПарыЗамен);
|
||
КонецЦикла;
|
||
|
||
Для Каждого Реквизит Из Описание.РеквизитыАдресации Цикл
|
||
Имя = Реквизит.Ключ;
|
||
ЦелеваяСсылка = ПарыЗамен[ Объект[Имя] ];
|
||
Если ЦелеваяСсылка <> Неопределено Тогда
|
||
ЗарегистрироватьФактЗамены(Объект, Объект[Имя], ЦелеваяСсылка, "РеквизитыАдресации", Имя);
|
||
Объект[Имя] = ЦелеваяСсылка;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ЗарегистрироватьФактЗамены(Объект, СсылкаДубля, СсылкаОригинала, ВидРеквизита, ИмяРеквизита,
|
||
Индекс = Неопределено, ИмяКолонки = Неопределено)
|
||
|
||
ЕстьДополнительныеСвойства = Новый Структура("ДополнительныеСвойства");
|
||
ЗаполнитьЗначенияСвойств(ЕстьДополнительныеСвойства, Объект);
|
||
Если ТипЗнч(ЕстьДополнительныеСвойства.ДополнительныеСвойства) <> Тип("Структура") Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
ДополнительныеСвойства = Объект.ДополнительныеСвойства;
|
||
ДополнительныеСвойства.Вставить("ЗаменаСсылок", Истина);
|
||
ВыполненныеЗамены = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ДополнительныеСвойства, "ВыполненныеЗамены");
|
||
Если ВыполненныеЗамены = Неопределено Тогда
|
||
ВыполненныеЗамены = Новый Массив;
|
||
ДополнительныеСвойства.Вставить("ВыполненныеЗамены", ВыполненныеЗамены);
|
||
КонецЕсли;
|
||
|
||
ОписаниеЗамены = Новый Структура;
|
||
ОписаниеЗамены.Вставить("СсылкаДубля", СсылкаДубля);
|
||
ОписаниеЗамены.Вставить("СсылкаОригинала", СсылкаОригинала);
|
||
ОписаниеЗамены.Вставить("ВидРеквизита", ВидРеквизита);
|
||
ОписаниеЗамены.Вставить("ИмяРеквизита", ИмяРеквизита);
|
||
ОписаниеЗамены.Вставить("Индекс", Индекс);
|
||
ОписаниеЗамены.Вставить("ИмяКолонки", ИмяКолонки);
|
||
ВыполненныеЗамены.Добавить(ОписаниеЗамены);
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура УстановитьПометкуУдаленияДляОбъектов(Результат, Знач УдаляемыеСсылки, Знач ПараметрыВыполнения)
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
ЕстьВнешняяТранзакция = ТранзакцияАктивна();
|
||
ВсеМестаИспользования = МестаИспользования(УдаляемыеСсылки,,ПараметрыВыполнения.ПараметрыПоискаМестИспользования);
|
||
Для Каждого УдаляемаяСсылка Из УдаляемыеСсылки Цикл
|
||
Информация = ИнформацияОТипе(ТипЗнч(УдаляемаяСсылка), ПараметрыВыполнения);
|
||
Блокировка = Новый БлокировкаДанных;
|
||
Блокировка.Добавить(Информация.ПолноеИмя).УстановитьЗначение("Ссылка", УдаляемаяСсылка);
|
||
|
||
НачатьТранзакцию();
|
||
Попытка
|
||
ЭтоОшибкаБлокировки = Истина;
|
||
Блокировка.Заблокировать();
|
||
|
||
ЭтоОшибкаБлокировки = Ложь;
|
||
Успешно = УстановитьПометкуУдаления(Результат, УдаляемаяСсылка, ВсеМестаИспользования,
|
||
ПараметрыВыполнения, ЕстьВнешняяТранзакция);
|
||
Если Не Успешно Тогда
|
||
ОтменитьТранзакцию();
|
||
Продолжить;
|
||
КонецЕсли;
|
||
ЗафиксироватьТранзакцию();
|
||
Исключение
|
||
ОтменитьТранзакцию();
|
||
Если ЭтоОшибкаБлокировки Тогда
|
||
ЗарегистрироватьОшибкуВТаблицу(Результат, УдаляемаяСсылка, Неопределено, УдаляемаяСсылка, Информация,
|
||
"БлокировкаДляУдаленияДубля", ИнформацияОбОшибке());
|
||
КонецЕсли;
|
||
Если ЕстьВнешняяТранзакция Тогда
|
||
ВызватьИсключение;
|
||
КонецЕсли;
|
||
КонецПопытки;
|
||
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция УстановитьПометкуУдаления(Результат, Знач УдаляемаяСсылка, Знач ВсеМестаИспользования, Знач ПараметрыВыполнения,
|
||
ЕстьВнешняяТранзакция)
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
|
||
ПредставлениеСсылки = ПредметСтрокой(УдаляемаяСсылка);
|
||
Фильтр = Новый Структура("Ссылка");
|
||
Фильтр.Ссылка = УдаляемаяСсылка;
|
||
МестаИспользования = ВсеМестаИспользования.НайтиСтроки(Фильтр);
|
||
|
||
Индекс = МестаИспользования.ВГраница();
|
||
Пока Индекс >= 0 Цикл
|
||
Если МестаИспользования[Индекс].ВспомогательныеДанные Тогда
|
||
МестаИспользования.Удалить(Индекс);
|
||
КонецЕсли;
|
||
Индекс = Индекс - 1;
|
||
КонецЦикла;
|
||
|
||
Если МестаИспользования.Количество() > 0 Тогда
|
||
ДобавитьРезультатыЗаменыИзмененныхОбъектов(Результат, МестаИспользования);
|
||
Возврат Ложь; // Остались места использования, нельзя удалять.
|
||
КонецЕсли;
|
||
|
||
Объект = УдаляемаяСсылка.ПолучитьОбъект(); // ДокументОбъект, СправочникОбъект
|
||
Если Объект = Неопределено Тогда
|
||
Возврат Ложь; // Уже удален.
|
||
КонецЕсли;
|
||
|
||
Если Не ПараметрыВыполнения.ПривилегированнаяЗапись Тогда
|
||
УстановитьПривилегированныйРежим(Ложь);
|
||
КонецЕсли;
|
||
|
||
Успешно = Истина;
|
||
Попытка
|
||
ЗаписатьОбъектСПерехватомСообщений(Объект, "ПометкаУдаления", Неопределено, ПараметрыВыполнения);
|
||
Результат.ОчередьКНепосредственномуУдалению.Добавить(Объект.Ссылка);
|
||
Исключение
|
||
Успешно = Ложь;
|
||
ИнформацияОбОшибке = ИнформацияОбОшибке();
|
||
Уточнение = ОбщегоНазначенияКлиентСервер.УточнениеИсключения(ИнформацияОбОшибке,
|
||
НСтр("ru = 'Элемент не был помечен на удаление по причине:'"));
|
||
Попытка
|
||
ВызватьИсключение(Уточнение.Текст, Уточнение.Категория,,, ИнформацияОбОшибке);
|
||
Исключение
|
||
ОписаниеОшибки = ОписаниеОшибкиЗамены("ОшибкаУдаления", УдаляемаяСсылка, ПредставлениеСсылки, ИнформацияОбОшибке());
|
||
ЗарегистрироватьОшибкуЗамены(Результат, УдаляемаяСсылка, ОписаниеОшибки);
|
||
Если ЕстьВнешняяТранзакция Тогда
|
||
ВызватьИсключение;
|
||
КонецЕсли;
|
||
КонецПопытки;
|
||
КонецПопытки;
|
||
|
||
Возврат Успешно;
|
||
|
||
КонецФункции
|
||
|
||
Процедура ДобавитьРезультатыЗаменыИзмененныхОбъектов(Результат, ТаблицаПовторногоПоиска)
|
||
|
||
Фильтр = Новый Структура("Ссылка, ОбъектОшибки");
|
||
Для Каждого СтрокаТаблицы Из ТаблицаПовторногоПоиска Цикл
|
||
Тест = Новый Структура("ВспомогательныеДанные", Ложь);
|
||
ЗаполнитьЗначенияСвойств(Тест, СтрокаТаблицы);
|
||
Если Тест.ВспомогательныеДанные Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
|
||
Фильтр.ОбъектОшибки = СтрокаТаблицы.Данные;
|
||
Фильтр.Ссылка = СтрокаТаблицы.Ссылка;
|
||
Если Результат.Ошибки.НайтиСтроки(Фильтр).Количество() > 0 Тогда
|
||
Продолжить; // По данной проблеме уже записана ошибка.
|
||
КонецЕсли;
|
||
|
||
ЗарегистрироватьОшибкуЗамены(Результат, СтрокаТаблицы.Ссылка,
|
||
ОписаниеОшибкиЗамены("ДанныеИзменены", СтрокаТаблицы.Данные, ПредметСтрокой(СтрокаТаблицы.Данные),
|
||
НСтр("ru = 'Заменены не все места использования. Возможно места использования были добавлены или изменены другим пользователем.'")));
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ЗаблокироватьМестоИспользования(ПараметрыВыполнения, Блокировка, МестоИспользования)
|
||
|
||
Если МестоИспользования.КлючЗамены = "Константа" Тогда
|
||
|
||
Блокировка.Добавить(МестоИспользования.Метаданные.ПолноеИмя());
|
||
|
||
ИначеЕсли МестоИспользования.КлючЗамены = "Объект" Тогда
|
||
|
||
СсылкаОбъекта = МестоИспользования.Данные;
|
||
МетаданныеОбъекта = МестоИспользования.Метаданные;
|
||
|
||
// Сам объект.
|
||
Блокировка.Добавить(МетаданныеОбъекта.ПолноеИмя()).УстановитьЗначение("Ссылка", СсылкаОбъекта);
|
||
|
||
// Движения по регистратору.
|
||
ОписаниеДвижений = ОписаниеДвижений(МетаданныеОбъекта);
|
||
Для Каждого Элемент Из ОписаниеДвижений Цикл
|
||
Блокировка.Добавить(Элемент.ПространствоБлокировки + ".НаборЗаписей").УстановитьЗначение("Регистратор", СсылкаОбъекта);
|
||
КонецЦикла;
|
||
|
||
// Последовательности.
|
||
ОписаниеПоследовательностей = ОписаниеПоследовательностей(МетаданныеОбъекта);
|
||
Для Каждого Элемент Из ОписаниеПоследовательностей Цикл
|
||
Блокировка.Добавить(Элемент.ПространствоБлокировки).УстановитьЗначение("Регистратор", СсылкаОбъекта);
|
||
КонецЦикла;
|
||
|
||
// Задачи (для бизнес-процессов)
|
||
ОписаниеЗадач = ОписаниеЗадач(МетаданныеОбъекта);
|
||
Если ОписаниеЗадач <> Неопределено Тогда
|
||
Блокировка.Добавить(ОписаниеЗадач.ПространствоБлокировки).УстановитьЗначение("БизнесПроцесс", СсылкаОбъекта);
|
||
КонецЕсли;
|
||
|
||
ИначеЕсли МестоИспользования.КлючЗамены = "Последовательность" Тогда
|
||
|
||
СсылкаОбъекта = МестоИспользования.Данные;
|
||
МетаданныеОбъекта = МестоИспользования.Метаданные;
|
||
|
||
ОписаниеПоследовательностей = ОписаниеПоследовательностей(МетаданныеОбъекта);
|
||
Для Каждого Элемент Из ОписаниеПоследовательностей Цикл
|
||
Блокировка.Добавить(Элемент.ПространствоБлокировки).УстановитьЗначение("Регистратор", СсылкаОбъекта);
|
||
КонецЦикла;
|
||
|
||
ИначеЕсли МестоИспользования.КлючЗамены = "КлючЗаписи"
|
||
Или МестоИспользования.КлючЗамены = "РегистрСведений" Тогда
|
||
|
||
Информация = ИнформацияОТипе(МестоИспользования.Метаданные, ПараметрыВыполнения);
|
||
ТипДубля = МестоИспользования.ТипСсылки;
|
||
ТипОригинала = ТипЗнч(МестоИспользования.ЦелеваяСсылка);
|
||
|
||
Для Каждого КлючЗначение Из Информация.Измерения Цикл
|
||
ТипИзмерения = КлючЗначение.Значение.Тип;
|
||
Если ТипИзмерения.СодержитТип(ТипДубля) Тогда
|
||
БлокировкаПоИзмерению = Блокировка.Добавить(Информация.ПолноеИмя);
|
||
БлокировкаПоИзмерению.УстановитьЗначение(КлючЗначение.Ключ, МестоИспользования.Ссылка);
|
||
КонецЕсли;
|
||
Если ТипИзмерения.СодержитТип(ТипОригинала) Тогда
|
||
БлокировкаПоИзмерению = Блокировка.Добавить(Информация.ПолноеИмя);
|
||
БлокировкаПоИзмерению.УстановитьЗначение(КлючЗначение.Ключ, МестоИспользования.ЦелеваяСсылка);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ОтключитьОбновлениеКлючейДоступа(Значение)
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом") Тогда
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
МодульУправлениеДоступом = ОбщийМодуль("УправлениеДоступом");
|
||
МодульУправлениеДоступом.ОтключитьОбновлениеКлючейДоступа(Значение);
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных
|
||
//
|
||
// Возвращаемое значение:
|
||
// Массив из Структура:
|
||
// * СписокПолей - Структура
|
||
// * СтруктураИзмерений - Структура
|
||
// * СписокВедущих - Структура
|
||
// * НаборЗаписей - РегистрСведенийНаборЗаписей
|
||
// * ПространствоБлокировки - Строка
|
||
//
|
||
Функция ОписаниеДвижений(Знач ОбъектМетаданных)
|
||
|
||
ОписаниеДвижений = Новый Массив;
|
||
Если Не Метаданные.Документы.Содержит(ОбъектМетаданных) Тогда
|
||
Возврат ОписаниеДвижений;
|
||
КонецЕсли;
|
||
|
||
Для Каждого Движение Из ОбъектМетаданных.Движения Цикл
|
||
|
||
Если Метаданные.РегистрыНакопления.Содержит(Движение) Тогда
|
||
НаборЗаписей = РегистрыНакопления[Движение.Имя].СоздатьНаборЗаписей();
|
||
ИсключатьПоля = "Активность, НомерСтроки, Период, Регистратор";
|
||
|
||
ИначеЕсли Метаданные.РегистрыСведений.Содержит(Движение) Тогда
|
||
НаборЗаписей = РегистрыСведений[Движение.Имя].СоздатьНаборЗаписей();
|
||
ИсключатьПоля = "Активность, ВидДвижения, НомерСтроки, Период, Регистратор";
|
||
|
||
ИначеЕсли Метаданные.РегистрыБухгалтерии.Содержит(Движение) Тогда
|
||
НаборЗаписей = РегистрыБухгалтерии[Движение.Имя].СоздатьНаборЗаписей();
|
||
ИсключатьПоля = "Активность, ВидДвижения, НомерСтроки, Период, Регистратор";
|
||
|
||
ИначеЕсли Метаданные.РегистрыРасчета.Содержит(Движение) Тогда
|
||
НаборЗаписей = РегистрыРасчета[Движение.Имя].СоздатьНаборЗаписей();
|
||
ИсключатьПоля = "Активность, БазовыйПериодКонец, БазовыйПериодНачало, НомерСтроки, ПериодДействия,
|
||
|ПериодДействияКонец, ПериодДействияНачало, ПериодРегистрации, Регистратор, Сторно,
|
||
|ФактическийПериодДействия";
|
||
Иначе
|
||
// Неизвестный тип
|
||
Продолжить;
|
||
КонецЕсли;
|
||
|
||
// Поля ссылочного типа и измерения - кандидаты.
|
||
// @skip-check query-in-loop - Пустой запрос для получения списка полей таблицы.
|
||
Описание = СпискиПолейОбъекта(НаборЗаписей, Движение.Измерения, ИсключатьПоля);
|
||
Если Описание.СписокПолей.Количество() = 0 Тогда
|
||
// Незачем обрабатывать
|
||
Продолжить;
|
||
КонецЕсли;
|
||
|
||
Описание.Вставить("НаборЗаписей", НаборЗаписей);
|
||
Описание.Вставить("ПространствоБлокировки", Движение.ПолноеИмя() );
|
||
|
||
ОписаниеДвижений.Добавить(Описание);
|
||
КонецЦикла;
|
||
|
||
Возврат ОписаниеДвижений;
|
||
КонецФункции
|
||
|
||
// Параметры:
|
||
// Мета - ОбъектМетаданных
|
||
//
|
||
// Возвращаемое значение:
|
||
// Массив из Структура:
|
||
// * НаборЗаписей - ПоследовательностьНаборЗаписей
|
||
// * ПространствоБлокировки - Строка
|
||
// * Измерения - Структура
|
||
//
|
||
Функция ОписаниеПоследовательностей(Знач Мета)
|
||
|
||
ОписаниеПоследовательностей = Новый Массив;
|
||
Если Не Метаданные.Документы.Содержит(Мета) Тогда
|
||
Возврат ОписаниеПоследовательностей;
|
||
КонецЕсли;
|
||
|
||
Для Каждого Последовательность Из Метаданные.Последовательности Цикл
|
||
Если Не Последовательность.Документы.Содержит(Мета) Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
|
||
ИмяТаблицы = Последовательность.ПолноеИмя();
|
||
|
||
// @skip-check query-in-loop - Пустой запрос для получения списка полей таблицы.
|
||
Описание = СпискиПолейОбъекта(ИмяТаблицы, Последовательность.Измерения, "Регистратор");
|
||
Если Описание.СписокПолей.Количество() > 0 Тогда
|
||
|
||
Описание.Вставить("НаборЗаписей", Последовательности[Последовательность.Имя].СоздатьНаборЗаписей());
|
||
Описание.Вставить("ПространствоБлокировки", ИмяТаблицы + ".Записи");
|
||
Описание.Вставить("Измерения", Новый Структура);
|
||
|
||
ОписаниеПоследовательностей.Добавить(Описание);
|
||
КонецЕсли;
|
||
|
||
КонецЦикла;
|
||
|
||
Возврат ОписаниеПоследовательностей;
|
||
КонецФункции
|
||
|
||
// Возвращаемое значение:
|
||
// Структура:
|
||
// * СтандартныеРеквизиты - Структура
|
||
// * РеквизитыАдресации - Структура
|
||
// * Реквизиты - Структура
|
||
// * СтандартныеТабличныеЧасти - Массив из Структура:
|
||
// ** Имя - Строка
|
||
// ** СписокПолей - Структура
|
||
// * ТабличныеЧасти - Массив из Структура:
|
||
// ** Имя - Строка
|
||
// ** СписокПолей - Структура
|
||
// * МожетБытьПроведен - Булево
|
||
//
|
||
Функция ОписаниеОбъекта(Знач ОбъектМетаданных)
|
||
|
||
ТипВсеСсылки = ОписаниеТипаВсеСсылки();
|
||
|
||
Кандидаты = Новый Структура("Реквизиты, СтандартныеРеквизиты, ТабличныеЧасти, СтандартныеТабличныеЧасти, РеквизитыАдресации");
|
||
ЗаполнитьЗначенияСвойств(Кандидаты, ОбъектМетаданных);
|
||
|
||
ОписаниеОбъекта = Новый Структура;
|
||
|
||
ОписаниеОбъекта.Вставить("Реквизиты", Новый Структура);
|
||
Если Кандидаты.Реквизиты <> Неопределено Тогда
|
||
Для Каждого МетаРеквизит Из Кандидаты.Реквизиты Цикл
|
||
Если ОписанияТиповПересекаются(МетаРеквизит.Тип, ТипВсеСсылки) Тогда
|
||
ОписаниеОбъекта.Реквизиты.Вставить(МетаРеквизит.Имя);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
ОписаниеОбъекта.Вставить("СтандартныеРеквизиты", Новый Структура);
|
||
Если Кандидаты.СтандартныеРеквизиты <> Неопределено Тогда
|
||
Исключаемые = Новый Структура("Ссылка");
|
||
|
||
Для Каждого МетаРеквизит Из Кандидаты.СтандартныеРеквизиты Цикл
|
||
Имя = МетаРеквизит.Имя;
|
||
Если Не Исключаемые.Свойство(Имя) И ОписанияТиповПересекаются(МетаРеквизит.Тип, ТипВсеСсылки) Тогда
|
||
ОписаниеОбъекта.Реквизиты.Вставить(МетаРеквизит.Имя);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
ОписаниеОбъекта.Вставить("ТабличныеЧасти", Новый Массив);
|
||
Если Кандидаты.ТабличныеЧасти <> Неопределено Тогда
|
||
Для Каждого МетаТаблица Из Кандидаты.ТабличныеЧасти Цикл
|
||
|
||
СписокПолей = Новый Структура;
|
||
Для Каждого МетаРеквизит Из МетаТаблица.Реквизиты Цикл
|
||
Если ОписанияТиповПересекаются(МетаРеквизит.Тип, ТипВсеСсылки) Тогда
|
||
СписокПолей.Вставить(МетаРеквизит.Имя);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если СписокПолей.Количество() > 0 Тогда
|
||
ОписаниеОбъекта.ТабличныеЧасти.Добавить(Новый Структура("Имя, СписокПолей", МетаТаблица.Имя, СписокПолей));
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
ОписаниеОбъекта.Вставить("СтандартныеТабличныеЧасти", Новый Массив);
|
||
Если Кандидаты.СтандартныеТабличныеЧасти <> Неопределено Тогда
|
||
Для Каждого МетаТаблица Из Кандидаты.СтандартныеТабличныеЧасти Цикл
|
||
|
||
СписокПолей = Новый Структура;
|
||
Для Каждого МетаРеквизит Из МетаТаблица.СтандартныеРеквизиты Цикл
|
||
Если ОписанияТиповПересекаются(МетаРеквизит.Тип, ТипВсеСсылки) Тогда
|
||
СписокПолей.Вставить(МетаРеквизит.Имя);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если СписокПолей.Количество() > 0 Тогда
|
||
ОписаниеОбъекта.СтандартныеТабличныеЧасти.Добавить(Новый Структура("Имя, СписокПолей", МетаТаблица.Имя, СписокПолей));
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
ОписаниеОбъекта.Вставить("РеквизитыАдресации", Новый Структура);
|
||
Если Кандидаты.РеквизитыАдресации <> Неопределено Тогда
|
||
Для Каждого Реквизит Из Кандидаты.РеквизитыАдресации Цикл
|
||
Если ОписанияТиповПересекаются(Реквизит.Тип, ТипВсеСсылки) Тогда
|
||
ОписаниеОбъекта.РеквизитыАдресации.Вставить(Реквизит.Имя);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
ОписаниеОбъекта.Вставить("МожетБытьПроведен", Метаданные.Документы.Содержит(ОбъектМетаданных));
|
||
Возврат ОписаниеОбъекта;
|
||
КонецФункции
|
||
|
||
// Параметры:
|
||
// ОбъектМетаданных - ОбъектМетаданных
|
||
//
|
||
// Возвращаемое значение:
|
||
// Массив из Структура:
|
||
// * СписокПолей - Структура
|
||
// * СтруктураИзмерений - Структура
|
||
// * СписокВедущих - Структура
|
||
// * НаборЗаписей - РегистрСведенийНаборЗаписей
|
||
// * ПространствоБлокировки - Строка
|
||
//
|
||
Функция ОписаниеЗадач(Знач Мета)
|
||
|
||
ОписаниеЗадач = Неопределено;
|
||
Если НЕ Метаданные.БизнесПроцессы.Содержит(Мета) Тогда
|
||
Возврат ОписаниеЗадач;
|
||
КонецЕсли;
|
||
|
||
ОписаниеЗадач = ОписаниеОбъекта(Мета.Задача);
|
||
ОписаниеЗадач.Вставить("ПространствоБлокировки", Мета.Задача.ПолноеИмя());
|
||
|
||
Возврат ОписаниеЗадач;
|
||
|
||
КонецФункции
|
||
|
||
Функция ОписаниеКлючаЗаписи(Знач МетаданныеТаблицы)
|
||
|
||
ИмяТаблицы = МетаданныеТаблицы.ПолноеИмя();
|
||
|
||
// Поля ссылочного типа - кандидаты и набор измерений.
|
||
// @skip-check query-in-loop - Пустой запрос для получения списка полей таблицы.
|
||
ОписаниеКлюча = СпискиПолейОбъекта(ИмяТаблицы, МетаданныеТаблицы.Измерения, "Период, Регистратор");
|
||
|
||
Если Метаданные.РегистрыСведений.Содержит(МетаданныеТаблицы) Тогда
|
||
НаборЗаписей = РегистрыСведений[МетаданныеТаблицы.Имя].СоздатьНаборЗаписей();
|
||
ИначеЕсли Метаданные.РегистрыНакопления.Содержит(МетаданныеТаблицы) Тогда
|
||
НаборЗаписей = РегистрыНакопления[МетаданныеТаблицы.Имя].СоздатьНаборЗаписей();
|
||
ИначеЕсли Метаданные.РегистрыБухгалтерии.Содержит(МетаданныеТаблицы) Тогда
|
||
НаборЗаписей = РегистрыБухгалтерии[МетаданныеТаблицы.Имя].СоздатьНаборЗаписей();
|
||
ИначеЕсли Метаданные.РегистрыРасчета.Содержит(МетаданныеТаблицы) Тогда
|
||
НаборЗаписей = РегистрыРасчета[МетаданныеТаблицы.Имя].СоздатьНаборЗаписей();
|
||
ИначеЕсли Метаданные.Последовательности.Содержит(МетаданныеТаблицы) Тогда
|
||
НаборЗаписей = Последовательности[МетаданныеТаблицы.Имя].СоздатьНаборЗаписей();
|
||
Иначе
|
||
НаборЗаписей = Неопределено;
|
||
КонецЕсли;
|
||
|
||
ОписаниеКлюча.Вставить("НаборЗаписей", НаборЗаписей);
|
||
ОписаниеКлюча.Вставить("ПространствоБлокировки", ИмяТаблицы);
|
||
|
||
Возврат ОписаниеКлюча;
|
||
КонецФункции
|
||
|
||
Функция ОписанияТиповПересекаются(Знач Описание1, Знач Описание2)
|
||
|
||
Для Каждого Тип Из Описание1.Типы() Цикл
|
||
Если Описание2.СодержитТип(Тип) Тогда
|
||
Возврат Истина;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат Ложь;
|
||
КонецФункции
|
||
|
||
// Возвращает описание по имени таблицы или по набору записей.
|
||
Функция СпискиПолейОбъекта(Знач ИсточникДанных, Знач МетаданныеИзмеренийРегистра, Знач ИсключатьПоля)
|
||
|
||
Описание = Новый Структура;
|
||
Описание.Вставить("СписокПолей", Новый Структура);
|
||
Описание.Вставить("СтруктураИзмерений", Новый Структура);
|
||
Описание.Вставить("СписокВедущих", Новый Структура);
|
||
|
||
ТипКонтроля = ОписаниеТипаВсеСсылки();
|
||
Исключаемые = Новый Структура(ИсключатьПоля);
|
||
|
||
ТипИсточникаДанных = ТипЗнч(ИсточникДанных);
|
||
|
||
Если ТипИсточникаДанных = Тип("Строка") Тогда
|
||
// Источник - имя таблицы, получаем поля запросом.
|
||
ТекстЗапроса = "ВЫБРАТЬ * ИЗ &ИмяТаблицы ГДЕ ЛОЖЬ";
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ИмяТаблицы", ИсточникДанных);
|
||
Запрос = Новый Запрос(ТекстЗапроса);
|
||
ИсточникПолей = Запрос.Выполнить();
|
||
Иначе
|
||
// Источник - набор записей
|
||
ИсточникПолей = ИсточникДанных.ВыгрузитьКолонки();
|
||
КонецЕсли;
|
||
|
||
Для Каждого Колонка Из ИсточникПолей.Колонки Цикл
|
||
Имя = Колонка.Имя;
|
||
Если Не Исключаемые.Свойство(Имя) И ОписанияТиповПересекаются(Колонка.ТипЗначения, ТипКонтроля) Тогда
|
||
Описание.СписокПолей.Вставить(Имя);
|
||
|
||
// И проверка на ведущее измерение.
|
||
Мета = МетаданныеИзмеренийРегистра.Найти(Имя);
|
||
Если Мета <> Неопределено Тогда
|
||
Описание.СтруктураИзмерений.Вставить(Имя, Мета.Тип);
|
||
Тест = Новый Структура("Ведущее", Ложь);
|
||
ЗаполнитьЗначенияСвойств(Тест, Мета);
|
||
Если Тест.Ведущее Тогда
|
||
Описание.СписокВедущих.Вставить(Имя, Мета.Тип);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
|
||
КонецЦикла;
|
||
|
||
Возврат Описание;
|
||
КонецФункции
|
||
|
||
|
||
Процедура ЗаменитьВКоллекцииСтрок(ВидКоллекции, ИмяКоллекции, Объект, Коллекция, Знач СписокПолей, Знач ПарыЗамен)
|
||
|
||
ИзмененнаяКоллекция = Коллекция.Выгрузить();
|
||
Модифицировано = Ложь;
|
||
ИменаИзмененныхРеквизитов = Новый Массив;
|
||
|
||
Для Каждого СтрокаТаблицы Из ИзмененнаяКоллекция Цикл
|
||
|
||
Для Каждого КлючЗначение Из СписокПолей Цикл
|
||
ИмяРеквизита = КлючЗначение.Ключ;
|
||
ЦелеваяСсылка = ПарыЗамен[ СтрокаТаблицы[ИмяРеквизита] ];
|
||
Если ЦелеваяСсылка <> Неопределено Тогда
|
||
ЗарегистрироватьФактЗамены(Объект, СтрокаТаблицы[ИмяРеквизита], ЦелеваяСсылка, ВидКоллекции, ИмяКоллекции,
|
||
ИзмененнаяКоллекция.Индекс(СтрокаТаблицы), ИмяРеквизита);
|
||
СтрокаТаблицы[ИмяРеквизита] = ЦелеваяСсылка;
|
||
Модифицировано = Истина;
|
||
ИменаИзмененныхРеквизитов.Добавить(ИмяРеквизита);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
КонецЦикла;
|
||
|
||
Если Модифицировано Тогда
|
||
ЭтоРегистрБухгалтерии = ВидКоллекции = "Движения" И ЭтоРегистрБухгалтерии(Коллекция.Метаданные());
|
||
Если ЭтоРегистрБухгалтерии Тогда
|
||
ЗагрузитьИзмененныйНаборВРегистрБухгалтерии(Коллекция, ИзмененнаяКоллекция, ИменаИзмененныхРеквизитов);
|
||
Иначе
|
||
Коллекция.Загрузить(ИзмененнаяКоллекция);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецПроцедуры
|
||
|
||
Процедура ЗагрузитьИзмененныйНаборВРегистрБухгалтерии(НаборЗаписей, ИзмененнаяКоллекция, ИменаИзмененныхРеквизитов)
|
||
НеизмененныеИзмерения = Новый Соответствие;
|
||
ИзмененныеИзмерения = Новый Соответствие;
|
||
МетаданныеРегистра = НаборЗаписей.Метаданные();
|
||
|
||
Для каждого Измерение Из МетаданныеРегистра.Измерения Цикл
|
||
ИменаИзмерений = Новый Массив;
|
||
|
||
Если Измерение.Балансовый ИЛИ НЕ МетаданныеРегистра.Корреспонденция Тогда
|
||
ИменаИзмерений.Добавить(Измерение.Имя);
|
||
Иначе
|
||
ИменаИзмерений.Добавить(Измерение.Имя + "Дт");
|
||
ИменаИзмерений.Добавить(Измерение.Имя + "Кт");
|
||
КонецЕсли;
|
||
|
||
Для каждого ИмяИзмерения Из ИменаИзмерений Цикл
|
||
Если ИменаИзмененныхРеквизитов.Найти(ИмяИзмерения) = Неопределено Тогда
|
||
НеизмененныеИзмерения.Вставить(ИмяИзмерения, НаборЗаписей.ВыгрузитьКолонку(ИмяИзмерения));
|
||
Иначе
|
||
ИзмененныеИзмерения.Вставить(ИмяИзмерения, НаборЗаписей.ВыгрузитьКолонку(ИмяИзмерения));
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
|
||
Для Сч = 0 По НаборЗаписей.Количество()-1 Цикл
|
||
|
||
Для каждого ИмяИзмеренияЗначения Из ИзмененныеИзмерения Цикл
|
||
Если НаборЗаписей[Сч][ИмяИзмеренияЗначения.Ключ] = NULL Тогда
|
||
ИмяИзмеренияЗначения.Значение[Сч] = NULL;
|
||
Иначе
|
||
ИмяИзмеренияЗначения.Значение[Сч] = ИзмененнаяКоллекция[Сч][ИмяИзмеренияЗначения.Ключ];
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
КонецЦикла;
|
||
|
||
НаборЗаписей.Загрузить(ИзмененнаяКоллекция);
|
||
|
||
Для каждого ИзмеренияЗначенияВКолонке Из НеизмененныеИзмерения Цикл
|
||
НаборЗаписей.ЗагрузитьКолонку(ИзмеренияЗначенияВКолонке.Значение, ИзмеренияЗначенияВКолонке.Ключ);
|
||
КонецЦикла;
|
||
|
||
Для каждого ИзмеренияЗначенияВКолонке Из ИзмененныеИзмерения Цикл
|
||
НаборЗаписей.ЗагрузитьКолонку(ИзмеренияЗначенияВКолонке.Значение, ИзмеренияЗначенияВКолонке.Ключ);
|
||
КонецЦикла;
|
||
КонецПроцедуры
|
||
|
||
Процедура ЗаписатьОбъектСПерехватомСообщений(Знач Объект, Знач Действие, Знач РежимЗаписи, Знач ПараметрыЗаписи)
|
||
|
||
// Текущие сообщения до исключения запоминаем.
|
||
ПредыдущиеСообщения = ПолучитьСообщенияПользователю(Истина);
|
||
СообщатьПовторно = ТекущийРежимЗапуска() <> Неопределено;
|
||
|
||
Попытка
|
||
|
||
Если Действие = "Запись" Тогда
|
||
|
||
Объект.ОбменДанными.Загрузка = Не ПараметрыЗаписи.ВключатьБизнесЛогику;
|
||
|
||
Если РежимЗаписи = Неопределено Тогда
|
||
Объект.Записать();
|
||
Иначе
|
||
Объект.Записать(РежимЗаписи);
|
||
КонецЕсли;
|
||
|
||
ИначеЕсли Действие = "ПометкаУдаления" Тогда
|
||
|
||
МетаданныеОбъекта = Объект.Метаданные();
|
||
Если ЭтоСправочник(МетаданныеОбъекта)
|
||
Или ЭтоПланВидовХарактеристик(МетаданныеОбъекта)
|
||
Или ЭтоПланСчетов(МетаданныеОбъекта) Тогда
|
||
|
||
Объект.ОбменДанными.Загрузка = Не ПараметрыЗаписи.ВключатьБизнесЛогику;
|
||
Объект.УстановитьПометкуУдаления(Истина, Ложь);
|
||
ИначеЕсли ЭтоДокумент(МетаданныеОбъекта)
|
||
И МетаданныеОбъекта.Проведение = Метаданные.СвойстваОбъектов.Проведение.Разрешить Тогда
|
||
|
||
Объект.УстановитьПометкуУдаления(Истина);
|
||
Иначе
|
||
Объект.ОбменДанными.Загрузка = Не ПараметрыЗаписи.ВключатьБизнесЛогику;
|
||
Объект.УстановитьПометкуУдаления(Истина);
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
|
||
Исключение
|
||
ТекстСообщений = "";
|
||
Для Каждого Сообщение Из ПолучитьСообщенияПользователю(Ложь) Цикл
|
||
ТекстСообщений = ТекстСообщений + Символы.ПС + Сообщение.Текст;
|
||
КонецЦикла;
|
||
|
||
Если СообщатьПовторно Тогда
|
||
СообщитьОтложенныеСообщения(ПредыдущиеСообщения);
|
||
КонецЕсли;
|
||
|
||
Если ТекстСообщений = "" Тогда
|
||
ВызватьИсключение;
|
||
КонецЕсли;
|
||
ИнформацияОбОшибке = ИнформацияОбОшибке();
|
||
Уточнение = ОбщегоНазначенияКлиентСервер.УточнениеИсключения(ИнформацияОбОшибке);
|
||
Уточнение.Текст = Уточнение.Текст + Символы.ПС + СокрЛП(ТекстСообщений);
|
||
ВызватьИсключение(Уточнение.Текст, Уточнение.Категория,,, ИнформацияОбОшибке);
|
||
КонецПопытки;
|
||
|
||
Если СообщатьПовторно Тогда
|
||
СообщитьОтложенныеСообщения(ПредыдущиеСообщения);
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура СообщитьОтложенныеСообщения(Знач Сообщения)
|
||
|
||
Для Каждого Сообщение Из Сообщения Цикл
|
||
Сообщение.Сообщить();
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ЗаписатьОбъект(Знач Объект, Знач ПараметрыЗаписи)
|
||
|
||
МетаданныеОбъекта = Объект.Метаданные();
|
||
|
||
Если ЭтоДокумент(МетаданныеОбъекта) Тогда
|
||
ЗаписатьОбъектСПерехватомСообщений(Объект, "Запись", РежимЗаписиДокумента.Запись, ПараметрыЗаписи);
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
// Проверка на возможные циклические ссылки.
|
||
СвойстваОбъекта = Новый Структура("Иерархический, ВидыСубконто, Владельцы", Ложь, Неопределено, Новый Массив);
|
||
ЗаполнитьЗначенияСвойств(СвойстваОбъекта, МетаданныеОбъекта);
|
||
|
||
// По родителю
|
||
Если СвойстваОбъекта.Иерархический Или СвойстваОбъекта.ВидыСубконто <> Неопределено Тогда
|
||
|
||
Если Объект.Родитель = Объект.Ссылка Тогда
|
||
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Невозможно записать ""%1"", т.к. его родительским элементом не может быть он сам.'"),
|
||
ПредметСтрокой(Объект));
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
|
||
// По владельцу
|
||
Если СвойстваОбъекта.Владельцы.Количество() > 1 И Объект.Владелец = Объект.Ссылка Тогда
|
||
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Невозможно записать ""%1"", т.к. его владельцем не может быть он сам.'"),
|
||
ПредметСтрокой(Объект));
|
||
КонецЕсли;
|
||
|
||
// Для последовательностей право "Изменение" может отсутствовать даже у роли "АдминистраторСистемы".
|
||
Если ЭтоПоследовательность(МетаданныеОбъекта)
|
||
И Не ПравоДоступа("Изменение", МетаданныеОбъекта)
|
||
И Пользователи.ЭтоПолноправныйПользователь(,, Ложь) Тогда
|
||
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
КонецЕсли;
|
||
|
||
ЗаписатьОбъектСПерехватомСообщений(Объект, "Запись", Неопределено, ПараметрыЗаписи);
|
||
КонецПроцедуры
|
||
|
||
Функция СобытиеЖурналаРегистрацииЗаменыСсылок()
|
||
|
||
Возврат НСтр("ru = 'Поиск и удаление ссылок'", КодОсновногоЯзыка());
|
||
|
||
КонецФункции
|
||
|
||
// Параметры:
|
||
// Результат - см. РезультатЗаменыСсылок
|
||
// Ссылка - ЛюбаяСсылка
|
||
// ОписаниеОшибки - см. ОписаниеОшибкиЗамены
|
||
//
|
||
Процедура ЗарегистрироватьОшибкуЗамены(Результат, Знач Ссылка, Знач ОписаниеОшибки)
|
||
|
||
Результат.ЕстьОшибки = Истина;
|
||
|
||
Строка = Результат.Ошибки.Добавить();
|
||
Строка.Ссылка = Ссылка;
|
||
Строка.ПредставлениеОбъектаОшибки = ОписаниеОшибки.ПредставлениеОбъектаОшибки;
|
||
Строка.ОбъектОшибки = ОписаниеОшибки.ОбъектОшибки;
|
||
Строка.ИнформацияОбОшибке = ?(ТипЗнч(ОписаниеОшибки.ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке"),
|
||
ОписаниеОшибки.ИнформацияОбОшибке, Неопределено);
|
||
Строка.ТекстОшибки = ?(ТипЗнч(ОписаниеОшибки.ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке"),
|
||
ОбработкаОшибок.КраткоеПредставлениеОшибки(ОписаниеОшибки.ИнформацияОбОшибке), ОписаниеОшибки.ИнформацияОбОшибке);
|
||
Строка.ТипОшибки = ОписаниеОшибки.ТипОшибки;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Возвращаемое значение:
|
||
// Структура:
|
||
// * ТипОшибки - Строка
|
||
// * ОбъектОшибки - ЛюбаяСсылка
|
||
// * ПредставлениеОбъектаОшибки - Строка
|
||
// * ИнформацияОбОшибке - ИнформацияОбОшибке, Строка
|
||
//
|
||
Функция ОписаниеОшибкиЗамены(Знач ТипОшибки, Знач ОбъектОшибки, Знач ПредставлениеОбъектаОшибки, Знач ИнформацияОбОшибке)
|
||
|
||
Результат = Новый Структура;
|
||
Результат.Вставить("ТипОшибки", ТипОшибки);
|
||
Результат.Вставить("ОбъектОшибки", ОбъектОшибки);
|
||
Результат.Вставить("ПредставлениеОбъектаОшибки", ПредставлениеОбъектаОшибки);
|
||
Результат.Вставить("ИнформацияОбОшибке", ИнформацияОбОшибке);
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Возвращаемое значение:
|
||
// Структура:
|
||
// * ЕстьОшибки - Булево
|
||
// * ОчередьКНепосредственномуУдалению - Массив
|
||
// * Ошибки - см. ОбщегоНазначения.ЗаменитьСсылки
|
||
//
|
||
Функция РезультатЗаменыСсылок(Знач ОшибкиЗамены)
|
||
|
||
Результат = Новый Структура;
|
||
Результат.Вставить("ЕстьОшибки", Ложь);
|
||
Результат.Вставить("ОчередьКНепосредственномуУдалению", Новый Массив);
|
||
Результат.Вставить("Ошибки", ОшибкиЗамены);
|
||
Возврат Результат
|
||
|
||
КонецФункции
|
||
|
||
Процедура ЗарегистрироватьОшибкуВТаблицу(Результат, Дубль, Оригинал, Данные, Информация, ТипОшибки, ИнформацияОбОшибке)
|
||
Результат.ЕстьОшибки = Истина;
|
||
|
||
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииЗаменыСсылок(),
|
||
УровеньЖурналаРегистрации.Ошибка,,,
|
||
ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке));
|
||
|
||
ПолноеПредставлениеДанных = Строка(Данные) + " (" + Информация.ПредставлениеЭлемента + ")";
|
||
|
||
Ошибка = Результат.Ошибки.Добавить();
|
||
Ошибка.Ссылка = Дубль;
|
||
Ошибка.ОбъектОшибки = Данные;
|
||
Ошибка.ПредставлениеОбъектаОшибки = ПолноеПредставлениеДанных;
|
||
|
||
Если ТипОшибки = "БлокировкаДляРегистра" Тогда
|
||
НовыйШаблон = НСтр("ru = 'Не удалось начать редактирование %1: %2'");
|
||
Ошибка.ТипОшибки = "ОшибкаБлокировки";
|
||
ИначеЕсли ТипОшибки = "БлокировкаДляУдаленияДубля" Тогда
|
||
НовыйШаблон = НСтр("ru = 'Не удалось начать удаление: %2'");
|
||
Ошибка.ТипОшибки = "ОшибкаБлокировки";
|
||
ИначеЕсли ТипОшибки = "УдалитьНаборДубля" Тогда
|
||
НовыйШаблон = НСтр("ru = 'Не удалось очистить сведения о дубле в %1: %2'");
|
||
Ошибка.ТипОшибки = "ОшибкаЗаписи";
|
||
ИначеЕсли ТипОшибки = "ЗаписатьНаборОригинала" Тогда
|
||
НовыйШаблон = НСтр("ru = 'Не удалось обновить сведения в %1: %2'");
|
||
Ошибка.ТипОшибки = "ОшибкаЗаписи";
|
||
Иначе
|
||
НовыйШаблон = ТипОшибки + " (%1): %2";
|
||
Ошибка.ТипОшибки = ТипОшибки;
|
||
КонецЕсли;
|
||
|
||
НовыйШаблон = НовыйШаблон + Символы.ПС + Символы.ПС + НСтр("ru = 'Подробности в журнале регистрации.'");
|
||
|
||
КраткоеПредставление = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
|
||
Ошибка.ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НовыйШаблон, ПолноеПредставлениеДанных, КраткоеПредставление);
|
||
|
||
КонецПроцедуры
|
||
|
||
// Формирует информацию о типе объекта метаданных: полное имя, представления, вид и т.п.
|
||
Функция ИнформацияОТипе(ПолноеИмяИлиМетаданныеИлиТип, Кэш)
|
||
ТипПервогоПараметра = ТипЗнч(ПолноеИмяИлиМетаданныеИлиТип);
|
||
Если ТипПервогоПараметра = Тип("Строка") Тогда
|
||
ОбъектМетаданных = ОбъектМетаданныхПоПолномуИмени(ПолноеИмяИлиМетаданныеИлиТип);
|
||
Иначе
|
||
Если ТипПервогоПараметра = Тип("Тип") Тогда // Поиск объекта метаданных.
|
||
ОбъектМетаданных = Метаданные.НайтиПоТипу(ПолноеИмяИлиМетаданныеИлиТип);
|
||
Иначе
|
||
ОбъектМетаданных = ПолноеИмяИлиМетаданныеИлиТип;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
ПолноеИмя = ВРег(ОбъектМетаданных.ПолноеИмя());
|
||
|
||
ИнформацияОТипах = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Кэш, "ИнформацияОТипах");
|
||
Если ИнформацияОТипах = Неопределено Тогда
|
||
ИнформацияОТипах = Новый Соответствие;
|
||
Кэш.Вставить("ИнформацияОТипах", ИнформацияОТипах);
|
||
Иначе
|
||
Информация = ИнформацияОТипах.Получить(ПолноеИмя);
|
||
Если Информация <> Неопределено Тогда
|
||
Возврат Информация;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Информация = Новый Структура("ПолноеИмя, ПредставлениеЭлемента,
|
||
|Вид, Ссылочный, Технический, Разделенный,
|
||
|Иерархический,
|
||
|ЕстьПодчиненные, ИменаПодчиненных,
|
||
|Измерения, Реквизиты, Ресурсы");
|
||
ИнформацияОТипах.Вставить(ПолноеИмя, Информация);
|
||
|
||
// Заполнение базовой информации.
|
||
Информация.ПолноеИмя = ПолноеИмя;
|
||
|
||
// Представление элемента.
|
||
Информация.ПредставлениеЭлемента = ПредставлениеОбъекта(ОбъектМетаданных);
|
||
|
||
// Вид и его свойства.
|
||
Информация.Вид = Лев(Информация.ПолноеИмя, СтрНайти(Информация.ПолноеИмя, ".")-1);
|
||
Если Информация.Вид = "СПРАВОЧНИК"
|
||
Или Информация.Вид = "ДОКУМЕНТ"
|
||
Или Информация.Вид = "ПЕРЕЧИСЛЕНИЕ"
|
||
Или Информация.Вид = "ПЛАНВИДОВХАРАКТЕРИСТИК"
|
||
Или Информация.Вид = "ПЛАНСЧЕТОВ"
|
||
Или Информация.Вид = "ПЛАНВИДОВРАСЧЕТА"
|
||
Или Информация.Вид = "БИЗНЕСПРОЦЕСС"
|
||
Или Информация.Вид = "ЗАДАЧА"
|
||
Или Информация.Вид = "ПЛАНОБМЕНА" Тогда
|
||
Информация.Ссылочный = Истина;
|
||
Иначе
|
||
Информация.Ссылочный = Ложь;
|
||
КонецЕсли;
|
||
|
||
Если Информация.Вид = "СПРАВОЧНИК"
|
||
Или Информация.Вид = "ПЛАНВИДОВХАРАКТЕРИСТИК" Тогда
|
||
Информация.Иерархический = ОбъектМетаданных.Иерархический;
|
||
ИначеЕсли Информация.Вид = "ПЛАНСЧЕТОВ" Тогда
|
||
Информация.Иерархический = Истина;
|
||
Иначе
|
||
Информация.Иерархический = Ложь;
|
||
КонецЕсли;
|
||
|
||
Информация.ЕстьПодчиненные = Ложь;
|
||
Если Информация.Вид = "СПРАВОЧНИК"
|
||
Или Информация.Вид = "ПЛАНВИДОВХАРАКТЕРИСТИК"
|
||
Или Информация.Вид = "ПЛАНОБМЕНА"
|
||
Или Информация.Вид = "ПЛАНСЧЕТОВ"
|
||
Или Информация.Вид = "ПЛАНВИДОВРАСЧЕТА" Тогда
|
||
Для Каждого Справочник Из Метаданные.Справочники Цикл
|
||
Если Справочник.Владельцы.Содержит(ОбъектМетаданных) Тогда
|
||
Если Информация.ЕстьПодчиненные = Ложь Тогда
|
||
Информация.ЕстьПодчиненные = Истина;
|
||
Информация.ИменаПодчиненных = Новый Массив;
|
||
КонецЕсли;
|
||
ИменаПодчиненных = Информация.ИменаПодчиненных; // Массив -
|
||
ИменаПодчиненных.Добавить(Справочник.ПолноеИмя());
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
Если Информация.ПолноеИмя = "СПРАВОЧНИК.ИДЕНТИФИКАТОРЫОБЪЕКТОВМЕТАДАННЫХ"
|
||
Или Информация.ПолноеИмя = "СПРАВОЧНИК.ПРЕДОПРЕДЕЛЕННЫЕВАРИАНТЫОТЧЕТОВ" Тогда
|
||
Информация.Технический = Истина;
|
||
Информация.Разделенный = Ложь;
|
||
Иначе
|
||
Информация.Технический = Ложь;
|
||
Если Не Кэш.Свойство("МодельСервиса") Тогда
|
||
Кэш.Вставить("МодельСервиса", РазделениеВключено());
|
||
Если Кэш.МодельСервиса Тогда
|
||
|
||
Если ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
|
||
МодульРаботаВМоделиСервиса = ОбщийМодуль("РаботаВМоделиСервиса");
|
||
РазделительОсновныхДанных = МодульРаботаВМоделиСервиса.РазделительОсновныхДанных();
|
||
РазделительВспомогательныхДанных = МодульРаботаВМоделиСервиса.РазделительВспомогательныхДанных();
|
||
Иначе
|
||
РазделительОсновныхДанных = Неопределено;
|
||
РазделительВспомогательныхДанных = Неопределено;
|
||
КонецЕсли;
|
||
|
||
Кэш.Вставить("ВОбластиДанных", РазделениеВключено() И ДоступноИспользованиеРазделенныхДанных());
|
||
Кэш.Вставить("РазделительОсновныхДанных", РазделительОсновныхДанных);
|
||
Кэш.Вставить("РазделительВспомогательныхДанных", РазделительВспомогательныхДанных);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если Кэш.МодельСервиса Тогда
|
||
Если ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
|
||
МодульРаботаВМоделиСервиса = ОбщийМодуль("РаботаВМоделиСервиса");
|
||
ЭтоРазделенныйОбъектМетаданных = МодульРаботаВМоделиСервиса.ЭтоРазделенныйОбъектМетаданных(ОбъектМетаданных);
|
||
Иначе
|
||
ЭтоРазделенныйОбъектМетаданных = Истина;
|
||
КонецЕсли;
|
||
Информация.Разделенный = ЭтоРазделенныйОбъектМетаданных;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Информация.Измерения = Новый Структура;
|
||
Информация.Реквизиты = Новый Структура;
|
||
Информация.Ресурсы = Новый Структура;
|
||
|
||
ВидыРеквизитов = Новый Структура("СтандартныеРеквизиты, Реквизиты, Измерения, Ресурсы");
|
||
ЗаполнитьЗначенияСвойств(ВидыРеквизитов, ОбъектМетаданных);
|
||
Для Каждого КлючИЗначение Из ВидыРеквизитов Цикл
|
||
Коллекция = КлючИЗначение.Значение; // КоллекцияОбъектовМетаданных
|
||
Если ТипЗнч(Коллекция) = Тип("КоллекцияОбъектовМетаданных") Тогда
|
||
КудаПишем = ?(Информация.Свойство(КлючИЗначение.Ключ), Информация[КлючИЗначение.Ключ], Информация.Реквизиты);
|
||
Для Каждого Реквизит Из Коллекция Цикл
|
||
КудаПишем.Вставить(Реквизит.Имя, ИнформацияПоРеквизиту(Реквизит));
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если Информация.Вид = "РЕГИСТРСВЕДЕНИЙ"
|
||
И ОбъектМетаданных.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
|
||
ИнформацияПоРеквизиту = Новый Структура("Ведущее, Представление, Формат, Тип, ЗначениеПоУмолчанию, ЗаполнятьИзДанныхЗаполнения");
|
||
ИнформацияПоРеквизиту.Ведущее = Ложь;
|
||
ИнформацияПоРеквизиту.ЗаполнятьИзДанныхЗаполнения = Ложь;
|
||
Если ОбъектМетаданных.ПериодичностьРегистраСведений = Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.ПозицияРегистратора Тогда
|
||
ИнформацияПоРеквизиту.Тип = Новый ОписаниеТипов("МоментВремени");
|
||
ИначеЕсли ОбъектМетаданных.ПериодичностьРегистраСведений = Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Секунда Тогда
|
||
ИнформацияПоРеквизиту.Тип = Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя));
|
||
Иначе
|
||
ИнформацияПоРеквизиту.Тип = Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.Дата));
|
||
КонецЕсли;
|
||
Информация.Измерения.Вставить("Период", ИнформацияПоРеквизиту);
|
||
КонецЕсли;
|
||
|
||
Возврат Информация;
|
||
КонецФункции
|
||
|
||
// Параметры:
|
||
// МетаданныеРеквизита - ОбъектМетаданныхРеквизит
|
||
//
|
||
Функция ИнформацияПоРеквизиту(МетаданныеРеквизита)
|
||
// ОписаниеСтандартногоРеквизита
|
||
// ОбъектМетаданных: Измерение
|
||
// ОбъектМетаданных: Ресурс
|
||
// ОбъектМетаданных: Реквизит
|
||
Информация = Новый Структура("Ведущее, Представление, Формат, Тип, ЗначениеПоУмолчанию, ЗаполнятьИзДанныхЗаполнения");
|
||
ЗаполнитьЗначенияСвойств(Информация, МетаданныеРеквизита);
|
||
Информация.Представление = МетаданныеРеквизита.Представление();
|
||
Если Информация.ЗаполнятьИзДанныхЗаполнения = Истина Тогда
|
||
Информация.ЗначениеПоУмолчанию = МетаданныеРеквизита.ЗначениеЗаполнения;
|
||
Иначе
|
||
Информация.ЗначениеПоУмолчанию = МетаданныеРеквизита.Тип.ПривестиЗначение();
|
||
КонецЕсли;
|
||
Возврат Информация;
|
||
КонецФункции
|
||
|
||
Процедура ДобавитьВСтатистикуЗаменыСсылок(Статистика, Дубль, ЕстьОшибки)
|
||
|
||
КлючДубля = Дубль.Метаданные().ПолноеИмя();
|
||
ЭлементСтатистики = Статистика[КлючДубля];
|
||
Если ЭлементСтатистики = Неопределено Тогда
|
||
ЭлементСтатистики = Новый Структура("КоличествоЭлементов, КоличествоОшибок",0,0);
|
||
Статистика.Вставить(КлючДубля, ЭлементСтатистики);
|
||
КонецЕсли;
|
||
|
||
ЭлементСтатистики.КоличествоЭлементов = ЭлементСтатистики.КоличествоЭлементов + 1;
|
||
ЭлементСтатистики.КоличествоОшибок = ЭлементСтатистики.КоличествоОшибок + ?(ЕстьОшибки, 1,0);
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ОтправитьСтатистикуЗаменыСсылок(Статистика)
|
||
|
||
Если НЕ ПодсистемаСуществует("СтандартныеПодсистемы.ЦентрМониторинга") Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
МодульЦентрМониторинга = ОбщийМодуль("ЦентрМониторинга");
|
||
Для каждого ЭлементСтатистики Из Статистика Цикл
|
||
МодульЦентрМониторинга.ЗаписатьОперациюБизнесСтатистики(
|
||
"БазоваяФункциональность.ЗаменаСсылок." + ЭлементСтатистики.Ключ, ЭлементСтатистики.Значение.КоличествоЭлементов);
|
||
МодульЦентрМониторинга.ЗаписатьОперациюБизнесСтатистики(
|
||
"БазоваяФункциональность.ЗаменаСсылокКоличествоОшибок." + ЭлементСтатистики.Ключ, ЭлементСтатистики.Значение.КоличествоОшибок);
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ДополнитьИсключенияПоискаСсылокПодчиненнымиОбъектами(Знач ИсключенияПоискаСсылок)
|
||
|
||
Для каждого ОписаниеПодчиненногоОбъекта Из ПодчиненныеОбъекты() Цикл
|
||
|
||
ПоляСвязи = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(
|
||
ОписаниеПодчиненногоОбъекта.ПоляСвязей, ",",, Истина);
|
||
ЗначениеИсключенияПоискаСсылок = Новый Массив;
|
||
Для каждого ПолеСвязи Из ПоляСвязи Цикл
|
||
ЗначениеИсключенияПоискаСсылок.Добавить(ПолеСвязи);
|
||
КонецЦикла;
|
||
ИсключенияПоискаСсылок.Вставить(ОписаниеПодчиненногоОбъекта.ПодчиненныйОбъект, ЗначениеИсключенияПоискаСсылок);
|
||
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ЗарегистрироватьОшибкиУдаления(Результат, ПрепятствующиеУдалению)
|
||
|
||
ПредставленияСсылок = ПредметыСтрокой(ПрепятствующиеУдалению.ВыгрузитьКолонку("МестоИспользования"));
|
||
Для каждого ПрепятствующиеУдалению Из ПрепятствующиеУдалению Цикл
|
||
ТекстОшибки = НСтр("ru = 'Элемент не удален, т.к. на него есть ссылки.'");
|
||
ОписаниеОшибки = ОписаниеОшибкиЗамены("ОшибкаУдаления", ПрепятствующиеУдалению.МестоИспользования,
|
||
ПредставленияСсылок[ПрепятствующиеУдалению.МестоИспользования], ТекстОшибки);
|
||
ЗарегистрироватьОшибкуЗамены(Результат, ПрепятствующиеУдалению.УдаляемыйСсылка, ОписаниеОшибки);
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция СформироватьДубли(ПараметрыВыполнения, ПараметрыЗамены, ПарыЗамен, Результат)
|
||
|
||
Дубли = Новый Массив;
|
||
Для Каждого КлючЗначение Из ПарыЗамен Цикл
|
||
Дубль = КлючЗначение.Ключ;
|
||
Оригинал = КлючЗначение.Значение;
|
||
Если Дубль = Оригинал Или Дубль.Пустая() Тогда
|
||
Продолжить; // Самого на себя и пустые ссылки не заменяем.
|
||
КонецЕсли;
|
||
Дубли.Добавить(Дубль);
|
||
// Пропускаем промежуточные замены, чтобы не строить граф (если A->B и B->C то вместо A->B производится замена A->C).
|
||
ОригиналОригинала = ПарыЗамен[Оригинал];
|
||
ЕстьОригиналОригинала = (ОригиналОригинала <> Неопределено И ОригиналОригинала <> Дубль И ОригиналОригинала <> Оригинал);
|
||
Если ЕстьОригиналОригинала Тогда
|
||
Пока ЕстьОригиналОригинала Цикл
|
||
Оригинал = ОригиналОригинала;
|
||
ОригиналОригинала = ПарыЗамен[Оригинал];
|
||
ЕстьОригиналОригинала = (ОригиналОригинала <> Неопределено И ОригиналОригинала <> Дубль И ОригиналОригинала <> Оригинал);
|
||
КонецЦикла;
|
||
ПарыЗамен.Вставить(Дубль, Оригинал);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если ПараметрыВыполнения.УчитыватьПрикладныеПравила И ПодсистемаСуществует("СтандартныеПодсистемы.ПоискИУдалениеДублей") Тогда
|
||
МодульПоискИУдалениеДублей = ОбщийМодуль("ПоискИУдалениеДублей");
|
||
Ошибки = МодульПоискИУдалениеДублей.ПроверитьВозможностьЗаменыЭлементов(ПарыЗамен, ПараметрыЗамены);
|
||
|
||
ОригиналыОбъектов = Новый Массив;
|
||
Для Каждого КлючЗначение Из Ошибки Цикл
|
||
Дубль = КлючЗначение.Ключ;
|
||
ОригиналыОбъектов.Добавить(ПарыЗамен[Дубль]);
|
||
|
||
Индекс = Дубли.Найти(Дубль);
|
||
Если Индекс <> Неопределено Тогда
|
||
Дубли.Удалить(Индекс); // пропускаем проблемный элемент.
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
ПредставленияОбъектов = ПредметыСтрокой(ОригиналыОбъектов);
|
||
Для Каждого КлючЗначение Из Ошибки Цикл
|
||
Дубль = КлючЗначение.Ключ;
|
||
Оригинал = ПарыЗамен[Дубль];
|
||
ТекстОшибки = КлючЗначение.Значение;
|
||
Причина = ОписаниеОшибкиЗамены("ОшибкаЗаписи", Оригинал, ПредставленияОбъектов[Оригинал], ТекстОшибки);
|
||
ЗарегистрироватьОшибкуЗамены(Результат, Дубль, Причина);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
Возврат Дубли;
|
||
|
||
КонецФункции
|
||
|
||
Функция НовыйПараметрыВыполненияЗаменыСсылок(Знач ПараметрыЗамены)
|
||
|
||
ПараметрыПоУмолчанию = ПараметрыЗаменыСсылок();
|
||
ПараметрыВыполнения = Новый Структура;
|
||
ПараметрыВыполнения.Вставить("УдалятьНепосредственно", ПараметрыПоУмолчанию.СпособУдаления = "Непосредственно");
|
||
ПараметрыВыполнения.Вставить("ПомечатьНаУдаление", ПараметрыПоУмолчанию.СпособУдаления = "Пометка");
|
||
ПараметрыВыполнения.Вставить("ВключатьБизнесЛогику", ПараметрыПоУмолчанию.ВключатьБизнесЛогику);
|
||
ПараметрыВыполнения.Вставить("ПривилегированнаяЗапись", ПараметрыПоУмолчанию.ПривилегированнаяЗапись);
|
||
ПараметрыВыполнения.Вставить("УчитыватьПрикладныеПравила", ПараметрыПоУмолчанию.УчитыватьПрикладныеПравила);
|
||
ПараметрыВыполнения.Вставить("МестаЗамены", Новый Массив);
|
||
|
||
// Переданные параметры обрабатываются условно для обратной совместимости.
|
||
ЗначениеПараметра = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыЗамены, "СпособУдаления");
|
||
Если ЗначениеПараметра = "Непосредственно" Тогда
|
||
ПараметрыВыполнения.УдалятьНепосредственно = Истина;
|
||
ПараметрыВыполнения.ПомечатьНаУдаление = Ложь;
|
||
ИначеЕсли ЗначениеПараметра = "Пометка" Тогда
|
||
ПараметрыВыполнения.УдалятьНепосредственно = Ложь;
|
||
ПараметрыВыполнения.ПомечатьНаУдаление = Истина;
|
||
КонецЕсли;
|
||
|
||
ЗначениеПараметра = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыЗамены, "ВключатьБизнесЛогику");
|
||
Если ТипЗнч(ЗначениеПараметра) = Тип("Булево") Тогда
|
||
ПараметрыВыполнения.ВключатьБизнесЛогику = ЗначениеПараметра;
|
||
КонецЕсли;
|
||
|
||
ЗначениеПараметра = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыЗамены, "ПривилегированнаяЗапись");
|
||
Если ТипЗнч(ЗначениеПараметра) = Тип("Булево") Тогда
|
||
ПараметрыВыполнения.ПривилегированнаяЗапись = ЗначениеПараметра;
|
||
КонецЕсли;
|
||
|
||
ЗначениеПараметра = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыЗамены, "УчитыватьПрикладныеПравила");
|
||
Если ТипЗнч(ЗначениеПараметра) = Тип("Булево") Тогда
|
||
ПараметрыВыполнения.УчитыватьПрикладныеПравила = ЗначениеПараметра;
|
||
КонецЕсли;
|
||
|
||
ЗначениеПараметра = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыЗамены, "МестаЗамены", Новый Массив);
|
||
Если (ЗначениеПараметра.Количество() > 0) Тогда
|
||
ПараметрыВыполнения.МестаЗамены = Новый Массив(Новый ФиксированныйМассив(ЗначениеПараметра));
|
||
КонецЕсли;
|
||
|
||
Возврат ПараметрыВыполнения;
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область МестаИспользования
|
||
|
||
Функция ОписаниеТипаКлючиЗаписей()
|
||
|
||
ДобавляемыеТипы = Новый Массив;
|
||
Для Каждого Мета Из Метаданные.РегистрыСведений Цикл
|
||
ДобавляемыеТипы.Добавить(Тип("РегистрСведенийКлючЗаписи." + Мета.Имя));
|
||
КонецЦикла;
|
||
Для Каждого Мета Из Метаданные.РегистрыНакопления Цикл
|
||
ДобавляемыеТипы.Добавить(Тип("РегистрНакопленияКлючЗаписи." + Мета.Имя));
|
||
КонецЦикла;
|
||
Для Каждого Мета Из Метаданные.РегистрыБухгалтерии Цикл
|
||
ДобавляемыеТипы.Добавить(Тип("РегистрБухгалтерииКлючЗаписи." + Мета.Имя));
|
||
КонецЦикла;
|
||
Для Каждого Мета Из Метаданные.РегистрыРасчета Цикл
|
||
ДобавляемыеТипы.Добавить(Тип("РегистрРасчетаКлючЗаписи." + Мета.Имя));
|
||
КонецЦикла;
|
||
|
||
Возврат Новый ОписаниеТипов(ДобавляемыеТипы);
|
||
КонецФункции
|
||
|
||
Функция ОписаниеИзмеренийНабора(Знач МетаданныеРегистра, КэшИзмеренийРегистров)
|
||
|
||
ОписаниеИзмерений = КэшИзмеренийРегистров[МетаданныеРегистра];
|
||
Если ОписаниеИзмерений <> Неопределено Тогда
|
||
Возврат ОписаниеИзмерений;
|
||
КонецЕсли;
|
||
|
||
// Период и регистратор, если есть.
|
||
ОписаниеИзмерений = Новый Структура;
|
||
|
||
ДанныеИзмерения = Новый Структура("Ведущее, Представление, Формат, Тип", Ложь);
|
||
|
||
Если Метаданные.РегистрыСведений.Содержит(МетаданныеРегистра) Тогда
|
||
// Возможно есть период
|
||
МетаПериод = МетаданныеРегистра.ПериодичностьРегистраСведений;
|
||
Периодичность = Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений;
|
||
|
||
Если МетаПериод = Периодичность.ПозицияРегистратора Тогда
|
||
ДанныеИзмерения.Тип = Документы.ТипВсеСсылки();
|
||
ДанныеИзмерения.Представление = НСтр("ru = 'Регистратор'");
|
||
ДанныеИзмерения.Ведущее = Истина;
|
||
ОписаниеИзмерений.Вставить("Регистратор", ДанныеИзмерения);
|
||
|
||
ИначеЕсли МетаПериод = Периодичность.Год Тогда
|
||
ДанныеИзмерения.Тип = Новый ОписаниеТипов("Дата");
|
||
ДанныеИзмерения.Представление = НСтр("ru = 'Период'");
|
||
ДанныеИзмерения.Формат = НСтр("ru = 'ДФ=''yyyy ""г.""''; ДП=''Дата не задана'''");
|
||
ОписаниеИзмерений.Вставить("Период", ДанныеИзмерения);
|
||
|
||
ИначеЕсли МетаПериод = Периодичность.День Тогда
|
||
ДанныеИзмерения.Тип = Новый ОписаниеТипов("Дата");
|
||
ДанныеИзмерения.Представление = НСтр("ru = 'Период'");
|
||
ДанныеИзмерения.Формат = НСтр("ru = 'ДЛФ=D; ДП=''Дата не задана'''");
|
||
ОписаниеИзмерений.Вставить("Период", ДанныеИзмерения);
|
||
|
||
ИначеЕсли МетаПериод = Периодичность.Квартал Тогда
|
||
ДанныеИзмерения.Тип = Новый ОписаниеТипов("Дата");
|
||
ДанныеИзмерения.Представление = НСтр("ru = 'Период'");
|
||
ДанныеИзмерения.Формат = НСтр("ru = 'ДФ=''к """"квартал """"yyyy """"г.""""''; ДП=''Дата не задана'''");
|
||
ОписаниеИзмерений.Вставить("Период", ДанныеИзмерения);
|
||
|
||
ИначеЕсли МетаПериод = Периодичность.Месяц Тогда
|
||
ДанныеИзмерения.Тип = Новый ОписаниеТипов("Дата");
|
||
ДанныеИзмерения.Представление = НСтр("ru = 'Период'");
|
||
ДанныеИзмерения.Формат = НСтр("ru = 'ДФ=''ММММ yyyy """"г.""""''; ДП=''Дата не задана'''");
|
||
ОписаниеИзмерений.Вставить("Период", ДанныеИзмерения);
|
||
|
||
ИначеЕсли МетаПериод = Периодичность.Секунда Тогда
|
||
ДанныеИзмерения.Тип = Новый ОписаниеТипов("Дата");
|
||
ДанныеИзмерения.Представление = НСтр("ru = 'Период'");
|
||
ДанныеИзмерения.Формат = НСтр("ru = 'ДЛФ=DT; ДП=''Дата не задана'''");
|
||
ОписаниеИзмерений.Вставить("Период", ДанныеИзмерения);
|
||
|
||
КонецЕсли;
|
||
|
||
Иначе
|
||
ДанныеИзмерения.Тип = Документы.ТипВсеСсылки();
|
||
ДанныеИзмерения.Представление = НСтр("ru = 'Регистратор'");
|
||
ДанныеИзмерения.Ведущее = Истина;
|
||
ОписаниеИзмерений.Вставить("Регистратор", ДанныеИзмерения);
|
||
|
||
КонецЕсли;
|
||
|
||
// Все измерения
|
||
Для Каждого МетаИзмерение Из МетаданныеРегистра.Измерения Цикл
|
||
ДанныеИзмерения = Новый Структура("Ведущее, Представление, Формат, Тип");
|
||
ДанныеИзмерения.Тип = МетаИзмерение.Тип;
|
||
ДанныеИзмерения.Представление = МетаИзмерение.Представление();
|
||
ДанныеИзмерения.Ведущее = МетаИзмерение.Ведущее;
|
||
ОписаниеИзмерений.Вставить(МетаИзмерение.Имя, ДанныеИзмерения);
|
||
КонецЦикла;
|
||
|
||
КэшИзмеренийРегистров[МетаданныеРегистра] = ОписаниеИзмерений;
|
||
Возврат ОписаниеИзмерений;
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#КонецОбласти
|
||
|
||
#Область УсловныеВызовы
|
||
|
||
// Возвращает серверный модуль менеджера по имени объекта.
|
||
Функция СерверныйМодульМенеджера(Имя)
|
||
ОбъектНайден = Ложь;
|
||
|
||
ЧастиИмени = СтрРазделить(Имя, ".");
|
||
Если ЧастиИмени.Количество() = 2 Тогда
|
||
|
||
ИмяВида = ВРег(ЧастиИмени[0]);
|
||
ИмяОбъекта = ЧастиИмени[1];
|
||
|
||
Если ИмяВида = ВРег("Константы") Тогда
|
||
Если Метаданные.Константы.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("РегистрыСведений") Тогда
|
||
Если Метаданные.РегистрыСведений.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("РегистрыНакопления") Тогда
|
||
Если Метаданные.РегистрыНакопления.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("РегистрыБухгалтерии") Тогда
|
||
Если Метаданные.РегистрыБухгалтерии.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("РегистрыРасчета") Тогда
|
||
Если Метаданные.РегистрыРасчета.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("Справочники") Тогда
|
||
Если Метаданные.Справочники.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("Документы") Тогда
|
||
Если Метаданные.Документы.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("Отчеты") Тогда
|
||
Если Метаданные.Отчеты.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("Обработки") Тогда
|
||
Если Метаданные.Обработки.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("БизнесПроцессы") Тогда
|
||
Если Метаданные.БизнесПроцессы.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("ЖурналыДокументов") Тогда
|
||
Если Метаданные.ЖурналыДокументов.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("Задачи") Тогда
|
||
Если Метаданные.Задачи.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("ПланыСчетов") Тогда
|
||
Если Метаданные.ПланыСчетов.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("ПланыОбмена") Тогда
|
||
Если Метаданные.ПланыОбмена.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("ПланыВидовХарактеристик") Тогда
|
||
Если Метаданные.ПланыВидовХарактеристик.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
ИначеЕсли ИмяВида = ВРег("ПланыВидовРасчета") Тогда
|
||
Если Метаданные.ПланыВидовРасчета.Найти(ИмяОбъекта) <> Неопределено Тогда
|
||
ОбъектНайден = Истина;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
|
||
Если Не ОбъектНайден Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверное значение параметра %1 в функции %2. Объект метаданных ""%3"" не существует.'"),
|
||
"Имя", "ОбщегоНазначения.СерверныйМодульМенеджера", Имя),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
// АПК:488-выкл ВычислитьВБезопасномРежиме не используется, чтобы избежать вызова ОбщийМодуль рекурсивно.
|
||
УстановитьБезопасныйРежим(Истина);
|
||
Модуль = Вычислить(Имя);
|
||
// АПК:488-вкл
|
||
|
||
Возврат Модуль;
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область Данные
|
||
|
||
Функция СравниваемыеКолонки(Знач КоллекцияСтрок, Знач ИменаКолонок, Знач ИсключаяКолонки)
|
||
|
||
Если ПустаяСтрока(ИменаКолонок) Тогда
|
||
|
||
ТипКоллекции = ТипЗнч(КоллекцияСтрок);
|
||
ЭтоСписокЗначений = (ТипКоллекции = Тип("СписокЗначений"));
|
||
ЭтоТаблицаЗначений = (ТипКоллекции = Тип("ТаблицаЗначений"));
|
||
ЭтоКоллекцияКлючИЗначение = (ТипКоллекции = Тип("Соответствие"))
|
||
Или (ТипКоллекции = Тип("Структура"))
|
||
Или (ТипКоллекции = Тип("ФиксированноеСоответствие"))
|
||
Или (ТипКоллекции = Тип("ФиксированнаяСтруктура"));
|
||
|
||
СравниваемыеКолонки = Новый Массив;
|
||
Если ЭтоТаблицаЗначений Тогда
|
||
Для Каждого Колонка Из КоллекцияСтрок.Колонки Цикл
|
||
СравниваемыеКолонки.Добавить(Колонка.Имя);
|
||
КонецЦикла;
|
||
ИначеЕсли ЭтоСписокЗначений Тогда
|
||
СравниваемыеКолонки.Добавить("Значение");
|
||
СравниваемыеКолонки.Добавить("Картинка");
|
||
СравниваемыеКолонки.Добавить("Пометка");
|
||
СравниваемыеКолонки.Добавить("Представление");
|
||
ИначеЕсли ЭтоКоллекцияКлючИЗначение Тогда
|
||
СравниваемыеКолонки.Добавить("Ключ");
|
||
СравниваемыеКолонки.Добавить("Значение");
|
||
Иначе
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверное значение параметра %1 (тип %2) в %3. Укажите имена полей, по которым производится сравнение.'"),
|
||
"КоллекцияСтрок1", ТипКоллекции, "ОбщегоНазначения.КоллекцииИдентичны"),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
Иначе
|
||
СравниваемыеКолонки = СтрРазделить(СтрЗаменить(ИменаКолонок, " ", ""), ",");
|
||
КонецЕсли;
|
||
|
||
// Вычитаем исключаемые поля
|
||
Если Не ПустаяСтрока(ИсключаяКолонки) Тогда
|
||
ИсключаяКолонки = СтрРазделить(СтрЗаменить(ИсключаяКолонки, " ", ""), ",");
|
||
СравниваемыеКолонки = ОбщегоНазначенияКлиентСервер.РазностьМассивов(СравниваемыеКолонки, ИсключаяКолонки);
|
||
КонецЕсли;
|
||
Возврат СравниваемыеКолонки;
|
||
|
||
КонецФункции
|
||
|
||
Функция СравнитьСУчетомПоследовательности(Знач КоллекцияСтрок1, Знач КоллекцияСтрок2, Знач СравниваемыеКолонки)
|
||
|
||
ТипКоллекции = ТипЗнч(КоллекцияСтрок1);
|
||
СравниваютсяМассивы = (ТипКоллекции = Тип("Массив") Или ТипКоллекции = Тип("ФиксированныйМассив"));
|
||
|
||
// Параллельный обход обеих коллекций.
|
||
НомерСтрокиКоллекции1 = 0;
|
||
Для Каждого СтрокаКоллекции1 Из КоллекцияСтрок1 Цикл
|
||
// Спозиционируемся на аналогичную строку второй коллекции.
|
||
НомерСтрокиКоллекции2 = 0;
|
||
ЕстьСтрокиКоллекции2 = Ложь;
|
||
Для Каждого СтрокаКоллекции2 Из КоллекцияСтрок2 Цикл
|
||
ЕстьСтрокиКоллекции2 = Истина;
|
||
Если НомерСтрокиКоллекции2 = НомерСтрокиКоллекции1 Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
НомерСтрокиКоллекции2 = НомерСтрокиКоллекции2 + 1;
|
||
КонецЦикла;
|
||
Если Не ЕстьСтрокиКоллекции2 Тогда
|
||
// Во второй коллекции вообще нет строк.
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
// Сравниваем значения полей двух строк.
|
||
Если СравниваютсяМассивы Тогда
|
||
Если СтрокаКоллекции1 <> СтрокаКоллекции2 Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
Иначе
|
||
Для Каждого ИмяКолонки Из СравниваемыеКолонки Цикл
|
||
Если СтрокаКоллекции1[ИмяКолонки] <> СтрокаКоллекции2[ИмяКолонки] Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
НомерСтрокиКоллекции1 = НомерСтрокиКоллекции1 + 1;
|
||
КонецЦикла;
|
||
|
||
КоличествоСтрокКоллекции1 = НомерСтрокиКоллекции1;
|
||
|
||
// Отдельно подсчитаем количество строк второй коллекции.
|
||
КоличествоСтрокКоллекции2 = 0;
|
||
Для Каждого СтрокаКоллекции2 Из КоллекцияСтрок2 Цикл
|
||
КоличествоСтрокКоллекции2 = КоличествоСтрокКоллекции2 + 1;
|
||
КонецЦикла;
|
||
|
||
// Если в первой коллекции не оказалось строк,
|
||
// то их не должно быть и во второй.
|
||
Если КоличествоСтрокКоллекции1 = 0 Тогда
|
||
Для Каждого СтрокаКоллекции2 Из КоллекцияСтрок2 Цикл
|
||
Возврат Ложь;
|
||
КонецЦикла;
|
||
КоличествоСтрокКоллекции2 = 0;
|
||
КонецЕсли;
|
||
|
||
// Количество строк не должно отличаться.
|
||
Если КоличествоСтрокКоллекции1 <> КоличествоСтрокКоллекции2 Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
Функция СравнитьБезУчетаПоследовательности(Знач КоллекцияСтрок1, Знач КоллекцияСтрок2, Знач СравниваемыеКолонки)
|
||
|
||
// Строки отбора накапливаем по первой коллекции для того, чтобы:
|
||
// - повторно не искать одинаковые строки,
|
||
// - убедиться, что во второй коллекции ни одной такой строки, которой нет в накопленных.
|
||
|
||
СтрокиОтбора = Новый ТаблицаЗначений;
|
||
ПараметрыОтбора = Новый Структура;
|
||
Для Каждого ИмяКолонки Из СравниваемыеКолонки Цикл
|
||
СтрокиОтбора.Колонки.Добавить(ИмяКолонки);
|
||
ПараметрыОтбора.Вставить(ИмяКолонки);
|
||
КонецЦикла;
|
||
|
||
ЕстьСтрокиКоллекции1 = Ложь;
|
||
Для Каждого СтрокаОтбора Из КоллекцияСтрок1 Цикл
|
||
|
||
ЗаполнитьЗначенияСвойств(ПараметрыОтбора, СтрокаОтбора);
|
||
Если СтрокиОтбора.НайтиСтроки(ПараметрыОтбора).Количество() > 0 Тогда
|
||
// Строку с такими полями уже искали.
|
||
Продолжить;
|
||
КонецЕсли;
|
||
ЗаполнитьЗначенияСвойств(СтрокиОтбора.Добавить(), СтрокаОтбора);
|
||
|
||
// Подсчитаем количество таких строк в первой коллекции.
|
||
НайденоСтрокКоллекции1 = 0;
|
||
Для Каждого СтрокаКоллекции1 Из КоллекцияСтрок1 Цикл
|
||
СтрокаПодходит = Истина;
|
||
Для Каждого ИмяКолонки Из СравниваемыеКолонки Цикл
|
||
Если СтрокаКоллекции1[ИмяКолонки] <> СтрокаОтбора[ИмяКолонки] Тогда
|
||
СтрокаПодходит = Ложь;
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если СтрокаПодходит Тогда
|
||
НайденоСтрокКоллекции1 = НайденоСтрокКоллекции1 + 1;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
// Подсчитаем количество таких строк во второй коллекции.
|
||
НайденоСтрокКоллекции2 = 0;
|
||
Для Каждого СтрокаКоллекции2 Из КоллекцияСтрок2 Цикл
|
||
СтрокаПодходит = Истина;
|
||
Для Каждого ИмяКолонки Из СравниваемыеКолонки Цикл
|
||
Если СтрокаКоллекции2[ИмяКолонки] <> СтрокаОтбора[ИмяКолонки] Тогда
|
||
СтрокаПодходит = Ложь;
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если СтрокаПодходит Тогда
|
||
НайденоСтрокКоллекции2 = НайденоСтрокКоллекции2 + 1;
|
||
// Если количество таких строк во второй коллекции превысило количество в первой,
|
||
// то уже можно сделать вывод, что коллекции не идентичны.
|
||
Если НайденоСтрокКоллекции2 > НайденоСтрокКоллекции1 Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
// Количество таких строк не должно отличаться.
|
||
Если НайденоСтрокКоллекции1 <> НайденоСтрокКоллекции2 Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
ЕстьСтрокиКоллекции1 = Истина;
|
||
|
||
КонецЦикла;
|
||
|
||
// Если в первой коллекции не оказалось строк,
|
||
// то их не должно быть и во второй.
|
||
Если Не ЕстьСтрокиКоллекции1 Тогда
|
||
Для Каждого СтрокаКоллекции2 Из КоллекцияСтрок2 Цикл
|
||
Возврат Ложь;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
// Проверим, что во второй коллекции нет ни одной такой строки, которой нет в накопленных.
|
||
Для Каждого СтрокаКоллекции2 Из КоллекцияСтрок2 Цикл
|
||
ЗаполнитьЗначенияСвойств(ПараметрыОтбора, СтрокаКоллекции2);
|
||
Если СтрокиОтбора.НайтиСтроки(ПараметрыОтбора).Количество() = 0 Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
Функция СравнитьМассивы(Знач Массив1, Знач Массив2)
|
||
|
||
Если Массив1.Количество() <> Массив2.Количество() Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
|
||
Для Каждого Элемент Из Массив1 Цикл
|
||
Если Массив2.Найти(Элемент) = Неопределено Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
Процедура ПроверкаФиксированностиДанных(Данные, ДанныеВЗначенииФиксированныхТипов = Ложь)
|
||
|
||
ТипДанных = ТипЗнч(Данные);
|
||
СоставТипов = Новый ОписаниеТипов(
|
||
"ХранилищеЗначения,
|
||
|ФиксированныйМассив,
|
||
|ФиксированнаяСтруктура,
|
||
|ФиксированноеСоответствие");
|
||
|
||
Если СоставТипов.СодержитТип(ТипДанных) Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
Если ДанныеВЗначенииФиксированныхТипов Тогда
|
||
|
||
СоставТипов = Новый ОписаниеТипов(
|
||
"Булево,Строка,Число,Дата,
|
||
|Неопределено,УникальныйИдентификатор,Null,Тип,
|
||
|РежимОтправкиИнформацииОбОшибке,
|
||
|ХранилищеЗначения,ОбщийМодуль,ОбъектМетаданных,
|
||
|ТипЗначенияXDTO,ТипОбъектаXDTO,
|
||
|ИдентификаторОбсужденияСистемыВзаимодействия");
|
||
|
||
Если СоставТипов.СодержитТип(ТипДанных)
|
||
Или ЭтоСсылка(ТипДанных) Тогда
|
||
|
||
Возврат;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверное значение параметра %1 в функции %2. Данные типа %3 не могут быть зафиксированы.'"),
|
||
"Данные", "ОбщегоНазначения.ФиксированныеДанные", Строка(ТипДанных)),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция РазмерСтрокиВБайтах(Знач Строка)
|
||
|
||
Возврат ПолучитьДвоичныеДанныеИзСтроки(Строка, "UTF-8").Размер();
|
||
|
||
КонецФункции
|
||
|
||
#Область СкопироватьРекурсивно
|
||
|
||
Функция СкопироватьСтруктуру(СтруктураИсточник, ФиксироватьДанные)
|
||
|
||
СтруктураРезультат = Новый Структура;
|
||
|
||
Для Каждого КлючИЗначение Из СтруктураИсточник Цикл
|
||
СтруктураРезультат.Вставить(КлючИЗначение.Ключ, СкопироватьРекурсивно(КлючИЗначение.Значение, ФиксироватьДанные));
|
||
КонецЦикла;
|
||
|
||
Если ФиксироватьДанные = Истина
|
||
Или ФиксироватьДанные = Неопределено
|
||
И ТипЗнч(СтруктураИсточник) = Тип("ФиксированнаяСтруктура") Тогда
|
||
|
||
Возврат Новый ФиксированнаяСтруктура(СтруктураРезультат);
|
||
КонецЕсли;
|
||
|
||
Возврат СтруктураРезультат;
|
||
|
||
КонецФункции
|
||
|
||
Функция СкопироватьСоответствие(СоответствиеИсточник, ФиксироватьДанные)
|
||
|
||
СоответствиеРезультат = Новый Соответствие;
|
||
|
||
Для Каждого КлючИЗначение Из СоответствиеИсточник Цикл
|
||
СоответствиеРезультат.Вставить(КлючИЗначение.Ключ, СкопироватьРекурсивно(КлючИЗначение.Значение, ФиксироватьДанные));
|
||
КонецЦикла;
|
||
|
||
Если ФиксироватьДанные = Истина
|
||
Или ФиксироватьДанные = Неопределено
|
||
И ТипЗнч(СоответствиеИсточник) = Тип("ФиксированноеСоответствие") Тогда
|
||
Возврат Новый ФиксированноеСоответствие(СоответствиеРезультат);
|
||
КонецЕсли;
|
||
|
||
Возврат СоответствиеРезультат;
|
||
|
||
КонецФункции
|
||
|
||
Функция СкопироватьМассив(МассивИсточник, ФиксироватьДанные)
|
||
|
||
МассивРезультат = Новый Массив;
|
||
|
||
Для Каждого Элемент Из МассивИсточник Цикл
|
||
МассивРезультат.Добавить(СкопироватьРекурсивно(Элемент, ФиксироватьДанные));
|
||
КонецЦикла;
|
||
|
||
Если ФиксироватьДанные = Истина
|
||
Или ФиксироватьДанные = Неопределено
|
||
И ТипЗнч(МассивИсточник) = Тип("ФиксированныйМассив") Тогда
|
||
Возврат Новый ФиксированныйМассив(МассивРезультат);
|
||
КонецЕсли;
|
||
|
||
Возврат МассивРезультат;
|
||
|
||
КонецФункции
|
||
|
||
Функция СкопироватьСписокЗначений(СписокИсточник, ФиксироватьДанные)
|
||
|
||
СписокРезультат = Новый СписокЗначений;
|
||
|
||
Для Каждого ЭлементСписка Из СписокИсточник Цикл
|
||
СписокРезультат.Добавить(
|
||
СкопироватьРекурсивно(ЭлементСписка.Значение, ФиксироватьДанные),
|
||
ЭлементСписка.Представление,
|
||
ЭлементСписка.Пометка,
|
||
ЭлементСписка.Картинка);
|
||
КонецЦикла;
|
||
|
||
Возврат СписокРезультат;
|
||
|
||
КонецФункции
|
||
|
||
Процедура СкопироватьЗначенияТаблицыЗначений(ТаблицаЗначений, ФиксироватьДанные)
|
||
Для Каждого СтрокаТаблицыЗначений Из ТаблицаЗначений Цикл
|
||
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
|
||
СтрокаТаблицыЗначений[Колонка.Имя] = СкопироватьРекурсивно(СтрокаТаблицыЗначений[Колонка.Имя], ФиксироватьДанные);
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
КонецПроцедуры
|
||
|
||
Процедура СкопироватьЗначенияСтрокиДереваЗначений(СтрокиДереваЗначений, ФиксироватьДанные);
|
||
Для Каждого СтрокаДереваЗначений Из СтрокиДереваЗначений Цикл
|
||
Для Каждого Колонка Из СтрокаДереваЗначений.Владелец().Колонки Цикл
|
||
СтрокаДереваЗначений[Колонка.Имя] = СкопироватьРекурсивно(СтрокаДереваЗначений[Колонка.Имя], ФиксироватьДанные);
|
||
КонецЦикла;
|
||
СкопироватьЗначенияСтрокиДереваЗначений(СтрокаДереваЗначений.Строки, ФиксироватьДанные);
|
||
КонецЦикла;
|
||
КонецПроцедуры
|
||
|
||
#КонецОбласти
|
||
|
||
#КонецОбласти
|
||
|
||
#Область Метаданные
|
||
|
||
Процедура ПроверитьОбъектМетаданныхСуществует(ПолноеИмя)
|
||
|
||
Если ОбъектМетаданныхПоПолномуИмени(ПолноеИмя) = Неопределено Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Несуществующий тип объекта метаданных ""%1"".'"), ПолноеИмя),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
#КонецОбласти
|
||
|
||
#Область ХранилищеНастроек
|
||
|
||
Процедура ХранилищеСохранить(МенеджерХранилища, КлючОбъекта, КлючНастроек, Настройки,
|
||
ОписаниеНастроек, ИмяПользователя, ОбновитьПовторноИспользуемыеЗначения)
|
||
|
||
Если Не ПравоДоступа("СохранениеДанныхПользователя", Метаданные) Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
МенеджерХранилища.Сохранить(КлючОбъекта, КлючНастроек(КлючНастроек), Настройки,
|
||
ОписаниеНастроек, ИмяПользователя);
|
||
|
||
Если ОбновитьПовторноИспользуемыеЗначения Тогда
|
||
ОбновитьПовторноИспользуемыеЗначения();
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция ХранилищеЗагрузить(МенеджерХранилища, КлючОбъекта, КлючНастроек, ЗначениеПоУмолчанию,
|
||
ОписаниеНастроек, ИмяПользователя)
|
||
|
||
Результат = Неопределено;
|
||
|
||
Если ПравоДоступа("СохранениеДанныхПользователя", Метаданные) Тогда
|
||
Результат = МенеджерХранилища.Загрузить(КлючОбъекта, КлючНастроек(КлючНастроек),
|
||
ОписаниеНастроек, ИмяПользователя);
|
||
КонецЕсли;
|
||
|
||
Если Результат = Неопределено Тогда
|
||
Результат = ЗначениеПоУмолчанию;
|
||
Иначе
|
||
УстановитьПривилегированныйРежим(Истина);
|
||
Если ОчиститьНесуществующиеСсылки(Результат) Тогда
|
||
Результат = ЗначениеПоУмолчанию;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Удаляет из переданной коллекции ссылки, ссылающиеся на несуществующие данные в информационной базе.
|
||
// Не очищает переданное значение, если в нем передана несуществующая ссылка, а возвращает Ложь.
|
||
//
|
||
// Параметры:
|
||
// Значение - ЛюбаяСсылка
|
||
// - Произвольный - проверяемое значение или коллекция.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если Значение ссылочного типа и объект не существует в информационной базе.
|
||
// Ложь, если Значение не ссылочного типа или объект существует.
|
||
//
|
||
Функция ОчиститьНесуществующиеСсылки(Значение)
|
||
|
||
Тип = ТипЗнч(Значение);
|
||
Если Тип = Тип("Неопределено")
|
||
Или Тип = Тип("Булево")
|
||
Или Тип = Тип("Строка")
|
||
Или Тип = Тип("Число")
|
||
Или Тип = Тип("Дата") Тогда // Оптимизация - часто используемые примитивные типы.
|
||
|
||
Возврат Ложь; // Не ссылка.
|
||
|
||
ИначеЕсли Тип = Тип("Массив") Тогда
|
||
|
||
Количество = Значение.Количество();
|
||
Для Номер = 1 По Количество Цикл
|
||
ОбратныйИндекс = Количество - Номер;
|
||
// @skip-check query-in-loop - выборка ссылок из разных таблиц.
|
||
Если ОчиститьНесуществующиеСсылки(Значение[ОбратныйИндекс]) Тогда
|
||
Значение.Удалить(ОбратныйИндекс);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат Ложь; // Не ссылка.
|
||
|
||
ИначеЕсли Тип = Тип("Структура")
|
||
Или Тип = Тип("Соответствие") Тогда
|
||
|
||
Для Каждого КлючИЗначение Из Значение Цикл
|
||
// @skip-check query-in-loop - выборка ссылок из разных таблиц.
|
||
Если ОчиститьНесуществующиеСсылки(КлючИЗначение.Значение) Тогда
|
||
Значение.Вставить(КлючИЗначение.Ключ, Неопределено);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат Ложь; // Не ссылка.
|
||
|
||
ИначеЕсли Документы.ТипВсеСсылки().СодержитТип(Тип)
|
||
Или Справочники.ТипВсеСсылки().СодержитТип(Тип)
|
||
Или Перечисления.ТипВсеСсылки().СодержитТип(Тип)
|
||
Или ПланыВидовХарактеристик.ТипВсеСсылки().СодержитТип(Тип)
|
||
Или ПланыСчетов.ТипВсеСсылки().СодержитТип(Тип)
|
||
Или ПланыВидовРасчета.ТипВсеСсылки().СодержитТип(Тип)
|
||
Или ПланыОбмена.ТипВсеСсылки().СодержитТип(Тип)
|
||
Или БизнесПроцессы.ТипВсеСсылки().СодержитТип(Тип)
|
||
Или Задачи.ТипВсеСсылки().СодержитТип(Тип) Тогда
|
||
// Ссылочный тип, исключая ТочкаМаршрутаБизнесПроцессаСсылка.
|
||
|
||
Если Значение.Пустая() Тогда
|
||
Возврат Ложь; // Ссылка пустая.
|
||
КонецЕсли;
|
||
Возврат ЗначениеРеквизитаОбъекта(Значение, "Ссылка") = Неопределено;
|
||
|
||
Иначе
|
||
Возврат Ложь; // Не ссылка.
|
||
КонецЕсли;
|
||
|
||
КонецФункции
|
||
|
||
Процедура ХранилищеУдалить(МенеджерХранилища, КлючОбъекта, КлючНастроек, ИмяПользователя)
|
||
|
||
Если ПравоДоступа("СохранениеДанныхПользователя", Метаданные) Тогда
|
||
МенеджерХранилища.Удалить(КлючОбъекта, КлючНастроек(КлючНастроек), ИмяПользователя);
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Возвращает строку ключа настроек, не превышающую допустимую длину 128 символов.
|
||
// Если указанная строка превышает 128, тогда вместо символов сверх 96 символов
|
||
// добавляется их хеш-сумма по алгоритму MD5 размером 32 символа.
|
||
//
|
||
// Параметры:
|
||
// Строка - Строка - строка произвольной длины.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка - не более 128 символов.
|
||
//
|
||
Функция КлючНастроек(Знач Строка)
|
||
Возврат СократитьСтрокуКонтрольнойСуммой(Строка, 128);
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область БезопасноеХранилище
|
||
|
||
Функция ДанныеИзБезопасногоХранилища(Владельцы, Ключи, ОбщиеДанные)
|
||
|
||
ИмяБезопасногоХранилищаДанных = "РегистрСведений.БезопасноеХранилищеДанных";
|
||
Если РазделениеВключено() И ДоступноИспользованиеРазделенныхДанных() И ОбщиеДанные <> Истина Тогда
|
||
ИмяБезопасногоХранилищаДанных = "РегистрСведений.БезопасноеХранилищеДанныхОбластейДанных";
|
||
КонецЕсли;
|
||
|
||
ТекстЗапроса =
|
||
"ВЫБРАТЬ
|
||
| БезопасноеХранилищеДанных.Владелец КАК ВладелецДанных,
|
||
| БезопасноеХранилищеДанных.Данные КАК Данные
|
||
|ИЗ
|
||
| #ИмяБезопасногоХранилищаДанных КАК БезопасноеХранилищеДанных
|
||
|ГДЕ
|
||
| БезопасноеХранилищеДанных.Владелец В (&Владельцы)";
|
||
|
||
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ИмяБезопасногоХранилищаДанных", ИмяБезопасногоХранилищаДанных);
|
||
Запрос = Новый Запрос(ТекстЗапроса);
|
||
Запрос.УстановитьПараметр("Владельцы", Владельцы);
|
||
РезультатЗапроса = Запрос.Выполнить().Выбрать();
|
||
|
||
Результат = Новый Соответствие();
|
||
|
||
НаборДанныхКлюча = ?(ЗначениеЗаполнено(Ключи) И СтрНайти(Ключи, ","), Новый Структура(Ключи), Неопределено);
|
||
Для Каждого ВладелецДанных Из Владельцы Цикл
|
||
Результат.Вставить(ВладелецДанных, НаборДанныхКлюча);
|
||
КонецЦикла;
|
||
|
||
Пока РезультатЗапроса.Следующий() Цикл
|
||
|
||
ДанныеВладельца = Новый Структура(Ключи);
|
||
|
||
Если ЗначениеЗаполнено(РезультатЗапроса.Данные) Тогда
|
||
|
||
СохраненныеДанные = РезультатЗапроса.Данные.Получить();
|
||
Если ЗначениеЗаполнено(СохраненныеДанные) Тогда
|
||
|
||
Если ЗначениеЗаполнено(Ключи) Тогда
|
||
ВладелецДанных = Результат[РезультатЗапроса.ВладелецДанных];
|
||
ЗаполнитьЗначенияСвойств(ДанныеВладельца, СохраненныеДанные);
|
||
Иначе
|
||
ДанныеВладельца = СохраненныеДанные;
|
||
КонецЕсли;
|
||
|
||
Если Ключи <> Неопределено
|
||
И ДанныеВладельца <> Неопределено
|
||
И ДанныеВладельца.Количество() = 1 Тогда
|
||
ЗначениеПоКлючу = ?(ДанныеВладельца.Свойство(Ключи), ДанныеВладельца[Ключи], Неопределено);
|
||
Результат.Вставить(РезультатЗапроса.ВладелецДанных, ЗначениеПоКлючу);
|
||
Иначе
|
||
Результат.Вставить(РезультатЗапроса.ВладелецДанных, ДанныеВладельца);
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Возврат Результат;
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область БезопасноеВыполнениеВнешнегоКода
|
||
|
||
// Проверяет, что переданное имя ИмяПроцедуры является именем экспортной процедуры конфигурации.
|
||
// Может использоваться для проверки, что переданная строка не содержит произвольного алгоритма
|
||
// на встроенном языке 1С:Предприятия перед использованием его в операторах Выполнить и Вычислить
|
||
// при их использовании для динамического вызова методов код конфигурации.
|
||
//
|
||
// В случае если переданная строка не является именем процедуры конфигурации, генерируется исключение.
|
||
//
|
||
// Предназначена для вызова из см. процедуру ВыполнитьМетодКонфигурации.
|
||
//
|
||
// Параметры:
|
||
// ИмяПроцедуры - Строка - проверяемое имя экспортной процедуры.
|
||
//
|
||
Процедура ПроверитьИмяПроцедурыКонфигурации(Знач ИмяПроцедуры)
|
||
|
||
ЧастиИмени = СтрРазделить(ИмяПроцедуры, ".");
|
||
Если ЧастиИмени.Количество() <> 2 И ЧастиИмени.Количество() <> 3 Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неправильный формат параметра %1 (передано значение: ""%2"") в %3.'"),
|
||
"ИмяПроцедуры", ИмяПроцедуры, "ОбщегоНазначения.ВыполнитьМетодКонфигурации"),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
ИмяОбъекта = ЧастиИмени[0];
|
||
Если ЧастиИмени.Количество() = 2 И Метаданные.ОбщиеМодули.Найти(ИмяОбъекта) = Неопределено Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неправильный формат параметра %1 (передано значение: ""%2"") в %3:
|
||
|Не существует общий модуль ""%4"".'"),
|
||
"ИмяПроцедуры", ИмяПроцедуры, "ОбщегоНазначения.ВыполнитьМетодКонфигурации", ИмяОбъекта),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
|
||
Если ЧастиИмени.Количество() = 3 Тогда
|
||
ПолноеИмяОбъекта = ЧастиИмени[0] + "." + ЧастиИмени[1];
|
||
Попытка
|
||
Менеджер = МенеджерОбъектаПоИмени(ПолноеИмяОбъекта);
|
||
Исключение
|
||
Менеджер = Неопределено;
|
||
КонецПопытки;
|
||
Если Менеджер = Неопределено Тогда
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неправильный формат параметра %1 (передано значение: ""%2"") в %3:
|
||
|Не существует менеджер объекта ""%4"".'"),
|
||
"ИмяПроцедуры", ИмяПроцедуры, "ОбщегоНазначения.ВыполнитьМетодКонфигурации", ПолноеИмяОбъекта),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
ИмяМетодаОбъекта = ЧастиИмени[ЧастиИмени.ВГраница()];
|
||
ВременнаяСтруктура = Новый Структура;
|
||
Попытка
|
||
// Проверка того, что ИмяПроцедуры является допустимым идентификатором.
|
||
// Например: МояПроцедура.
|
||
ВременнаяСтруктура.Вставить(ИмяМетодаОбъекта);
|
||
Исключение
|
||
ЗаписьЖурналаРегистрации(НСтр("ru = 'Безопасное выполнение метода'", КодОсновногоЯзыка()),
|
||
УровеньЖурналаРегистрации.Ошибка, , , ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неправильный формат параметра %1 (передано значение: ""%2"") в %3:
|
||
|Имя метода ""%4"" не соответствует требованиям образования имен процедур и функций.'"),
|
||
"ИмяПроцедуры", ИмяПроцедуры, "ОбщегоНазначения.ВыполнитьМетодКонфигурации", ИмяМетодаОбъекта),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецПопытки;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Возвращает менеджер объекта по имени.
|
||
// Ограничение: не обрабатываются точки маршрутов бизнес-процессов.
|
||
//
|
||
// Параметры:
|
||
// Имя - Строка - имя например, "Справочник", "Справочники", "Справочник.Организации".
|
||
//
|
||
// Возвращаемое значение:
|
||
// СправочникиМенеджер
|
||
// СправочникМенеджер
|
||
// ДокументыМенеджер
|
||
// ДокументМенеджер
|
||
// ...
|
||
//
|
||
Функция МенеджерОбъектаПоИмени(Имя)
|
||
Перем КлассОМ, ИмяОМ, Менеджер;
|
||
|
||
ЧастиИмени = СтрРазделить(Имя, ".");
|
||
|
||
Если ЧастиИмени.Количество() > 0 Тогда
|
||
КлассОМ = ВРег(ЧастиИмени[0]);
|
||
КонецЕсли;
|
||
|
||
Если ЧастиИмени.Количество() > 1 Тогда
|
||
ИмяОМ = ЧастиИмени[1];
|
||
КонецЕсли;
|
||
|
||
Если КлассОМ = "ПЛАНОБМЕНА"
|
||
Или КлассОМ = "ПЛАНЫОБМЕНА" Тогда
|
||
Менеджер = ПланыОбмена;
|
||
|
||
ИначеЕсли КлассОМ = "СПРАВОЧНИК"
|
||
Или КлассОМ = "СПРАВОЧНИКИ" Тогда
|
||
Менеджер = Справочники;
|
||
|
||
ИначеЕсли КлассОМ = "ДОКУМЕНТ"
|
||
Или КлассОМ = "ДОКУМЕНТЫ" Тогда
|
||
Менеджер = Документы;
|
||
|
||
ИначеЕсли КлассОМ = "ЖУРНАЛДОКУМЕНТОВ"
|
||
Или КлассОМ = "ЖУРНАЛЫДОКУМЕНТОВ" Тогда
|
||
Менеджер = ЖурналыДокументов;
|
||
|
||
ИначеЕсли КлассОМ = "ПЕРЕЧИСЛЕНИЕ"
|
||
Или КлассОМ = "ПЕРЕЧИСЛЕНИЯ" Тогда
|
||
Менеджер = Перечисления;
|
||
|
||
ИначеЕсли КлассОМ = "ОБЩИЙМОДУЛЬ"
|
||
Или КлассОМ = "ОБЩИЕМОДУЛИ" Тогда
|
||
|
||
Возврат ОбщийМодуль(ИмяОМ);
|
||
|
||
ИначеЕсли КлассОМ = "ОТЧЕТ"
|
||
Или КлассОМ = "ОТЧЕТЫ" Тогда
|
||
Менеджер = Отчеты;
|
||
|
||
ИначеЕсли КлассОМ = "ОБРАБОТКА"
|
||
Или КлассОМ = "ОБРАБОТКИ" Тогда
|
||
Менеджер = Обработки;
|
||
|
||
ИначеЕсли КлассОМ = "ПЛАНВИДОВХАРАКТЕРИСТИК"
|
||
Или КлассОМ = "ПЛАНЫВИДОВХАРАКТЕРИСТИК" Тогда
|
||
Менеджер = ПланыВидовХарактеристик;
|
||
|
||
ИначеЕсли КлассОМ = "ПЛАНСЧЕТОВ"
|
||
Или КлассОМ = "ПЛАНЫСЧЕТОВ" Тогда
|
||
Менеджер = ПланыСчетов;
|
||
|
||
ИначеЕсли КлассОМ = "ПЛАНВИДОВРАСЧЕТА"
|
||
Или КлассОМ = "ПЛАНЫВИДОВРАСЧЕТА" Тогда
|
||
Менеджер = ПланыВидовРасчета;
|
||
|
||
ИначеЕсли КлассОМ = "РЕГИСТРСВЕДЕНИЙ"
|
||
Или КлассОМ = "РЕГИСТРЫСВЕДЕНИЙ" Тогда
|
||
Менеджер = РегистрыСведений;
|
||
|
||
ИначеЕсли КлассОМ = "РЕГИСТРНАКОПЛЕНИЯ"
|
||
Или КлассОМ = "РЕГИСТРЫНАКОПЛЕНИЯ" Тогда
|
||
Менеджер = РегистрыНакопления;
|
||
|
||
ИначеЕсли КлассОМ = "РЕГИСТРБУХГАЛТЕРИИ"
|
||
Или КлассОМ = "РЕГИСТРЫБУХГАЛТЕРИИ" Тогда
|
||
Менеджер = РегистрыБухгалтерии;
|
||
|
||
ИначеЕсли КлассОМ = "РЕГИСТРРАСЧЕТА"
|
||
Или КлассОМ = "РЕГИСТРЫРАСЧЕТА" Тогда
|
||
|
||
Если ЧастиИмени.Количество() < 3 Тогда
|
||
// Регистр расчета
|
||
Менеджер = РегистрыРасчета;
|
||
Иначе
|
||
КлассПодчиненногоОМ = ВРег(ЧастиИмени[2]);
|
||
Если ЧастиИмени.Количество() > 3 Тогда
|
||
ИмяПодчиненногоОМ = ЧастиИмени[3];
|
||
КонецЕсли;
|
||
Если КлассПодчиненногоОМ = "ПЕРЕРАСЧЕТ"
|
||
Или КлассПодчиненногоОМ = "ПЕРЕРАСЧЕТЫ" Тогда
|
||
// Перерасчет
|
||
Попытка
|
||
Менеджер = РегистрыРасчета[ИмяОМ].Перерасчеты;
|
||
ИмяОМ = ИмяПодчиненногоОМ;
|
||
Исключение
|
||
Менеджер = Неопределено;
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
ИначеЕсли КлассОМ = "БИЗНЕСПРОЦЕСС"
|
||
Или КлассОМ = "БИЗНЕСПРОЦЕССЫ" Тогда
|
||
Менеджер = БизнесПроцессы;
|
||
|
||
ИначеЕсли КлассОМ = "ЗАДАЧА"
|
||
Или КлассОМ = "ЗАДАЧИ" Тогда
|
||
Менеджер = Задачи;
|
||
|
||
ИначеЕсли КлассОМ = "КОНСТАНТА"
|
||
Или КлассОМ = "КОНСТАНТЫ" Тогда
|
||
Менеджер = Константы;
|
||
|
||
ИначеЕсли КлассОМ = "ПОСЛЕДОВАТЕЛЬНОСТЬ"
|
||
Или КлассОМ = "ПОСЛЕДОВАТЕЛЬНОСТИ" Тогда
|
||
Менеджер = Последовательности;
|
||
КонецЕсли;
|
||
|
||
Если Менеджер <> Неопределено Тогда
|
||
Если ЗначениеЗаполнено(ИмяОМ) Тогда
|
||
Попытка
|
||
Возврат Менеджер[ИмяОМ];
|
||
Исключение
|
||
Менеджер = Неопределено;
|
||
КонецПопытки;
|
||
Иначе
|
||
Возврат Менеджер;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Неверное значение параметра %1 в %2. Менеджер для объекта ""%3"" не существует.'"), Имя),
|
||
"Имя", "ОбщегоНазначения.МенеджерОбъектаПоИмени", КатегорияОшибки.ОшибкаКонфигурации);
|
||
|
||
КонецФункции
|
||
|
||
// Вызвать экспортную функцию по имени с уровнем привилегий конфигурации.
|
||
// При включении профилей безопасности для вызова оператора Выполнить() используется
|
||
// переход в безопасный режим с профилем безопасности, используемом для информационной базы
|
||
// (если выше по стеку не был установлен другой безопасный режим).
|
||
//
|
||
// Параметры:
|
||
// ИмяМетода - Строка - имя экспортной функции в формате
|
||
// <имя объекта>.<имя процедуры>, где <имя объекта> - это
|
||
// общий модуль или модуль менеджера объекта.
|
||
// Параметры - Массив - параметры передаются в функцию <ИмяМетода>
|
||
// в порядке расположения элементов массива.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Произвольный - результат вызываемой функции.
|
||
//
|
||
Функция ВызватьФункциюКонфигурации(Знач ИмяМетода, Знач Параметры = Неопределено) Экспорт
|
||
|
||
ПроверитьИмяПроцедурыКонфигурации(ИмяМетода);
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.ПрофилиБезопасности") Тогда
|
||
МодульРаботаВБезопасномРежиме = ОбщийМодуль("РаботаВБезопасномРежиме");
|
||
Если МодульРаботаВБезопасномРежиме.ИспользуютсяПрофилиБезопасности()
|
||
И Не МодульРаботаВБезопасномРежиме.УстановленБезопасныйРежим() Тогда
|
||
|
||
ПрофильИнформационнойБазы = МодульРаботаВБезопасномРежиме.ПрофильБезопасностиИнформационнойБазы();
|
||
Если ЗначениеЗаполнено(ПрофильИнформационнойБазы) Тогда
|
||
|
||
УстановитьБезопасныйРежим(ПрофильИнформационнойБазы);
|
||
Если БезопасныйРежим() = Истина Тогда
|
||
УстановитьБезопасныйРежим(Ложь);
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
ПараметрыСтрока = "";
|
||
Если Параметры <> Неопределено И Параметры.Количество() > 0 Тогда
|
||
Для Индекс = 0 По Параметры.ВГраница() Цикл
|
||
ПараметрыСтрока = ПараметрыСтрока + "Параметры[" + XMLСтрока(Индекс) + "],";
|
||
КонецЦикла;
|
||
ПараметрыСтрока = Сред(ПараметрыСтрока, 1, СтрДлина(ПараметрыСтрока) - 1);
|
||
КонецЕсли;
|
||
|
||
Возврат Вычислить(ИмяМетода + "(" + ПараметрыСтрока + ")"); // АПК:488 Исполняемый код безопасен.
|
||
|
||
КонецФункции
|
||
|
||
// Вызвать экспортную функцию объекта встроенного языка по имени.
|
||
// При включении профилей безопасности для вызова оператора Выполнить() используется
|
||
// переход в безопасный режим с профилем безопасности, используемом для информационной базы
|
||
// (если выше по стеку не был установлен другой безопасный режим).
|
||
//
|
||
// Параметры:
|
||
// Объект - Произвольный - объект встроенного языка 1С:Предприятия, содержащий методы (например, ОбработкаОбъект).
|
||
// ИмяМетода - Строка - имя экспортной функции модуля объекта обработки.
|
||
// Параметры - Массив - параметры передаются в функцию <ИмяМетода>
|
||
// в порядке расположения элементов массива.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Произвольный - результат вызываемой функции.
|
||
//
|
||
Функция ВызватьФункциюОбъекта(Знач Объект, Знач ИмяМетода, Знач Параметры = Неопределено) Экспорт
|
||
|
||
// Проверка имени метода на корректность.
|
||
Попытка
|
||
Тест = Новый Структура;
|
||
Тест.Вставить(ИмяМетода, ИмяМетода);
|
||
Исключение
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Некорректное значение параметра %1 (%2) в %3.'"),
|
||
"ИмяМетода", ИмяМетода, "ОбщегоНазначения.ВыполнитьМетодОбъекта"),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
КонецПопытки;
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.ПрофилиБезопасности") Тогда
|
||
МодульРаботаВБезопасномРежиме = ОбщийМодуль("РаботаВБезопасномРежиме");
|
||
Если МодульРаботаВБезопасномРежиме.ИспользуютсяПрофилиБезопасности()
|
||
И Не МодульРаботаВБезопасномРежиме.УстановленБезопасныйРежим() Тогда
|
||
|
||
МодульРаботаВБезопасномРежиме = ОбщийМодуль("РаботаВБезопасномРежиме");
|
||
ПрофильИнформационнойБазы = МодульРаботаВБезопасномРежиме.ПрофильБезопасностиИнформационнойБазы();
|
||
|
||
Если ЗначениеЗаполнено(ПрофильИнформационнойБазы) Тогда
|
||
|
||
УстановитьБезопасныйРежим(ПрофильИнформационнойБазы);
|
||
Если БезопасныйРежим() = Истина Тогда
|
||
УстановитьБезопасныйРежим(Ложь);
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
ПараметрыСтрока = "";
|
||
Если Параметры <> Неопределено И Параметры.Количество() > 0 Тогда
|
||
Для Индекс = 0 По Параметры.ВГраница() Цикл
|
||
ПараметрыСтрока = ПараметрыСтрока + "Параметры[" + XMLСтрока(Индекс) + "],";
|
||
КонецЦикла;
|
||
ПараметрыСтрока = Сред(ПараметрыСтрока, 1, СтрДлина(ПараметрыСтрока) - 1);
|
||
КонецЕсли;
|
||
|
||
Возврат Вычислить("Объект." + ИмяМетода + "(" + ПараметрыСтрока + ")"); // АПК:488 Исполняемый код безопасен.
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область ВнешниеКомпоненты
|
||
|
||
Процедура ПроверитьМестоположениеКомпоненты(Идентификатор, Местоположение)
|
||
|
||
Если МакетСуществует(Местоположение) Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
Если ПодсистемаСуществует("СтандартныеПодсистемы.ВнешниеКомпоненты") Тогда
|
||
МодульВнешниеКомпонентыСлужебный = ОбщийМодуль("ВнешниеКомпонентыСлужебный");
|
||
МодульВнешниеКомпонентыСлужебный.ПроверитьМестоположениеКомпоненты(Идентификатор, Местоположение);
|
||
Возврат;
|
||
КонецЕсли;
|
||
ВызватьИсключение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Указан несуществующий макет ""%1"" при подключении внешней компоненты ""%2"".'"),
|
||
Местоположение, Идентификатор),
|
||
КатегорияОшибки.ОшибкаКонфигурации);
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция ОшибкаСовместимостиКомпонентыИзМакета(Местоположение)
|
||
|
||
Если Не ПодсистемаСуществует("СтандартныеПодсистемы.ВнешниеКомпоненты") Тогда
|
||
Возврат "";
|
||
КонецЕсли;
|
||
|
||
МодульВнешниеКомпонентыСлужебный = ОбщийМодуль("ВнешниеКомпонентыСлужебный");
|
||
|
||
Возврат МодульВнешниеКомпонентыСлужебный.ОшибкаСовместимостиКомпонентыИзМакета(
|
||
Местоположение);
|
||
|
||
КонецФункции
|
||
|
||
Функция СистемнаяИнформацияДляЖурналаРегистрации()
|
||
|
||
СистемнаяИнформация = Новый СистемнаяИнформация;
|
||
|
||
Возврат Символы.ПС + Символы.ПС + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Платформа 1С:Предприятие: %1
|
||
|Тип платформы: %2
|
||
|Версия ОС: %3
|
||
|Процессор: %4
|
||
|Оперативная память: %5'",
|
||
КодОсновногоЯзыка()),
|
||
СистемнаяИнформация.ВерсияПриложения,
|
||
СистемнаяИнформация.ТипПлатформы,
|
||
СистемнаяИнформация.ВерсияОС,
|
||
СистемнаяИнформация.Процессор,
|
||
СистемнаяИнформация.ОперативнаяПамять);
|
||
|
||
КонецФункции
|
||
|
||
#КонецОбласти
|
||
|
||
#Область ТекущееОкружение
|
||
|
||
Функция НомерСборкиПоТекущейВерсииПлатформы(НомераСборокСтрокой)
|
||
|
||
НомераСборок = СтрРазделить(НомераСборокСтрокой, ";", Истина);
|
||
|
||
СборкиПоВерсиям = Новый Соответствие;
|
||
Для Каждого НомерСборки Из НомераСборок Цикл
|
||
НомерВерсии = ОбщегоНазначенияКлиентСервер.ВерсияКонфигурацииБезНомераСборки(НомерСборки);
|
||
СборкиПоВерсиям.Вставить(СокрЛП(НомерВерсии), СокрЛП(НомерСборки));
|
||
КонецЦикла;
|
||
|
||
СистемнаяИнформация = Новый СистемнаяИнформация;
|
||
ТекущаяВерсия = ОбщегоНазначенияКлиентСервер.ВерсияКонфигурацииБезНомераСборки(СистемнаяИнформация.ВерсияПриложения);
|
||
|
||
Результат = СборкиПоВерсиям[ТекущаяВерсия];
|
||
Если Не ЗначениеЗаполнено(Результат) Тогда
|
||
Результат = НомераСборок[0];
|
||
КонецЕсли;
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Ниже этой версии платформы конфигурация может запуститься и показать окно с требованием обновить платформу,
|
||
// если она выше, чем в СтандартныеПодсистемыСервер.МинимальнаяВерсияПлатформыДляЗапуска.
|
||
// Конкретные номера версий указаны в СтандартныеПодсистемыСервер.МинимальнаяВерсияПлатформыДляИспользования.
|
||
// Версии могут быть переопределены в ОбщегоНазначенияПереопределяемый.ПриОпределенииОбщихПараметровБазовойФункциональности.
|
||
//
|
||
Функция МинимальнаяВерсияПлатформы() Экспорт // АПК:581 - экспортная, так как используется при тестировании.
|
||
|
||
ВерсияРежимаСовместимости = ВерсияРежимаСовместимости();
|
||
МинимальныеВерсииПлатформы = СтандартныеПодсистемыСервер.МинимальнаяВерсияПлатформыДляИспользования();
|
||
НайденнаяВерсия = МинимальныеВерсииПлатформы.НайтиПоЗначению(ВерсияРежимаСовместимости);
|
||
|
||
Если НайденнаяВерсия = Неопределено Тогда
|
||
НайденнаяВерсия = МинимальныеВерсииПлатформы[МинимальныеВерсииПлатформы.Количество() - 1];
|
||
КонецЕсли;
|
||
|
||
Возврат НайденнаяВерсия.Представление;
|
||
|
||
КонецФункции
|
||
|
||
Функция ВерсияРежимаСовместимости() Экспорт
|
||
|
||
СистемнаяИнформация = Новый СистемнаяИнформация();
|
||
РежимСовместимости = Метаданные.РежимСовместимости;
|
||
|
||
Если РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Тогда
|
||
ВерсияРежимаСовместимости = ОбщегоНазначенияКлиентСервер.ВерсияКонфигурацииБезНомераСборки(СистемнаяИнформация.ВерсияПриложения);
|
||
Иначе
|
||
ВерсияРежимаСовместимости = СтрСоединить(СтрРазделить(РежимСовместимости,
|
||
СтрСоединить(СтрРазделить(РежимСовместимости, "1234567890", Ложь), ""), Ложь), ".");
|
||
КонецЕсли;
|
||
|
||
Возврат ВерсияРежимаСовместимости;
|
||
|
||
КонецФункции
|
||
|
||
// Выполняет проверку правильности заполнения минимальной и рекомендуемой версии платформы.
|
||
//
|
||
// Параметры:
|
||
// Минимальная - Строка - номер версия платформы.
|
||
// Рекомендуемая - Строка - номер версия платформы.
|
||
//
|
||
// Возвращаемое значение:
|
||
// Булево - Истина, если минимальная и рекомендуемая версия платформы заполнена неправильно.
|
||
//
|
||
Функция МинимальнаяИРекомендуемаяВерсияПлатформыЗаполненаНеПравильно(Минимальная, Рекомендуемая)
|
||
|
||
// Минимальная версия платформы должна быть заполнена.
|
||
Если ПустаяСтрока(Минимальная) Тогда
|
||
Возврат Истина;
|
||
КонецЕсли;
|
||
|
||
// Минимальная версия платформы, заданная в конфигурации, не должна быть меньше минимальной версии платформы,
|
||
// заданной в библиотеке.
|
||
МинимальнаяБСП = НомерСборкиПоТекущейВерсииПлатформы(МинимальнаяВерсияПлатформы());
|
||
Если Не ЭтоВерсияЗащищенногоПрограммногоКомплекса(Минимальная)
|
||
И ОбщегоНазначенияКлиентСервер.СравнитьВерсии(МинимальнаяБСП, Минимальная) > 0 Тогда
|
||
Возврат Истина;
|
||
КонецЕсли;
|
||
|
||
// Минимальная версия платформы не должны быть больше рекомендуемой.
|
||
Возврат Не ПустаяСтрока(Минимальная)
|
||
И Не ПустаяСтрока(Рекомендуемая)
|
||
И ОбщегоНазначенияКлиентСервер.СравнитьВерсии(Минимальная, Рекомендуемая) > 0;
|
||
|
||
КонецФункции
|
||
|
||
Функция НедопустимыеВерсииПлатформы() Экспорт
|
||
|
||
Возврат "";
|
||
|
||
КонецФункции
|
||
|
||
Функция ЭтоВерсияЗащищенногоПрограммногоКомплекса(Версия)
|
||
|
||
Версии = СтандартныеПодсистемыСервер.ВерсииЗащищенногоПрограммногоКомплекса();
|
||
Возврат Версии.Найти(Версия) <> Неопределено;
|
||
|
||
КонецФункции
|
||
|
||
// Для функции ОбщиеПараметрыБазовойФункциональности.
|
||
Процедура УточнитьВерсиюПлатформы(ОбщиеПараметры)
|
||
|
||
СистемнаяИнформация = Новый СистемнаяИнформация;
|
||
НоваяСборка = СтандартныеПодсистемыСервер.НомерВерсииПлатформыВместоОтозванной(СистемнаяИнформация.ВерсияПриложения);
|
||
Если Не ЗначениеЗаполнено(НоваяСборка) Тогда
|
||
НоваяРекомендуемаяСборка = СтандартныеПодсистемыСервер.НомерВерсииПлатформыВместоОтозванной(ОбщиеПараметры.МинимальнаяВерсияПлатформы);
|
||
Если ЗначениеЗаполнено(НоваяРекомендуемаяСборка) Тогда
|
||
МинимальнаяСборка = НомерСборкиПоТекущейВерсииПлатформы(МинимальнаяВерсияПлатформы());
|
||
ОбщиеПараметры.МинимальнаяВерсияПлатформы = МинимальнаяСборка;
|
||
ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = МинимальнаяСборка;
|
||
Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ОбщиеПараметры.РекомендуемаяВерсияПлатформы, НоваяРекомендуемаяСборка) < 0 Тогда
|
||
ОбщиеПараметры.РекомендуемаяВерсияПлатформы = НоваяРекомендуемаяСборка;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
ИначеЕсли ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ОбщиеПараметры.МинимальнаяВерсияПлатформы, НоваяСборка) < 0 Тогда
|
||
ОбщиеПараметры.РекомендуемаяВерсияПлатформы = НоваяСборка;
|
||
ОбщиеПараметры.МинимальнаяВерсияПлатформы = НоваяСборка;
|
||
ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы = НоваяСборка;
|
||
ОбщиеПараметры.РаботаВПрограммеЗапрещена = Истина;
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Локализация
|
||
|
||
// Параметры:
|
||
// ОбщиеПараметры - см. ОбщиеПараметрыБазовойФункциональности
|
||
//
|
||
Процедура УточнитьМинимальнуюВерсиюПлатформыИзСервиса(ОбщиеПараметры)
|
||
|
||
Если Не ПодсистемаСуществует("ИнтернетПоддержкаПользователей.ПолучениеОбновленийПрограммы") Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
// Проверка версии БИП начиная с которой появился программный интерфейс
|
||
МодульИнтернетПоддержкаПользователейКлиентСервер = ОбщийМодуль("ИнтернетПоддержкаПользователейКлиентСервер");
|
||
ВерсияБИП = МодульИнтернетПоддержкаПользователейКлиентСервер.ВерсияБиблиотеки();
|
||
|
||
Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияБИП, "2.7.1.35") <= 0 Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
Попытка
|
||
МодульПолучениеОбновленийПрограммы = ОбщийМодуль("ПолучениеОбновленийПрограммы");
|
||
ИнформацияОВерсияхПлатформы = МодульПолучениеОбновленийПрограммы.ИнформацияОВерсияхПлатформы();
|
||
|
||
// Контроль заполнения версий платформы по данным сервиса
|
||
Если ПустаяСтрока(ИнформацияОВерсияхПлатформы.МинимальнаяВерсияПлатформы)
|
||
И ПустаяСтрока(ИнформацияОВерсияхПлатформы.РекомендуемаяВерсияПлатформы) Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
Минимальная = НомерСборкиПоТекущейВерсииПлатформы(ИнформацияОВерсияхПлатформы.МинимальнаяВерсияПлатформы);
|
||
Рекомендуемая = НомерСборкиПоТекущейВерсииПлатформы(ИнформацияОВерсияхПлатформы.РекомендуемаяВерсияПлатформы);
|
||
|
||
Если МинимальнаяИРекомендуемаяВерсияПлатформыЗаполненаНеПравильно(Минимальная, Рекомендуемая) Тогда
|
||
|
||
МодульПолучениеОбновленийПрограммы.УдалитьИнформациюОВерсияхПлатформы();
|
||
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Минимальная и рекомендуемая версии платформы ""1С:Предприятие"", полученные с сервиса обновления приложений, не соответствуют следующим требованиям:
|
||
| - минимальная версия должна быть заполнена;
|
||
| - минимальная версия не должна быть меньше минимальной версии БСП (см. %1);
|
||
| - минимальная версия не должна быть меньше рекомендуемой версии.
|
||
|Минимальная версия сервиса обновления приложений: %2
|
||
|Минимальная версия БСП: %3
|
||
|Рекомендуемая версия сервиса обновления приложений: %4
|
||
|
|
||
|Минимальная и рекомендуемая версия платформы ""1С:Предприятие"" установлена по данным см. %5.
|
||
|Минимальная версия: %6
|
||
|Рекомендуемая версия: %7'",
|
||
КодОсновногоЯзыка()),
|
||
"ОбщегоНазначения.МинимальнаяВерсияПлатформы", Минимальная, НомерСборкиПоТекущейВерсииПлатформы(МинимальнаяВерсияПлатформы()),
|
||
Рекомендуемая, "ОбщегоНазначенияПереопределяемый.ПриОпределенииОбщихПараметровБазовойФункциональности",
|
||
ОбщиеПараметры.МинимальнаяВерсияПлатформы, ОбщиеПараметры.РекомендуемаяВерсияПлатформы);
|
||
ЗаписьЖурналаРегистрации(НСтр("ru = 'Базовая функциональность'", КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Предупреждение,,,
|
||
ТекстСообщения);
|
||
Возврат;
|
||
КонецЕсли;
|
||
|
||
ОбщиеПараметры.МинимальнаяВерсияПлатформы = Минимальная;
|
||
ОбщиеПараметры.РекомендуемаяВерсияПлатформы = Рекомендуемая;
|
||
|
||
Исключение
|
||
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
|
||
НСтр("ru = 'Не удалось изменить минимальную и рекомендуемую версию платформы ""1С:Предприятие"", полученную с сервиса обновления приложений, по причине:
|
||
|%1'",
|
||
КодОсновногоЯзыка()), ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
|
||
ЗаписьЖурналаРегистрации(НСтр("ru = 'Базовая функциональность'", КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Предупреждение,,,
|
||
ТекстСообщения);
|
||
КонецПопытки;
|
||
|
||
КонецПроцедуры
|
||
// Конец Локализация
|
||
|
||
#КонецОбласти
|
||
|
||
#КонецОбласти
|
||
|
||
#КонецЕсли
|