/////////////////////////////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2022, ООО 1С-Софт // Все права защищены. Эта программа и сопроводительные материалы предоставляются // в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0) // Текст лицензии доступен по ссылке: // https://creativecommons.org/licenses/by/4.0/legalcode /////////////////////////////////////////////////////////////////////////////////////////////////////// #Область ПрограммныйИнтерфейс // Вызов этой процедуры необходимо разместить в модуле сеанса в процедуре УстановкаПараметровСеанса // согласно документации. // // Параметры: // ИменаПараметровСеанса - Массив // - Неопределено - имена параметров сеанса для инициализации. // Массив устанавливаемых идентификаторов параметров сеанса, // которые нужно инициализировать, если обработчик вызывается // перед использованием неинициализированных параметров сеанса. // Неопределено, если обработчик события вызывается системой при начале сеанса. // // Возвращаемое значение: // Массив - имена параметров сеанса, значения которых были успешно установлены. // Функция УстановкаПараметровСеанса(ИменаПараметровСеанса) Экспорт // Параметры сеанса, инициализация которых требует обращения к одним и тем же данным // следует инициализировать сразу группой. Для того, чтобы избежать их повторной инициализации, // имена уже установленных параметров сеанса сохраняются в массиве УстановленныеПараметры. УстановленныеПараметры = Новый Массив; Если ИменаПараметровСеанса <> Неопределено И ИменаПараметровСеанса.Найти("ПараметрыКлиентаНаСервере") <> Неопределено Тогда ПараметрыСеанса.ПараметрыКлиентаНаСервере = Новый ФиксированноеСоответствие(Новый Соответствие); УстановленныеПараметры.Добавить("ПараметрыКлиентаНаСервере"); Если ИменаПараметровСеанса.Количество() = 1 Тогда Возврат УстановленныеПараметры; КонецЕсли; КонецЕсли; Если ИменаПараметровСеанса = Неопределено Тогда Если ПараметрыСеанса.ПараметрыКлиентаНаСервере.Количество() = 0 Тогда НезаполненныеПараметрыКлиента = Новый Соответствие; НезаполненныеПараметрыКлиента.Вставить("ПервыйСерверныйВызовВыполнен", ?(ТекущийРежимЗапуска() = Неопределено, Неопределено, Ложь)); ПараметрыСеанса.ПараметрыКлиентаНаСервере = Новый ФиксированноеСоответствие(НезаполненныеПараметрыКлиента); КонецЕсли; Справочники.ВерсииРасширений.УстановкаПараметровСеанса(ИменаПараметровСеанса, УстановленныеПараметры); Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда МодульМультиязычностьСервер = ОбщегоНазначения.ОбщийМодуль("МультиязычностьСервер"); МодульМультиязычностьСервер.УстановкаПараметровСеанса(ИменаПараметровСеанса, УстановленныеПараметры); КонецЕсли; // При установке соединения с информационной базой до вызова всех остальных обработчиков. ПередЗапускомПрограммы(); Возврат УстановленныеПараметры; КонецЕсли; Если ИменаПараметровСеанса.Найти("КлючДанныхПовторногоИспользования") <> Неопределено Тогда ПараметрыСеанса.КлючДанныхПовторногоИспользования = Новый УникальныйИдентификатор; УстановленныеПараметры.Добавить("КлючДанныхПовторногоИспользования"); КонецЕсли; Справочники.ВерсииРасширений.УстановкаПараметровСеанса(ИменаПараметровСеанса, УстановленныеПараметры); Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда МодульМультиязычностьСервер = ОбщегоНазначения.ОбщийМодуль("МультиязычностьСервер"); МодульМультиязычностьСервер.УстановкаПараметровСеанса(ИменаПараметровСеанса, УстановленныеПараметры); КонецЕсли; Если ИменаПараметровСеанса.Найти("БуферОбмена") <> Неопределено Тогда ПараметрыСеанса.БуферОбмена = Новый ФиксированнаяСтруктура(Новый Структура("Источник, Данные")); УстановленныеПараметры.Добавить("БуферОбмена"); КонецЕсли; Обработчики = Новый Соответствие; ИнтеграцияПодсистемБСП.ПриДобавленииОбработчиковУстановкиПараметровСеанса(Обработчики); ОбработчикиСобственные = Новый Соответствие; ОбщегоНазначенияПереопределяемый.ПриДобавленииОбработчиковУстановкиПараметровСеанса(ОбработчикиСобственные); Для Каждого Запись Из ОбработчикиСобственные Цикл Обработчики.Вставить(Запись.Ключ, Запись.Значение); КонецЦикла; ВыполнитьОбработчикиУстановкиПараметровСеанса(ИменаПараметровСеанса, Обработчики, УстановленныеПараметры); ИнтеграцияПодсистемБСП.ПриУстановкеПараметровСеанса(ИменаПараметровСеанса); Возврат УстановленныеПараметры; КонецФункции // Возвращает признак того, является ли конфигурация базовой. // Базовые версии конфигураций могут иметь программные ограничения, действие которых // можно предусмотреть с помощью этой функции. // Конфигурация считается базовой, если в ее имени есть термин "Базовая", // например, "УправлениеТорговлейБазовая". // // Возвращаемое значение: // Булево - Истина, если конфигурация - базовая. // Функция ЭтоБазоваяВерсияКонфигурации() Экспорт ЭтоБазоваяВерсияКонфигурации = СтрНайти(ВРег(Метаданные.Имя), НСтр("ru = 'БАЗОВАЯ'")) > 0; ОбщегоНазначенияПереопределяемый.ПриОпределенииПризнакаЭтоБазоваяВерсияКонфигурации(ЭтоБазоваяВерсияКонфигурации); Возврат ЭтоБазоваяВерсияКонфигурации; КонецФункции // Обновляет кэши свойств метаданных, позволяющие ускорить // открытие сеанса, а также обновление ИБ, особенно в модели сервиса. // Их обновление происходит до обновления ИБ. // // Для использования в других библиотеках и конфигурациях. // Процедура ОбновитьВсеПараметрыРаботыПрограммы() Экспорт РегистрыСведений.ПараметрыРаботыПрограммы.ОбновитьВсеПараметрыРаботыПрограммы(); КонецПроцедуры // Возвращает номер версии "Библиотеки стандартных подсистем" (БСП), // встроенной в конфигурацию. // // Возвращаемое значение: // Строка - версия БСП, например "1.0.1.1". // Функция ВерсияБиблиотеки() Экспорт Возврат СтандартныеПодсистемыПовтИсп.ОписанияПодсистем().ПоИменам["СтандартныеПодсистемы"].Версия; КонецФункции // Получает уникальный идентификатор информационной базы, // с помощью которого можно различать различные экземпляры информационных баз, // например, при сборе статистики или в механизмах внешнего управления базами. // Если идентификатор не заполнен, то его значение автоматически устанавливается и возвращается. // // Идентификатор хранится в константе ИдентификаторИнформационнойБазы. // Константа ИдентификаторИнформационнойБазы не должна входить в составы планов обмена, чтобы иметь // различные значения в каждой информационной базе (узле РИБ). // // Возвращаемое значение: // Строка - идентификатор информационной базы. // Функция ИдентификаторИнформационнойБазы() Экспорт ИдентификаторИнформационнойБазы = Константы.ИдентификаторИнформационнойБазы.Получить(); Если ПустаяСтрока(ИдентификаторИнформационнойБазы) Тогда ИдентификаторИнформационнойБазы = Строка(Новый УникальныйИдентификатор()); УстановитьОтключениеБезопасногоРежима(Истина); УстановитьПривилегированныйРежим(Истина); Константы.ИдентификаторИнформационнойБазы.Установить(ИдентификаторИнформационнойБазы); УстановитьПривилегированныйРежим(Ложь); УстановитьОтключениеБезопасногоРежима(Ложь); КонецЕсли; Возврат ИдентификаторИнформационнойБазы; КонецФункции // Возвращает сохраненные в информационной базы параметры администрирования. // Предназначена для использования в механизмах, требующих для свой работы // ввода параметров администрирования информационной базы и/или кластера серверов. // Например, блокировка установки соединений с информационной базой. // См. так же УстановитьПараметрыАдминистрирования. // // Возвращаемое значение: // Структура - содержит свойства двух структур // АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера // и АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера. // При этом поля, содержащие пароли, возвращаются пустыми. Если параметры администрирования // не были ранее сохранены при помощи функции УстановитьПараметрыАдминистрирования, // то будут возвращены автоматически вычисленные параметры администрирования по умолчанию. // Функция ПараметрыАдминистрирования() Экспорт Если ОбщегоНазначения.РазделениеВключено() И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда Если Не Пользователи.ЭтоПолноправныйПользователь() Тогда ВызватьИсключение НСтр("ru = 'Недостаточно прав для выполнения операции'"); КонецЕсли; Иначе Если Не Пользователи.ЭтоПолноправныйПользователь(, Истина) Тогда ВызватьИсключение НСтр("ru = 'Недостаточно прав для выполнения операции'"); КонецЕсли; КонецЕсли; УстановитьПривилегированныйРежим(Истина); ПараметрыАдминистрированияИБ = Константы.ПараметрыАдминистрированияИБ.Получить().Получить(); ПараметрыАдминистрированияПоУмолчанию = ПараметрыАдминистрированияПоУмолчанию(); Если ТипЗнч(ПараметрыАдминистрированияИБ) = Тип("Структура") Тогда ЗаполнитьЗначенияСвойств(ПараметрыАдминистрированияПоУмолчанию, ПараметрыАдминистрированияИБ); КонецЕсли; ПараметрыАдминистрированияИБ = ПараметрыАдминистрированияПоУмолчанию; Если Не ОбщегоНазначения.ИнформационнаяБазаФайловая() Тогда ПрочитатьПараметрыИзСтрокиСоединения(ПараметрыАдминистрированияИБ); КонецЕсли; Возврат ПараметрыАдминистрированияИБ; КонецФункции // Сохраняет параметры администрирования информационной базы и кластера серверов. // При сохранении поля, содержащие пароли, будут очищены в целях безопасности. // // Параметры: // ПараметрыАдминистрированияИБ - см. ПараметрыАдминистрирования // // Пример: // ПараметрыАдминистрирования = СтандартныеПодсистемыСервер.ПараметрыАдминистрирования(); // // Вывод параметров администрирования администратору для подтверждения корректности и ввода паролей. // // Далее выполнение действий, связанных с подключением к кластеру серверов. // СтандартныеПодсистемыСервер.ПараметрыАдминистрирования(ПараметрыАдминистрирования); // Процедура УстановитьПараметрыАдминистрирования(ПараметрыАдминистрированияИБ) Экспорт ПараметрыАдминистрированияИБ.ПарольАдминистратораКластера = ""; ПараметрыАдминистрированияИБ.ПарольАдминистратораИнформационнойБазы = ""; Константы.ПараметрыАдминистрированияИБ.Установить(Новый ХранилищеЗначения(ПараметрыАдминистрированияИБ)); КонецПроцедуры // Устанавливает представление поля Дата в списках, содержащих реквизит с составом даты Дата и время. // Подробнее см. стандарт "Поле "Дата" в списках". // // Параметры: // Форма - ФормаКлиентскогоПриложения - форма со списком. // ПолноеИмяРеквизита - Строка - полный путь к реквизиту типа "Дата" в формате "<ИмяСписка>.<ИмяПоля>". // ИмяЭлемента - Строка - имя элемента формы, связанного с реквизитом списка типа "Дата". // // Пример: // // Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) // СтандартныеПодсистемыСервер.УстановитьУсловноеОформлениеПоляДата(ЭтотОбъект); // Процедура УстановитьУсловноеОформлениеПоляДата(Форма, ПолноеИмяРеквизита = "Список.Дата", ИмяЭлемента = "Дата") Экспорт ОбщегоНазначенияКлиентСервер.ПроверитьПараметр( "СтандартныеПодсистемыСервер.УстановитьУсловноеОформлениеПоляДата", "ЭтотОбъект", Форма, Тип("ФормаКлиентскогоПриложения")); ЧастиПолногоИмени = СтрРазделить(ПолноеИмяРеквизита, "."); Если ЧастиПолногоИмени.Количество() <> 2 Тогда // Недопустимое значение параметра ПолноеИмяРеквизита. // Имя реквизита должно быть в формате ""<ИмяСписка>.<ИмяПоля>""'"); Возврат; КонецЕсли; ИмяСписка = ЧастиПолногоИмени[0]; РеквизитСписок = Форма[ИмяСписка]; Если ТипЗнч(РеквизитСписок) = Тип("ДинамическийСписок") Тогда // ДинамическийСписок позволяет установить условное оформление с помощью собственного компоновщика. // При этом параметр ИмяЭлемента игнорируется, потому что компоновщик динамического списка // не знает как будут отображены реквизиты списка, потому путем к реквизиту и значения отбора и оформления // является имя реквизита динамического списка. УсловноеОформление = РеквизитСписок.УсловноеОформление; ПутьКРеквизиту = ЧастиПолногоИмени[1]; ИмяОформляемогоПоля = ПутьКРеквизиту; Иначе // Остальные списки, например, ДанныеФормыДерево: // не имеют собственного компоновщика, потому используют компоновщик самой формы. УсловноеОформление = Форма.УсловноеОформление; ПутьКРеквизиту = ПолноеИмяРеквизита; ИмяОформляемогоПоля = ИмяЭлемента; КонецЕсли; Если Не ЗначениеЗаполнено(УсловноеОформление.ИдентификаторПользовательскойНастройки) Тогда УсловноеОформление.ИдентификаторПользовательскойНастройки = "ОсновноеОформление"; КонецЕсли; // Представление даты. ЭлементОформления = УсловноеОформление.Элементы.Добавить(); ЭлементОформления.Использование = Истина; ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Формат", "ДЛФ=D"); ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить(); ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных(ИмяОформляемогоПоля); // Представление даты сегодня. ЭлементОформления = УсловноеОформление.Элементы.Добавить(); ЭлементОформления.Использование = Истина; ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Формат", НСтр("ru = 'ДФ=ЧЧ:мм'")); ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить(); ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных(ИмяОформляемогоПоля); ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных")); ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ПутьКРеквизиту); ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.БольшеИлиРавно; ЭлементОтбора.ПравоеЗначение = Новый СтандартнаяДатаНачала(ВариантСтандартнойДатыНачала.НачалоЭтогоДня); ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных")); ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ПутьКРеквизиту); ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Меньше; ЭлементОтбора.ПравоеЗначение = Новый СтандартнаяДатаНачала(ВариантСтандартнойДатыНачала.НачалоСледующегоДня); КонецПроцедуры // Получает настройку необходимости выводить подтверждение при завершении работы программы // для текущего пользователя. Предназначена для использования в форме персональных настроек // пользователя. Пример использования см. в общей форме _ДемоМоиНастройки. // // Возвращаемое значение: // Булево - если Истина, то пользователю при закрытии программы будет показано // окно с подтверждением завершения сеанса. // Функция ЗапрашиватьПодтверждениеПриЗавершенииПрограммы() Экспорт Результат = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить( "ОбщиеНастройкиПользователя", "ЗапрашиватьПодтверждениеПриЗавершенииПрограммы"); Если Результат = Неопределено Тогда Результат = ОбщегоНазначения.ОбщиеПараметрыБазовойФункциональности().ЗапрашиватьПодтверждениеПриЗавершенииПрограммы; КонецЕсли; Возврат Результат; КонецФункции // Возвращает описания форматов сохранения табличного документа. // // Возвращаемое значение: // ТаблицаЗначений: // * ТипФайлаТабличногоДокумента - ТипФайлаТабличногоДокумента - значение, соответствующее формату; // * Ссылка - ПеречислениеСсылка.ФорматыСохраненияОтчетов - ссылка на метаданные, где хранится представление; // * Представление - Строка - представление типа файла (заполняется из перечисления); // * Расширение - Строка - тип файла для операционной системы; // * Картинка - Картинка - картинка формата. // Функция НастройкиФорматовСохраненияТабличногоДокумента() Экспорт ТаблицаФорматов = Новый ТаблицаЗначений; ТаблицаФорматов.Колонки.Добавить("ТипФайлаТабличногоДокумента", Новый ОписаниеТипов("ТипФайлаТабличногоДокумента")); ТаблицаФорматов.Колонки.Добавить("Ссылка", Новый ОписаниеТипов("ПеречислениеСсылка.ФорматыСохраненияОтчетов")); ТаблицаФорматов.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка")); ТаблицаФорматов.Колонки.Добавить("Расширение", Новый ОписаниеТипов("Строка")); ТаблицаФорматов.Колонки.Добавить("Картинка", Новый ОписаниеТипов("Картинка")); // Документ PDF (.pdf) НовыйФормат = ТаблицаФорматов.Добавить(); НовыйФормат.ТипФайлаТабличногоДокумента = ТипФайлаТабличногоДокументаPDF(); НовыйФормат.Ссылка = Перечисления.ФорматыСохраненияОтчетов.PDF; НовыйФормат.Расширение = "pdf"; НовыйФормат.Картинка = БиблиотекаКартинок.ФорматPDF; НовыйФормат.Представление = ПредставлениеТипаФайлаТабличногоДокументаPDF(); // Табличный документ (.mxl) НовыйФормат = ТаблицаФорматов.Добавить(); НовыйФормат.ТипФайлаТабличногоДокумента = ТипФайлаТабличногоДокумента.MXL; НовыйФормат.Ссылка = Перечисления.ФорматыСохраненияОтчетов.MXL; НовыйФормат.Расширение = "mxl"; НовыйФормат.Картинка = БиблиотекаКартинок.ФорматMXL; // Лист Microsoft Excel 2007 (.xlsx) НовыйФормат = ТаблицаФорматов.Добавить(); НовыйФормат.ТипФайлаТабличногоДокумента = ТипФайлаТабличногоДокумента.XLSX; НовыйФормат.Ссылка = Перечисления.ФорматыСохраненияОтчетов.XLSX; НовыйФормат.Расширение = "xlsx"; НовыйФормат.Картинка = БиблиотекаКартинок.ФорматExcel2007; // Лист Microsoft Excel 97-2003 (.xls) НовыйФормат = ТаблицаФорматов.Добавить(); НовыйФормат.ТипФайлаТабличногоДокумента = ТипФайлаТабличногоДокумента.XLS; НовыйФормат.Ссылка = Перечисления.ФорматыСохраненияОтчетов.XLS; НовыйФормат.Расширение = "xls"; НовыйФормат.Картинка = БиблиотекаКартинок.ФорматExcel; // Электронная таблица OpenDocument (.ods). НовыйФормат = ТаблицаФорматов.Добавить(); НовыйФормат.ТипФайлаТабличногоДокумента = ТипФайлаТабличногоДокумента.ODS; НовыйФормат.Ссылка = Перечисления.ФорматыСохраненияОтчетов.ODS; НовыйФормат.Расширение = "ods"; НовыйФормат.Картинка = БиблиотекаКартинок.ФорматOpenOfficeCalc; // Документ Word 2007 (.docx) НовыйФормат = ТаблицаФорматов.Добавить(); НовыйФормат.ТипФайлаТабличногоДокумента = ТипФайлаТабличногоДокумента.DOCX; НовыйФормат.Ссылка = Перечисления.ФорматыСохраненияОтчетов.DOCX; НовыйФормат.Расширение = "docx"; НовыйФормат.Картинка = БиблиотекаКартинок.ФорматWord2007; // Веб-страница (.html) НовыйФормат = ТаблицаФорматов.Добавить(); НовыйФормат.ТипФайлаТабличногоДокумента = ТипФайлаТабличногоДокумента.HTML5; НовыйФормат.Ссылка = Перечисления.ФорматыСохраненияОтчетов.HTML; НовыйФормат.Расширение = "html"; НовыйФормат.Картинка = БиблиотекаКартинок.ФорматHTML; // Текстовый документ UTF-8 (.txt). НовыйФормат = ТаблицаФорматов.Добавить(); НовыйФормат.ТипФайлаТабличногоДокумента = ТипФайлаТабличногоДокумента.TXT; НовыйФормат.Ссылка = Перечисления.ФорматыСохраненияОтчетов.TXT; НовыйФормат.Расширение = "txt"; НовыйФормат.Картинка = БиблиотекаКартинок.ФорматTXT; // Текстовый документ ANSI (.txt). НовыйФормат = ТаблицаФорматов.Добавить(); НовыйФормат.ТипФайлаТабличногоДокумента = ТипФайлаТабличногоДокумента.ANSITXT; НовыйФормат.Ссылка = Перечисления.ФорматыСохраненияОтчетов.ANSITXT; НовыйФормат.Расширение = "txt"; НовыйФормат.Картинка = БиблиотекаКартинок.ФорматTXT; Для Каждого ФорматСохранения Из ТаблицаФорматов Цикл Если Не ЗначениеЗаполнено(ФорматСохранения.Представление) Тогда ФорматСохранения.Представление = Строка(ФорматСохранения.Ссылка); КонецЕсли; КонецЦикла; Возврат ТаблицаФорматов; КонецФункции // Возвращает версию режима совместимости в формате нумерации редакций и версий, например, 8.3.15.0. // // Возвращаемое значение: // Строка - версия режима совместимости в формате нумерации редакций и версий. // Функция ВерсияРежимаСовместимости() Экспорт Если Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Тогда Информация = Новый СистемнаяИнформация; Возврат Информация.ВерсияПриложения; КонецЕсли; ОписаниеРежимаСовместимости = СтрРазделить(Метаданные.РежимСовместимости, "_"); Символов = СтрДлина(ОписаниеРежимаСовместимости[0]); НомерРедакции = ""; Для НомерСимвола = 1 По Символов Цикл ТекущийСимвол = Сред(ОписаниеРежимаСовместимости[0], НомерСимвола, 1); Если СтрНайти("0123456789", ТекущийСимвол) > 0 Тогда НомерРедакции = НомерРедакции + ТекущийСимвол; КонецЕсли; КонецЦикла; ОписаниеРежимаСовместимости.Установить(0, НомерРедакции); Для Индекс = ОписаниеРежимаСовместимости.Количество() По 3 Цикл ОписаниеРежимаСовместимости.Добавить("0"); КонецЦикла; Возврат СтрСоединить(ОписаниеРежимаСовместимости, "."); КонецФункции #Область УстаревшиеПроцедурыИФункции // Устарела. Веб-клиент более не поддерживает конфигурации, которые используют интерфейс версии 8.2. // При работе в веб-клиенте отключена возможность переключения интерфейса // между интерфейсом версии 8.2 и интерфейсом Такси. // // Устанавливает жирное оформление шрифта заголовков групп формы для их корректного отображения в интерфейсе 8.2. // В интерфейсе "Такси" заголовки групп с обычным выделением и без выделения выводятся большим шрифтом. // В интерфейсе 8.2 такие заголовки выводятся как обычные надписи и не ассоциируются с заголовками. // Эта функция предназначена для визуального выделения (жирным шрифтом) заголовков групп в режиме интерфейса 8.2. // // Параметры: // Форма - ФормаКлиентскогоПриложения - форма для изменения шрифта заголовков групп; // ИменаГрупп - Строка - список имен групп формы, разделенных запятыми. Если имена групп не указаны, // то оформление будет применено ко всем группам на форме. // // Пример: // Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) // СтандартныеПодсистемыСервер.УстановитьОтображениеЗаголовковГрупп(ЭтотОбъект); // Процедура УстановитьОтображениеЗаголовковГрупп(Форма, ИменаГрупп = "") Экспорт // Ничего не выполняется. КонецПроцедуры #КонецОбласти // Возвращает признак необходимости показа всплывающего уведомления об установленных // обновлениях программы - динамическом обновлении программы, новых патчей и расширений. // // Возвращаемое значение: // Булево - если Истина, то всплывающие уведомления включены. // Функция ПоказыватьПредупреждениеОбУстановленныхОбновленияхПрограммы() Экспорт Результат = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить( "ОбщиеНастройкиПользователя", "ПоказыватьПредупреждениеОбУстановленныхОбновленияхПрограммы"); Если Результат = Неопределено Тогда Результат = Истина; КонецЕсли; Возврат Результат; КонецФункции #КонецОбласти #Область СлужебныйПрограммныйИнтерфейс //////////////////////////////////////////////////////////////////////////////// // Дополнительная базовая функциональность для анализа параметров клиента на сервере. // Возвращает пустое фиксированное соответствие, если ТекущийРежимЗапуска() = Неопределено. // // Возвращаемое значение: // ФиксированноеСоответствие: // * ПараметрЗапуска - Строка // * СтрокаСоединенияИнформационнойБазы - Строка - строка соединения, полученная на клиенте. // Функция ПараметрыКлиентаНаСервере() Экспорт УстановитьПривилегированныйРежим(Истина); ПараметрыКлиента = ПараметрыСеанса.ПараметрыКлиентаНаСервере; УстановитьПривилегированныйРежим(Ложь); Если ТекущийРежимЗапуска() = Неопределено И ПараметрыКлиента.Получить("ПервыйСерверныйВызовВыполнен") = Неопределено Или ПараметрыКлиента.Получить("ПервыйСерверныйВызовВыполнен") = Истина Тогда Возврат ПараметрыКлиента; КонецЕсли; Если ТекущийРежимЗапуска() <> Неопределено Тогда // Сброс клиентских кэшей для обращения к серверу при обращении к параметрам работы клиента, // чтобы при этом перезаполнились параметры клиента на сервере. ОбновитьПовторноИспользуемыеЗначения(); КонецЕсли; ПриЗапуске = ПараметрыКлиента.Получить("ПервыйСерверныйВызовВыполнен") = Ложь; Если ПриЗапуске Тогда КомментарийДляЖурналаРегистрацииБезСтекаВызовов = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Недопустимое обращение к неинициализированным параметрам клиента на сервере. |Вероятно, вызов выполнен преждевременно до завершения инициализации в %1.'", ОбщегоНазначения.КодОсновногоЯзыка()), "СтандартныеПодсистемыКлиент.ПередНачаломРаботыСистемы"); Иначе КомментарийДляЖурналаРегистрацииБезСтекаВызовов = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Недопустимое обращение к неинициализированным параметрам клиента на сервере. |Вероятно, вызван выполнен после некорректной очистки параметров сеанса без использования %2.'", ОбщегоНазначения.КодОсновногоЯзыка()), "ОбщегоНазначения.ОчиститьПараметрыСеанса"); КонецЕсли; Попытка ВызватьИсключение КомментарийДляЖурналаРегистрацииБезСтекаВызовов; Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); КонецПопытки; КомментарийСоСтекомВызовов = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); ИмяСобытия = НСтр("ru = 'Не заполнены параметры клиента на сервере'", ОбщегоНазначения.КодОсновногоЯзыка()); ЗаписьЖурналаРегистрации(ИмяСобытия, УровеньЖурналаРегистрации.Ошибка,,, КомментарийСоСтекомВызовов); Если Не ПриЗапуске Тогда ТекстОшибки = НСтр("ru = 'Не инициализированы параметры клиента на сервере. |Для их инициализации повторите действие или перезапустите сеанс.'"); ВызватьИсключение ТекстОшибки; КонецЕсли; Возврат ПараметрыКлиента; КонецФункции //////////////////////////////////////////////////////////////////////////////// // Процедуры для установки/обновления/получения параметров работы программы (кэшей). // Проверяет, что в текущем сеансе доступна последняя версия программы, // в противном случае, вызывает исключение с требованием перезапустить сеанс. // // В старых сеансах нельзя обновлять параметры работы программы, а также // нельзя выполнять изменение некоторых данных, чтобы не перезаписать // новую версию данных (полученную с помощью новой версии программы) // старой версией данных (полученной с помощью старой версии программы). // Процедура ПроверитьДинамическоеОбновлениеВерсииПрограммы() Экспорт Если ВерсияПрограммыОбновленаДинамически() Тогда ПотребоватьПерезапускСеансаПоПричинеДинамическогоОбновленияВерсииПрограммы(); КонецЕсли; КонецПроцедуры // Проверяет, что в текущем сеансе есть динамическое изменение конфигурации базы и // при этом нет режима обновления информационной базы. // // Возвращаемое значение: // Булево - Истина, если версия программы обновлена. // Функция ВерсияПрограммыОбновленаДинамически() Экспорт Если Не КонфигурацияБазыДанныхИзмененаДинамически() Тогда Возврат Ложь; КонецЕсли; // Если конфигурация базы данных изменена динамически после запуска // обновления информационной базы, но до его завершения, тогда нужно // продолжать обновление несмотря на изменение. Если ОбщегоНазначения.РазделениеВключено() Тогда // Параметры работы программы только неразделенные, поэтому для них обновление завершено, // если завершено обновление неразделенных данных. Возврат Не ОбновлениеИнформационнойБазыСлужебный.НеобходимоОбновлениеНеразделенныхДанныхИнформационнойБазы(); КонецЕсли; Возврат Не ОбновлениеИнформационнойБазы.НеобходимоОбновлениеИнформационнойБазы(); КонецФункции // Вызывает исключение с требованием перезапустить сеанс из-за обновления версии программы. Процедура ПотребоватьПерезапускСеансаПоПричинеДинамическогоОбновленияВерсииПрограммы() Экспорт ТекстОшибки = НСтр("ru = 'Версия программы обновлена, требуется перезапустить сеанс.'"); УстановитьТребуетсяПерезапускСеанса(ТекстОшибки); ВызватьИсключение ТекстОшибки; КонецПроцедуры // Вызывает исключение с требованием перезапустить сеанс из-за обновления расширений программы. Процедура ПотребоватьПерезапускСеансаПоПричинеДинамическогоОбновленияРасширенийПрограммы() Экспорт ТекстОшибки = НСтр("ru = 'Расширения программы обновлены, требуется перезапустить сеанс.'"); УстановитьТребуетсяПерезапускСеанса(ТекстОшибки); ВызватьИсключение ТекстОшибки; КонецПроцедуры // Устанавливает параметр сеанса необходимости перезапуска с текстом // краткого представления ошибки для проверки в исключении попытки. // // Параметры: // КраткоеПредставлениеОшибки - Строка - краткое представление текста ошибки при вызове // процедуры ПотребоватьПерезапускСеансаПоПричинеДинамическогоОбновленияВерсииПрограммы // или ПотребоватьПерезапускСеансаПоПричинеДинамическогоОбновленияРасширенийПрограммы. // Процедура УстановитьТребуетсяПерезапускСеанса(КраткоеПредставлениеОшибки) Экспорт Если ТекущийРежимЗапуска() <> Неопределено Тогда Возврат; КонецЕсли; ТекущийСеанс = ПолучитьТекущийСеансИнформационнойБазы(); Если ТекущийСеанс.ИмяПриложения <> "BackgroundJob" Тогда Возврат; КонецЕсли; Если ТребуетсяПерезапускСеанса() Тогда Возврат; КонецЕсли; ТекущиеПараметры = Новый Структура(ПараметрыСеанса.УстановленныеРасширения); ТекущиеПараметры.Вставить("ТребуетсяПерезапускСеанса", КраткоеПредставлениеОшибки); ПараметрыСеанса.УстановленныеРасширения = Новый ФиксированнаяСтруктура(ТекущиеПараметры); КонецПроцедуры // Возвращает факт вызова процедуры УстановитьТребуетсяПерезапускСеанса и // текст краткого представления ошибки установленный при вызове процедуры. // // Параметры: // КраткоеПредставлениеОшибки - Строка - возвращаемое значение, // установленное при вызове процедуры УстановитьТребуетсяПерезапускСеанса. // // Возвращаемое значение: // Булево // Функция ТребуетсяПерезапускСеанса(КраткоеПредставлениеОшибки = "") Экспорт Если Не ПараметрыСеанса.УстановленныеРасширения.Свойство("ТребуетсяПерезапускСеанса") Тогда Возврат Ложь; КонецЕсли; КраткоеПредставлениеОшибки = ПараметрыСеанса.УстановленныеРасширения.ТребуетсяПерезапускСеанса; Возврат Истина; КонецФункции // Проверяет, что пойманное исключение - это ошибка, краткое представление которой // начинается с текста, указанного при вызове процедуры УстановитьТребуетсяПерезапускСеанса. // // Параметры: // ИнформацияОбОшибке - ИнформацияОбОшибке // // Возвращаемое значение: // Булево // Функция ЭтоОшибкаТребованияПерезапускаСеанса(ИнформацияОбОшибке) Экспорт ТекстОшибки = ""; Если Не ТребуетсяПерезапускСеанса(ТекстОшибки) Тогда Возврат Ложь; КонецЕсли; Возврат ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") И ЗначениеЗаполнено(ТекстОшибки) И СтрНачинаетсяС(КраткоеПредставлениеОшибки(ИнформацияОбОшибке), ТекстОшибки); КонецФункции // Возвращает значение параметра работы программы. // // В старом сеансе (когда версия программы обновлена динамически), // если параметр не существует, вызывается исключение с требованием перезапуска, // иначе возвращается значение без учета версии. // // В разделенном режиме модели сервиса, если параметр не существует или // версия параметра не равна версии конфигурации вызывается исключение, // так как обновление неразделенных данных невозможно. // // Параметры: // ИмяПараметра - Строка - не более 128 символов. Например, // "СтандартныеПодсистемы.ВариантыОтчетов.ОтчетыСНастройками". // // Возвращаемое значение: // Произвольный - возвращается Неопределено, когда параметр не существует или // когда в новом сеансе версия параметра не равна версии конфигурации. // Функция ПараметрРаботыПрограммы(ИмяПараметра) Экспорт Возврат РегистрыСведений.ПараметрыРаботыПрограммы.ПараметрРаботыПрограммы(ИмяПараметра); КонецФункции // Устанавливает значение параметра работы программы. // Перед вызовом требуется установить привилегированный режим. // // Параметры: // ИмяПараметра - Строка - не более 128 символов. Например, // "СтандартныеПодсистемы.ВариантыОтчетов.ОтчетыСНастройками". // // Значение - Произвольный - значение, которое можно поместить в хранилище значения. // Процедура УстановитьПараметрРаботыПрограммы(ИмяПараметра, Значение) Экспорт РегистрыСведений.ПараметрыРаботыПрограммы.УстановитьПараметрРаботыПрограммы(ИмяПараметра, Значение); КонецПроцедуры // Обновляет значение параметра работы программы, если изменилось. // Перед вызовом требуется установить привилегированный режим. // // Параметры: // ИмяПараметра - Строка - не более 128 символов. Например, // "СтандартныеПодсистемы.ВариантыОтчетов.ОтчетыСНастройками". // // Значение - Произвольный - значение, которое можно поместить в хранилище значения. // // ЕстьИзменения - Булево - возвращаемое значение. Устанавливается Истина, // если старое и новое значения параметра не совпадают. // // СтароеЗначение - Произвольный - возвращаемое значение. До обновления. // Процедура ОбновитьПараметрРаботыПрограммы(ИмяПараметра, Значение, ЕстьИзменения = Ложь, СтароеЗначение = Неопределено) Экспорт РегистрыСведений.ПараметрыРаботыПрограммы.ОбновитьПараметрРаботыПрограммы(ИмяПараметра, Значение, ЕстьИзменения, СтароеЗначение); КонецПроцедуры // Возвращает изменения параметра работы программы с учетом текущей версии // конфигурации и текущей версии ИБ. // // Параметры: // ИмяПараметра - Строка - не более 128 символов. Например, // "СтандартныеПодсистемы.ВариантыОтчетов.ОтчетыСНастройками". // // Возвращаемое значение: // Неопределено - означает, что изменилось все. Возвращается // при начальном заполнении ИБ или области данных. // Массив - содержит значения изменений, если массив пустой, значит изменений нет. // Может быть несколько изменений, например, когда область данных давно не обновлялась. // Функция ИзмененияПараметраРаботыПрограммы(ИмяПараметра) Экспорт Возврат РегистрыСведений.ПараметрыРаботыПрограммы.ИзмененияПараметраРаботыПрограммы(ИмяПараметра); КонецФункции // Добавить изменения параметра работы программы при переходе на текущую версию метаданных конфигурации. // В дальнейшем изменения используются для условного добавления обязательных обработчиков обновления. // При начальном заполнении ИБ или неразделенных данных добавление изменений пропускается. // // Параметры: // ИмяПараметра - Строка - не более 128 символов. Например, // "СтандартныеПодсистемы.ВариантыОтчетов.ОтчетыСНастройками". // // Изменения - Произвольный - фиксированные данные, которые регистрируются в качестве изменений. // Изменения не добавляются, если значение ИзменениеПараметра не заполнено. // Процедура ДобавитьИзмененияПараметраРаботыПрограммы(ИмяПараметра, Изменения) Экспорт РегистрыСведений.ПараметрыРаботыПрограммы.ДобавитьИзмененияПараметраРаботыПрограммы(ИмяПараметра, Изменения); КонецПроцедуры // Только для внутреннего использования. Процедура ЗарегистрироватьИзменениеПриоритетныхДанныхДляПодчиненныхУзловРИБ() Экспорт Если ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ() Или Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда Возврат; КонецЕсли; Если Не СтандартныеПодсистемыПовтИсп.ОтключитьИдентификаторыОбъектовМетаданных() Тогда Справочники.ИдентификаторыОбъектовМетаданных.ЗарегистрироватьПолноеИзменениеДляПодчиненныхУзловРИБ(); КонецЕсли; УзлыПлановОбменаРИБ = Новый Соответствие; Для Каждого ПланОбмена Из Метаданные.ПланыОбмена Цикл Если Не ПланОбмена.РаспределеннаяИнформационнаяБаза Тогда Продолжить; КонецЕсли; УзлыРИБ = Новый Массив; УзлыПлановОбменаРИБ.Вставить(ПланОбмена.Состав, УзлыРИБ); ПланОбменаМенеджер = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПланОбмена.ПолноеИмя()); Выборка = ПланОбменаМенеджер.Выбрать(); Пока Выборка.Следующий() Цикл Если Выборка.Ссылка <> ПланОбменаМенеджер.ЭтотУзел() Тогда УзлыРИБ.Добавить(Выборка.Ссылка); КонецЕсли; КонецЦикла; КонецЦикла; Если УзлыПлановОбменаРИБ.Количество() > 0 Тогда ЗарегистрироватьИзменениеПредопределенных(УзлыПлановОбменаРИБ, Метаданные.Справочники); ЗарегистрироватьИзменениеПредопределенных(УзлыПлановОбменаРИБ, Метаданные.ПланыВидовХарактеристик); ЗарегистрироватьИзменениеПредопределенных(УзлыПлановОбменаРИБ, Метаданные.ПланыСчетов); ЗарегистрироватьИзменениеПредопределенных(УзлыПлановОбменаРИБ, Метаданные.ПланыВидовРасчета); КонецЕсли; КонецПроцедуры // Создает во всех списках недостающие предопределенные элементы с новыми ссылками (уникальными идентификаторами). // Для вызова после отключения подчиненного узла РИБ от главного, или для автоматического восстановления // отсутствующих предопределенных элементов. // Процедура ВосстановитьПредопределенныеЭлементы() Экспорт Если ПланыОбмена.ГлавныйУзел() <> Неопределено Тогда ВызватьИсключение НСтр("ru = 'Восстановление предопределенных элементов следует выполнять только в главном узле РИБ. |Затем выполнить синхронизацию с подчиненными узлами.'"); КонецЕсли; ОбъектыМетаданных = ОбъектыМетаданныхВсехПредопределенныхДанных(); Блокировка = Новый БлокировкаДанных; Для Каждого ОбъектМетаданных Из ОбъектыМетаданных Цикл Блокировка.Добавить(ОбъектМетаданных.ПолноеИмя()); КонецЦикла; НачатьТранзакцию(); Попытка Блокировка.Заблокировать(); УстановитьИнициализациюВсехПредопределенныхДанных(ОбъектыМетаданных); СоздатьНедостающиеПредопределенныеДанные(ОбъектыМетаданных); ЗафиксироватьТранзакцию(); Исключение ОтменитьТранзакцию(); ВызватьИсключение; КонецПопытки; КонецПроцедуры //////////////////////////////////////////////////////////////////////////////// // Процедуры для установки/получения параметров работы расширений (кэшей). // Возвращает значения параметра для текущей версии расширений. // Если не заполнен, возвращает Неопределено. // // Параметры: // ИмяПараметра - Строка - не более 128 символов. Например, // "СтандартныеПодсистемы.ВариантыОтчетов.ОтчетыСНастройками". // БезУчетаВерсииРасширений - Булево // // Возвращаемое значение: // Произвольный - возвращается Неопределено, если параметр не заполнен // для текущей версии расширений. // Функция ПараметрРаботыРасширения(ИмяПараметра, БезУчетаВерсииРасширений = Ложь) Экспорт Возврат РегистрыСведений.ПараметрыРаботыВерсийРасширений.ПараметрРаботыРасширения(ИмяПараметра, БезУчетаВерсииРасширений); КонецФункции // Устанавливает хранилище значения параметра для текущей версии расширений. // Используется для заполнения значений параметров. // Перед вызовом требуется установить привилегированный режим. // // Параметры: // ИмяПараметра - Строка - не более 128 символов. Например, // "СтандартныеПодсистемы.ВариантыОтчетов.ОтчетыСНастройками". // // Значение - Произвольный - значение параметра. // БезУчетаВерсииРасширений - Булево // Процедура УстановитьПараметрРаботыРасширения(ИмяПараметра, Значение, БезУчетаВерсииРасширений = Ложь) Экспорт РегистрыСведений.ПараметрыРаботыВерсийРасширений.УстановитьПараметрРаботыРасширения(ИмяПараметра, Значение, БезУчетаВерсииРасширений); КонецПроцедуры // Обработчик регламентного задания УдалениеУстаревшихПараметровРаботыВерсийРасширений. Процедура УдалениеУстаревшихПараметровРаботыВерсийРасширенийОбработчикЗадания() Экспорт ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания( Метаданные.РегламентныеЗадания.УдалениеУстаревшихПараметровРаботыВерсийРасширений); УстановитьПривилегированныйРежим(Истина); Справочники.ВерсииРасширений.УдалитьУстаревшиеВерсииПараметров(); КонецПроцедуры // Обработчик регламентного задания ЗаполнениеПараметровРаботыРасширений. Процедура ЗаполнениеПараметровРаботыРасширений() Экспорт // Регламентное задание должно запускаться сразу, как только было включено. // После успешного завершения задание отключает себя. ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания( Метаданные.РегламентныеЗадания.ЗаполнениеПараметровРаботыРасширений); УстановитьПривилегированныйРежим(Истина); РегистрыСведений.ПараметрыРаботыВерсийРасширений.ЗаполнитьВсеПараметрыРаботыПоследнейВерсииРасширений(); КонецПроцедуры // Только для внутреннего использования. Процедура ЗаполнитьВсеПараметрыРаботыРасширенийФоновоеЗадание(Параметры) Экспорт РегистрыСведений.ПараметрыРаботыВерсийРасширений.ЗаполнитьВсеПараметрыРаботыРасширенийФоновоеЗадание(Параметры); КонецПроцедуры //////////////////////////////////////////////////////////////////////////////// // Дополнительная базовая функциональность для обмена данными. // Выполняет регистрацию изменений объекта на всех узлах плана обмена. // Для разделенных конфигураций должны выполняться условия: // - план обмена должен быть разделенным, // - регистрируемый объект должен быть неразделенным. // // Параметры: // Объект - СправочникОбъект // - ДокументОбъект // - БизнесПроцессОбъект // - ЗадачаОбъект // - ПланВидовРасчетаОбъект // - ПланВидовХарактеристикОбъект // - ПланСчетовОбъект // - ПланОбменаОбъект // // ИмяПланаОбмена - Строка - имя плана обмена, на всех узлах которого требуется выполнить регистрацию объекта. // План обмена должен быть разделенным, иначе будет выдано исключение. // // ВключаяГлавныйУзел - Булево - если Ложь, тогда в подчиненном узле // не будет выполнена регистрация для главного узла. // // Процедура ЗарегистрироватьОбъектНаВсехУзлах(Знач Объект, Знач ИмяПланаОбмена, Знач ВключаяГлавныйУзел = Истина) Экспорт Если Метаданные.ПланыОбмена[ИмяПланаОбмена].Состав.Найти(Объект.Метаданные()) = Неопределено Тогда Возврат; КонецЕсли; Если ОбщегоНазначения.РазделениеВключено() Тогда Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда ВызватьИсключение НСтр("ru = 'Регистрация изменений неразделенных данных в разделенном режиме.'"); КонецЕсли; МодульРаботаВМоделиСервиса = Неопределено; Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса"); КонецЕсли; Если МодульРаботаВМоделиСервиса <> Неопределено Тогда ЭтоРазделенныйПланОбмена = МодульРаботаВМоделиСервиса.ЭтоРазделенныйОбъектМетаданных( "ПланОбмена." + ИмяПланаОбмена, МодульРаботаВМоделиСервиса.РазделительОсновныхДанных()); Иначе ЭтоРазделенныйПланОбмена = Ложь; КонецЕсли; Если Не ЭтоРазделенныйПланОбмена Тогда ВызватьИсключение НСтр("ru = 'Регистрация изменений для неразделенных планов обмена не поддерживается.'"); КонецЕсли; Если МодульРаботаВМоделиСервиса <> Неопределено Тогда ЭтоРазделенныйОбъектМетаданных = МодульРаботаВМоделиСервиса.ЭтоРазделенныйОбъектМетаданных( Объект.Метаданные().ПолноеИмя(), МодульРаботаВМоделиСервиса.РазделительОсновныхДанных()); Иначе ЭтоРазделенныйОбъектМетаданных = Ложь; КонецЕсли; Если ЭтоРазделенныйОбъектМетаданных Тогда ВызватьИсключение НСтр("ru = 'Регистрация изменений для разделенных объектов не поддерживается.'"); КонецЕсли; ТекстЗапроса = "ВЫБРАТЬ | ПланОбмена.Ссылка КАК Получатель |ИЗ | #ТаблицаПланаОбмена КАК ПланОбмена |ГДЕ | ПланОбмена.РегистрироватьИзменения | И НЕ ПланОбмена.ПометкаУдаления"; ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ТаблицаПланаОбмена", "ПланОбмена." + ИмяПланаОбмена); Запрос = Новый Запрос; Запрос.Текст = ТекстЗапроса; Получатели = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Получатель"); Для Каждого Получатель Из Получатели Цикл Объект.ОбменДанными.Получатели.Добавить(Получатель); КонецЦикла; Иначе ТекстЗапроса = "ВЫБРАТЬ | ПланОбмена.Ссылка КАК Получатель |ИЗ | #ТаблицаПланаОбмена КАК ПланОбмена |ГДЕ | НЕ ПланОбмена.ЭтотУзел | И НЕ ПланОбмена.ПометкаУдаления"; ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ТаблицаПланаОбмена", "ПланОбмена." + ИмяПланаОбмена); Запрос = Новый Запрос; Запрос.Текст = ТекстЗапроса; Получатели = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Получатель"); ГлавныйУзел = ПланыОбмена.ГлавныйУзел(); Для Каждого Получатель Из Получатели Цикл Если Не ВключаяГлавныйУзел И Получатель = ГлавныйУзел Тогда Продолжить; КонецЕсли; Объект.ОбменДанными.Получатели.Добавить(Получатель); КонецЦикла; КонецЕсли; КонецПроцедуры // Сохраняет ссылку на главный узел в константе ГлавныйУзел для возможности восстановления. Процедура СохранитьГлавныйУзел() Экспорт ГлавныйУзелМенеджер = Константы.ГлавныйУзел.СоздатьМенеджерЗначения(); ГлавныйУзелМенеджер.Значение = ПланыОбмена.ГлавныйУзел(); ОбновлениеИнформационнойБазы.ЗаписатьДанные(ГлавныйУзелМенеджер); КонецПроцедуры // Возвращаемое значение: // Булево - Истина, если выполнение происходит на учебной платформе, // на которой, например, недоступно получение свойства ПользовательОС. // Функция ЭтоУчебнаяПлатформа() Экспорт УстановитьПривилегированныйРежим(Истина); ТекущийПользователь = ПользователиИнформационнойБазы.ТекущийПользователь(); Попытка ПользовательОС = ТекущийПользователь.ПользовательОС; Исключение ПользовательОС = Неопределено; КонецПопытки; Возврат ПользовательОС = Неопределено; КонецФункции //////////////////////////////////////////////////////////////////////////////// // Обработчики отправки и получения данных для обмена в распределенной ИБ. // Процедура является обработчиком одноименного события, возникающего при обмене данными в распределенной // информационной базе. // См. описание параметров в обработчике события ПриОтправкеДанныхПодчиненному в синтакс-помощнике. // // Параметры: // ЭлементДанных - Произвольный // ОтправкаЭлемента - ОтправкаЭлементаДанных // СозданиеНачальногоОбраза - Булево // Получатель - ПланОбменаОбъект // Процедура ПриОтправкеДанныхПодчиненному(ЭлементДанных, ОтправкаЭлемента, Знач СозданиеНачальногоОбраза, Знач Получатель) Экспорт Если ОтправкаЭлемента = ОтправкаЭлементаДанных.Игнорировать Тогда Возврат; КонецЕсли; // Отправка идентификаторов объектов метаданных выполняется в другой секции сообщения обмена. ИгнорироватьОтправкуИдентификаторовОбъектовМетаданных(ЭлементДанных, ОтправкаЭлемента, СозданиеНачальногоОбраза); ИгнорироватьОтправкуДанныхОбработанныхВЦентральномУзлеРИБПриОбновленииИБ(ЭлементДанных, СозданиеНачальногоОбраза, Получатель); Если ОтправкаЭлемента = ОтправкаЭлементаДанных.Игнорировать Тогда Возврат; КонецЕсли; ПодсистемаОбменДаннымиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными"); // Вставка кода от подсистемы обмена данными должна быть первой. Если ПодсистемаОбменДаннымиСуществует Тогда МодульОбменДаннымиСобытия = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСобытия"); МодульОбменДаннымиСобытия.ПриОтправкеДанныхКорреспонденту(ЭлементДанных, ОтправкаЭлемента, СозданиеНачальногоОбраза, Получатель, Ложь); Если ОтправкаЭлемента = ОтправкаЭлементаДанных.Игнорировать Тогда Возврат; КонецЕсли; КонецЕсли; ИнтеграцияПодсистемБСП.ПриОтправкеДанныхПодчиненному(ЭлементДанных, ОтправкаЭлемента, СозданиеНачальногоОбраза, Получатель); Если ОтправкаЭлемента = ОтправкаЭлементаДанных.Игнорировать Тогда Возврат; КонецЕсли; // Вставка кода от подсистемы обмена данными в модели сервиса должна быть последней, влияющей на логику отправки. Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаВМоделиСервиса.ОбменДаннымиВМоделиСервиса") Тогда МодульОбменДаннымиВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиВМоделиСервиса"); МодульОбменДаннымиВМоделиСервиса.ПриОтправкеДанныхПодчиненному(ЭлементДанных, ОтправкаЭлемента, СозданиеНачальногоОбраза, Получатель); Если ОтправкаЭлемента = ОтправкаЭлементаДанных.Игнорировать Тогда Возврат; КонецЕсли; КонецЕсли; Если ПодсистемаОбменДаннымиСуществует Тогда МодульОбменДаннымиСервер = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСервер"); МодульОбменДаннымиСервер.РассчитатьПроцентВыгрузкиРИБ(Получатель, СозданиеНачальногоОбраза); КонецЕсли; КонецПроцедуры // Процедура является обработчиком одноименного события, возникающего при обмене данными в распределенной // информационной базе. // См. описание параметров в обработчике события ПриПолученииДанныхОтПодчиненного в синтакс-помощнике. // // Параметры: // ЭлементДанных - Произвольный // ПолучениеЭлемента - ПолучениеЭлементаДанных // ОтправкаНазад - Булево // Отправитель - ПланОбменаОбъект // Процедура ПриПолученииДанныхОтПодчиненного(ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад, Знач Отправитель) Экспорт // Идентификаторы объектов метаданных могут изменяться только в главном узле. ИгнорироватьПолучениеИдентификаторовОбъектовМетаданных(ЭлементДанных, ПолучениеЭлемента); Если ПолучениеЭлемента = ПолучениеЭлементаДанных.Игнорировать Тогда Возврат; КонецЕсли; ИнтеграцияПодсистемБСП.ПриПолученииДанныхОтПодчиненного(ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад, Отправитель); Если ПолучениеЭлемента = ПолучениеЭлементаДанных.Игнорировать Тогда Возврат; КонецЕсли; // Вызов переопределяемого обработчика для выполнения прикладной логики обмена РИБ. ОбщегоНазначенияПереопределяемый.ПриПолученииДанныхОтПодчиненного(ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад, Отправитель); ПодсистемаОбменДаннымиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными"); // Вставка кода от подсистемы обмена данными должна быть последней, влияющей на логику получения. Если ПодсистемаОбменДаннымиСуществует Тогда МодульОбменДаннымиСобытия = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСобытия"); МодульОбменДаннымиСобытия.ПриПолученииДанныхОтПодчиненногоВКонце(ЭлементДанных, ПолучениеЭлемента, Отправитель); КонецЕсли; Если ПодсистемаОбменДаннымиСуществует Тогда МодульОбменДаннымиСервер = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСервер"); МодульОбменДаннымиСервер.РассчитатьПроцентЗагрузкиРИБ(Отправитель); КонецЕсли; КонецПроцедуры // Процедура является обработчиком одноименного события, возникающего при обмене данными в распределенной // информационной базе. // См. описание обработчика события ПриПолученииДанныхОтГлавного в синтакс-помощнике. // Параметр Отправитель может быть не заполнен, например, при получении сообщения начального образа в АРМе. // // Параметры: // ЭлементДанных - Произвольный // ПолучениеЭлемента - ПолучениеЭлементаДанных // ОтправкаНазад - Булево // Отправитель - ПланОбменаОбъект // Процедура ПриПолученииДанныхОтГлавного(ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад, Отправитель = Неопределено) Экспорт Если ПолучениеЭлемента = ПолучениеЭлементаДанных.Игнорировать Тогда Возврат; КонецЕсли; ПодсистемаОбменДаннымиСуществует = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными"); // Вставка кода от подсистемы обмена данными должна быть первой. Если ПодсистемаОбменДаннымиСуществует Тогда МодульОбменДаннымиСобытия = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСобытия"); МодульОбменДаннымиСобытия.ПриПолученииДанныхОтГлавногоВНачале(ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад, Отправитель); Если ПолучениеЭлемента = ПолучениеЭлементаДанных.Игнорировать Тогда Возврат; КонецЕсли; КонецЕсли; ИнтеграцияПодсистемБСП.ПриПолученииДанныхОтГлавного(ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад, Отправитель); Если ПолучениеЭлемента = ПолучениеЭлементаДанных.Игнорировать Тогда Возврат; КонецЕсли; // Вызов переопределяемого обработчика для выполнения прикладной логики обмена РИБ. ОбщегоНазначенияПереопределяемый.ПриПолученииДанныхОтГлавного(Отправитель, ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад); // Вставка кода от подсистемы обмена данными должна быть последней, влияющей на логику получения. Если ПодсистемаОбменДаннымиСуществует И Не СозданиеНачальногоОбраза(ЭлементДанных) Тогда МодульОбменДаннымиСобытия = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСобытия"); МодульОбменДаннымиСобытия.ПриПолученииДанныхОтГлавногоВКонце(ЭлементДанных, ПолучениеЭлемента, Отправитель); КонецЕсли; Если ПодсистемаОбменДаннымиСуществует Тогда МодульОбменДаннымиСервер = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСервер"); МодульОбменДаннымиСервер.РассчитатьПроцентЗагрузкиРИБ(Отправитель); КонецЕсли; КонецПроцедуры //////////////////////////////////////////////////////////////////////////////// // Дополнительные функции для работы с типами. // Возвращает тип ссылки или ключа записи указанного объекта метаданных. // // Параметры: // ОбъектМетаданных - ОбъектМетаданных - регистр или ссылочный объект. // // Возвращаемое значение: // Тип // Функция ТипСсылкиИлиКлючаЗаписиОбъектаМетаданных(ОбъектМетаданных) Экспорт Если ОбщегоНазначения.ЭтоРегистр(ОбъектМетаданных) Тогда Если ОбщегоНазначения.ЭтоРегистрСведений(ОбъектМетаданных) Тогда ВидРегистра = "РегистрСведений"; ИначеЕсли ОбщегоНазначения.ЭтоРегистрНакопления(ОбъектМетаданных) Тогда ВидРегистра = "РегистрНакопления"; ИначеЕсли ОбщегоНазначения.ЭтоРегистрБухгалтерии(ОбъектМетаданных) Тогда ВидРегистра = "РегистрБухгалтерии"; ИначеЕсли ОбщегоНазначения.ЭтоРегистрРасчета(ОбъектМетаданных) Тогда ВидРегистра = "РегистрРасчета"; КонецЕсли; Тип = Тип(ВидРегистра + "КлючЗаписи." + ОбъектМетаданных.Имя); Иначе Менеджер = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ОбъектМетаданных.ПолноеИмя()); Тип = ТипЗнч(Менеджер.ПустаяСсылка()); КонецЕсли; Возврат Тип; КонецФункции // Возвращает тип объекта или набора записей указанного объекта метаданных. // // Параметры: // ОбъектМетаданных - ОбъектМетаданных - регистр или ссылочный объект. // // Возвращаемое значение: // Тип // Функция ТипОбъектаИлиНабораЗаписейОбъектаМетаданных(ОбъектМетаданных) Экспорт Если ОбщегоНазначения.ЭтоРегистр(ОбъектМетаданных) Тогда Если ОбщегоНазначения.ЭтоРегистрСведений(ОбъектМетаданных) Тогда ВидРегистра = "РегистрСведений"; ИначеЕсли ОбщегоНазначения.ЭтоРегистрНакопления(ОбъектМетаданных) Тогда ВидРегистра = "РегистрНакопления"; ИначеЕсли ОбщегоНазначения.ЭтоРегистрБухгалтерии(ОбъектМетаданных) Тогда ВидРегистра = "РегистрБухгалтерии"; ИначеЕсли ОбщегоНазначения.ЭтоРегистрРасчета(ОбъектМетаданных) Тогда ВидРегистра = "РегистрРасчета"; КонецЕсли; Тип = Тип(ВидРегистра + "НаборЗаписей." + ОбъектМетаданных.Имя); Иначе Менеджер = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ОбъектМетаданных.ПолноеИмя()); ВидОбъекта = ОбщегоНазначения.ВидОбъектаПоТипу(ТипЗнч(Менеджер.ПустаяСсылка())); Тип = Тип(ВидОбъекта + "Объект." + ОбъектМетаданных.Имя); КонецЕсли; Возврат Тип; КонецФункции // Выполняет проверку, что переданный объект имеет тип СправочникОбъект.ИдентификаторыОбъектовМетаданных. // // Параметры: // Объект - Произвольный // // Возвращаемое значение: // Булево // Функция ЭтоИдентификаторОбъектаМетаданных(Объект) Экспорт Возврат ТипЗнч(Объект) = Тип("СправочникОбъект.ИдентификаторыОбъектовМетаданных"); КонецФункции //////////////////////////////////////////////////////////////////////////////// // Процедуры и функции работы с формами. // Устанавливает ключ назначения формы (ключ назначения использования и // ключ сохранения положения окна). При необходимости копирует текущие настройки формы, // если для соответствующего нового ключа они еще не были записаны. // // Параметры: // Форма - ФормаКлиентскогоПриложения - форма ПриСозданииНаСервере, которой устанавливается ключ. // Ключ - Строка - новый ключ назначения формы. // КлючПоложения - Строка // УстановитьНастройки - Булево - установить новому ключу настройки, сохраненные для текущего ключа. // Процедура УстановитьКлючНазначенияФормы(Форма, Ключ, КлючПоложения = "", УстановитьНастройки = Истина) Экспорт УстановитьКлючНазначенияИспользованияФормы(Форма, Ключ, УстановитьНастройки); УстановитьКлючСохраненияПоложенияОкнаФормы(Форма, ?(КлючПоложения = "", Ключ, КлючПоложения), УстановитьНастройки); КонецПроцедуры Процедура СброситьРазмерыИПоложениеОкна(Форма) Экспорт Если Не ПравоДоступа("СохранениеДанныхПользователя", Метаданные) Тогда Возврат; КонецЕсли; ИмяФормы = Форма.ИмяФормы; НовыйКлючСохраненияПоложенияОкна = СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "_"); КлючОбъектаХранения = ИмяФормы + "/ВременныеКлючиСохраненияПоложенияОкна"; ИмяПользователя = ИмяПользователя(); НачалоДня = НачалоДня(ТекущаяУниверсальнаяДата()); ГраницаУстаревания = НачалоДня - 2*24*60*60; Ключи = ХранилищеСистемныхНастроек.Загрузить(КлючОбъектаХранения); Если ТипЗнч(Ключи) = Тип("Соответствие") Тогда ИменаНастроек = Новый Массив; ИменаНастроек.Добавить("/НастройкиОкна"); ИменаНастроек.Добавить("/НастройкиОкнаВебКлиента"); ИменаНастроек.Добавить("/НастройкиОкнаМобильногоКлиента"); ИменаНастроек.Добавить("/Такси/НастройкиОкна"); ИменаНастроек.Добавить("/Такси/НастройкиОкнаВебКлиента"); ИменаНастроек.Добавить("/Такси/НастройкиОкнаМобильногоКлиента"); Для Каждого КлючИЗначение Из Ключи Цикл ТекущийДень = КлючИЗначение.Ключ; Если ТипЗнч(ТекущийДень) <> Тип("Дата") Тогда Ключи = Неопределено; Прервать; КонецЕсли; Если ТекущийДень > ГраницаУстаревания Тогда Продолжить; КонецЕсли; КлючиТекущегоДня = КлючИЗначение.Значение; Если ТипЗнч(КлючиТекущегоДня) <> Тип("Массив") Тогда Ключи = Неопределено; Прервать; КонецЕсли; Для Каждого ТекущийКлюч Из КлючиТекущегоДня Цикл НачалоКлючаОбъекта = ИмяФормы + "/" + ТекущийКлюч; Для Каждого ИмяНастройки Из ИменаНастроек Цикл ХранилищеСистемныхНастроек.Удалить(НачалоКлючаОбъекта + ИмяНастройки, "", ИмяПользователя); КонецЦикла; КонецЦикла; Ключи.Удалить(ТекущийДень); КонецЦикла; КонецЕсли; ОчиститьСтарыеКлючи = ТипЗнч(Ключи) <> Тип("Соответствие"); Если ОчиститьСтарыеКлючи Тогда Ключи = Новый Соответствие; КонецЕсли; КлючиДня = Ключи.Получить(НачалоДня); Если ТипЗнч(КлючиДня) <> Тип("Массив") Тогда КлючиДня = Новый Массив; Ключи.Вставить(НачалоДня, КлючиДня); КонецЕсли; КлючиДня.Добавить(НовыйКлючСохраненияПоложенияОкна); ХранилищеСистемныхНастроек.Сохранить(КлючОбъектаХранения,, Ключи); Форма.КлючСохраненияПоложенияОкна = НовыйКлючСохраненияПоложенияОкна; Если Не ОчиститьСтарыеКлючи Тогда Возврат; КонецЕсли; Отбор = Новый Структура("Пользователь", ИмяПользователя); Выборка = ХранилищеСистемныхНастроек.Выбрать(Отбор); Пока Истина Цикл Попытка ЕстьСледующей = Выборка.Следующий(); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); ЗаписьЖурналаРегистрации( НСтр("ru = 'Ошибка выполнения'", ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке)); Прервать; КонецПопытки; Если Не ЕстьСледующей Тогда Прервать; КонецЕсли; Если Не СтрНачинаетсяС(Выборка.КлючОбъекта, ИмяФормы) Или Выборка.КлючНастроек <> "" Или Выборка.КлючОбъекта = КлючОбъектаХранения Тогда Продолжить; КонецЕсли; ЧастиКлючаОбъекта = СтрРазделить(Выборка.КлючОбъекта, "/"); Если ЧастиКлючаОбъекта.Количество() < 2 Тогда Продолжить; КонецЕсли; ПоследняяЧастьКлюча = ЧастиКлючаОбъекта[ЧастиКлючаОбъекта.ВГраница()]; Если СтрНайти(ПоследняяЧастьКлюча, "НастройкиОкна") > 0 Или СтрНайти(ПоследняяЧастьКлюча, "WindowSettings") > 0 Тогда ХранилищеСистемныхНастроек.Удалить(Выборка.КлючОбъекта, "", ИмяПользователя); КонецЕсли; КонецЦикла; КонецПроцедуры //////////////////////////////////////////////////////////////////////////////// // Прочие процедуры и функции. // Возвращает уточнения при возникновении проблем с параметрами работы программы. // // Возвращаемое значение: // Строка // Функция УточнениеОшибкиПараметровРаботыПрограммыДляРазработчика() Экспорт Возврат Символы.ПС + Символы.ПС + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Для разработчика: возможно требуется обновить вспомогательные данные, |которые влияют на работу программы. Для выполнения обновления можно: |- воспользоваться внешней обработкой | ""Инструменты разработчика: Обновление вспомогательных данных"", |- либо запустить программу с параметром командной строки 1С:Предприятия 8 | ""/С %1"", |- либо увеличить номер версии конфигурации, чтобы при очередном запуске | выполнились процедуры обновления данных информационной базы.'"), "ЗапуститьОбновлениеИнформационнойБазы"); КонецФункции // Возвращает текущего пользователя информационной базы. // // Возвращаемое значение: // ПользовательИнформационнойБазы // Функция ТекущийПользователь() Экспорт // Вычисляем актуальное имя пользователя, даже если оно было ранее изменено в текущем сеансе; // Например, для подключения к текущей ИБ через внешнее соединение из этого сеанса; // Во всех остальных случаях достаточно получить ПользователиИнформационнойБазы.ТекущийПользователь(). ТекущийПользователь = ПользователиИнформационнойБазы.НайтиПоУникальномуИдентификатору( ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор); Если ТекущийПользователь = Неопределено Тогда ТекущийПользователь = ПользователиИнформационнойБазы.ТекущийПользователь(); КонецЕсли; Возврат ТекущийПользователь; КонецФункции // Преобразует строку в допустимое наименование колонки таблицы значений, заменяя недопустимые // символы на код символа ограниченного символом подчеркивания. // // Параметры: // Строка - Строка - строка для преобразования. // // Возвращаемое значение: // Строка - строка, содержащая только допустимые символы для наименования колонок таблицы значений. // Функция ПреобразоватьСтрокуВДопустимоеНаименованиеКолонки(Строка) Экспорт НедопустимыеСимволы = ":;!@#$%^&-~`'.,?{}[]+=*/|\ ()_"""; Результат = ""; Для Индекс = 1 По СтрДлина(Строка) Цикл Символ = Сред(Строка, Индекс, 1); Если СтрНайти(НедопустимыеСимволы, Символ) > 0 Или (КодСимвола(Символ) > 126 И КодСимвола(Символ) < 256) Тогда Результат = Результат + "_" + КодСимвола(Символ) + "_"; Иначе Результат = Результат + Символ; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции // Преобразовать адаптированное наименование колонки, в котором недопустимые // символы заменены на код символа, ограниченного символом подчеркивания в обычную строку. // // Параметры: // НаименованиеКолонки - Строка - адаптированное наименование колонки. // // Возвращаемое значение: // Строка - преобразованная строка. // Функция ПреобразоватьАдаптированноеНаименованиеКолонкиВСтроку(НаименованиеКолонки) Экспорт Результат = ""; Для Индекс = 1 По СтрДлина(НаименованиеКолонки) Цикл Символ = Сред(НаименованиеКолонки, Индекс, 1); Если Символ = "_" Тогда ПозицияЗакрывающегоСимвола = СтрНайти(НаименованиеКолонки, "_", НаправлениеПоиска.СНачала, Индекс + 1); КодСимвола = Сред(НаименованиеКолонки, Индекс + 1, ПозицияЗакрывающегоСимвола - Индекс - 1); Результат = Результат + Символ(КодСимвола); Индекс = ПозицияЗакрывающегоСимвола; Иначе Результат = Результат + Символ; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции // Формирует сведения, необходимые для оповещения на клиенте открытых форм и динамических списков // о массовых изменениях объектов, которые произошли на сервере. // // Параметры: // ИзмененныеОбъекты - ЛюбаяСсылка // - Тип // - Массив - содержит сведения об измененных объектах. // Может быть передана ссылка или массив ссылок на измененные объекты, // либо можно указать тип или массив типов измененных объектов. // // Возвращаемое значение: // Соответствие из КлючИЗначение: // * Ключ - Тип - например, ДокументСсылка.ЗаказПокупателя. // * Значение - Структура: // ** ИмяСобытия - Строка - например, "Запись_ЗаказПокупателя". // ** ПустаяСсылка - ЛюбаяСсылка // Функция ПодготовитьОповещениеФормОбИзменении(ИзмененныеОбъекты) Экспорт Результат = Новый Соответствие; Если ИзмененныеОбъекты = Неопределено Тогда Возврат Результат; КонецЕсли; МассивТипов = Новый Массив; ТипСсылкиИлиТипаИлиМассива = ТипЗнч(ИзмененныеОбъекты); Если ТипСсылкиИлиТипаИлиМассива = Тип("Массив") Тогда Для Каждого Элемент Из ИзмененныеОбъекты Цикл ТипЭлемента = ТипЗнч(Элемент); Если ТипЭлемента = Тип("Тип") Тогда ТипЭлемента = Элемент; КонецЕсли; Если МассивТипов.Найти(ТипЭлемента) = Неопределено Тогда МассивТипов.Добавить(ТипЭлемента); КонецЕсли; КонецЦикла; Иначе МассивТипов.Добавить(ИзмененныеОбъекты); КонецЕсли; Для Каждого ТипЭлемента Из МассивТипов Цикл ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЭлемента); Если ТипЗнч(ОбъектМетаданных) <> Тип("ОбъектМетаданных") Тогда Продолжить; КонецЕсли; ИмяСобытия = "Запись_" + ОбъектМетаданных.Имя; Попытка ПустаяСсылка = ПредопределенноеЗначение(ОбъектМетаданных.ПолноеИмя() + ".ПустаяСсылка"); Исключение ПустаяСсылка = Неопределено; КонецПопытки; Результат.Вставить(ТипЭлемента, Новый Структура("ИмяСобытия,ПустаяСсылка", ИмяСобытия, ПустаяСсылка)); КонецЦикла; Возврат Результат; КонецФункции // Устанавливает общую форму ПустойРабочийСтол на рабочий стол с пустым составом форм. // // Для корректного отображения разделенного рабочего стола в веб-клиенте // неразделенный рабочий стол должен иметь не пустой состав форм, и наоборот. // Процедура УстановитьПустуюФормуНаПустойРабочийСтол() Экспорт КлючОбъекта = "Общее/НастройкиНачальнойСтраницы"; ТекущиеНастройки = ХранилищеСистемныхНастроек.Загрузить(КлючОбъекта); Если ТекущиеНастройки = Неопределено Тогда ТекущиеНастройки = Новый НастройкиНачальнойСтраницы; КонецЕсли; ТекущийСоставФорм = ТекущиеНастройки.ПолучитьСоставФорм(); Если ТекущийСоставФорм.ЛеваяКолонка.Количество() = 0 И ТекущийСоставФорм.ПраваяКолонка.Количество() = 0 Тогда ТекущийСоставФорм.ЛеваяКолонка.Добавить("ОбщаяФорма.ПустойРабочийСтол"); ТекущиеНастройки.УстановитьСоставФорм(ТекущийСоставФорм); ХранилищеСистемныхНастроек.Сохранить(КлючОбъекта, "", ТекущиеНастройки); КонецЕсли; КонецПроцедуры // Проверяет доступность проведения списка документов текущему пользователю. // // Параметры: // СписокДокументов - Массив - документы для проверки. // // Возвращаемое значение: // Булево - Истина, если есть право проведения хотя бы для одного документа. // Функция ДоступноПравоПроведения(СписокДокументов) Экспорт ТипыДокументов = Новый Массив; Для Каждого Документ Из СписокДокументов Цикл ТипДокумента = ТипЗнч(Документ); Если ТипыДокументов.Найти(ТипДокумента) <> Неопределено Тогда Продолжить; Иначе ТипыДокументов.Добавить(ТипДокумента); КонецЕсли; Если ПравоДоступа("Проведение", Метаданные.НайтиПоТипу(ТипДокумента)) Тогда Возврат Истина; КонецЕсли; КонецЦикла; Возврат Ложь; КонецФункции // Проверяет, что переданная таблица является регистром. // // Параметры: // ИмяТаблицы - Строка - полное имя таблицы. // // Возвращаемое значение: // Булево // Функция ЭтоТаблицаРегистра(ИмяТаблицы) Экспорт ВРегИмяТаблицы = ВРег(ИмяТаблицы); Если СтрНачинаетсяС(ВРегИмяТаблицы, ВРег("РегистрСведений")) Или СтрНачинаетсяС(ВРегИмяТаблицы, ВРег("РегистрНакопления")) Или СтрНачинаетсяС(ВРегИмяТаблицы, ВРег("РегистрБухгалтерии")) Или СтрНачинаетсяС(ВРегИмяТаблицы, ВРег("РегистрРасчета")) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // Возвращает представление начальной (главной) страницы. // // Возвращаемое значение: // Строка // Функция ПредставлениеНачальнойСтраницы() Экспорт Возврат НСтр("ru = 'Главное'"); КонецФункции //////////////////////////////////////////////////////////////////////////////// // Обработчики событий подсистем конфигурации. // См. ЗагрузкаДанныхИзФайлаПереопределяемый.ПриОпределенииСправочниковДляЗагрузкиДанных. Процедура ПриОпределенииСправочниковДляЗагрузкиДанных(ЗагружаемыеСправочники) Экспорт // Загрузка в справочник ИдентификаторыОбъектовМетаданных запрещена. СтрокаТаблицы = ЗагружаемыеСправочники.Найти(Метаданные.Справочники.ИдентификаторыОбъектовМетаданных.ПолноеИмя(), "ПолноеИмя"); Если СтрокаТаблицы <> Неопределено Тогда ЗагружаемыеСправочники.Удалить(СтрокаТаблицы); КонецЕсли; // Загрузка в справочник ИдентификаторыОбъектовРасширений запрещена. СтрокаТаблицы = ЗагружаемыеСправочники.Найти(Метаданные.Справочники.ИдентификаторыОбъектовРасширений.ПолноеИмя(), "ПолноеИмя"); Если СтрокаТаблицы <> Неопределено Тогда ЗагружаемыеСправочники.Удалить(СтрокаТаблицы); КонецЕсли; КонецПроцедуры // См. ГрупповоеИзменениеОбъектовПереопределяемый.ПриОпределенииОбъектовСРедактируемымиРеквизитами. Процедура ПриОпределенииОбъектовСРедактируемымиРеквизитами(Объекты) Экспорт Объекты.Вставить(Метаданные.Справочники.ИдентификаторыОбъектовМетаданных.ПолноеИмя(), "РеквизитыРедактируемыеВГрупповойОбработке"); Объекты.Вставить(Метаданные.Справочники.ИдентификаторыОбъектовРасширений.ПолноеИмя(), "РеквизитыРедактируемыеВГрупповойОбработке"); КонецПроцедуры // См. ОбщегоНазначенияПереопределяемый.ПриДобавленииИсключенийПоискаСсылок. Процедура ПриДобавленииИсключенийПоискаСсылок(ИсключенияПоискаСсылок) Экспорт ИсключенияПоискаСсылок.Добавить(Метаданные.РегистрыСведений.БезопасноеХранилищеДанных.Измерения.Владелец); ИсключенияПоискаСсылок.Добавить(Метаданные.РегистрыСведений.БезопасноеХранилищеДанныхОбластейДанных.Измерения.Владелец); КонецПроцедуры // См. ОбщегоНазначенияПереопределяемый.ПриДобавленииПараметровРаботыКлиента. Процедура ПриДобавленииПараметровРаботыКлиента(Параметры) Экспорт ДобавитьПараметрыРаботыКлиента(Параметры); КонецПроцедуры // См. ВыгрузкаЗагрузкаДанныхПереопределяемый.ПриЗаполненииТиповОбщихДанныхПоддерживающихСопоставлениеСсылокПриЗагрузке. Процедура ПриЗаполненииТиповОбщихДанныхПоддерживающихСопоставлениеСсылокПриЗагрузке(Типы) Экспорт Типы.Добавить(Метаданные.Справочники.ИдентификаторыОбъектовМетаданных); КонецПроцедуры // См. ВыгрузкаЗагрузкаДанныхПереопределяемый.ПриЗаполненииТиповИсключаемыхИзВыгрузкиЗагрузки. Процедура ПриЗаполненииТиповИсключаемыхИзВыгрузкиЗагрузки(Типы) Экспорт Типы.Добавить(Метаданные.Константы.АдресПубликацииИнформационнойБазыВИнтернете); Типы.Добавить(Метаданные.Константы.АдресПубликацииИнформационнойБазыВЛокальнойСети); Типы.Добавить(Метаданные.Константы.ИдентификаторИнформационнойБазы); Типы.Добавить(Метаданные.Справочники.ВерсииРасширений); Типы.Добавить(Метаданные.Справочники.ИдентификаторыОбъектовРасширений); Типы.Добавить(Метаданные.РегистрыСведений.ИдентификаторыОбъектовВерсийРасширений); Типы.Добавить(Метаданные.РегистрыСведений.ПараметрыРаботыВерсийРасширений); КонецПроцедуры // См. РаботаВБезопасномРежимеПереопределяемый.ПриЗаполненииРазрешенийНаДоступКВнешнимРесурсам. Процедура ПриЗаполненииРазрешенийНаДоступКВнешнимРесурсам(ЗапросыРазрешений) Экспорт МодульРаботаВБезопасномРежиме = ОбщегоНазначения.ОбщийМодуль("РаботаВБезопасномРежиме"); Разрешения = Новый Массив(); Разрешения.Добавить(МодульРаботаВБезопасномРежиме.РазрешениеНаИспользованиеКаталогаВременныхФайлов(Истина, Истина, НСтр("ru = 'Для возможности работы программы.'"))); Разрешения.Добавить(МодульРаботаВБезопасномРежиме.РазрешениеНаИспользованиеПривилегированногоРежима()); ЗапросыРазрешений.Добавить( МодульРаботаВБезопасномРежиме.ЗапросНаИспользованиеВнешнихРесурсов(Разрешения)); ДобавитьЗапросРазрешенийНаИспользованиеРасширений(ЗапросыРазрешений); КонецПроцедуры // Параметры: // ТекущиеДела - см. ТекущиеДелаСервер.ТекущиеДела. // Процедура ПриЗаполненииСпискаТекущихДел(ТекущиеДела) Экспорт Идентификатор = "КонтрольДинамическогоОбновленияПрограммы"; Дело = ТекущиеДела.Добавить(); Дело.Идентификатор = Идентификатор; Дело.ЕстьДела = КонфигурацияБазыДанныхИзмененаДинамически() Или Справочники.ВерсииРасширений.РасширенияИзмененыДинамически(); Дело.Важное = Ложь; Дело.Представление = НСтр("ru = 'Установлено обновление программы'"); Дело.Форма = "ОбщаяФорма.КонтрольДинамическогоОбновления"; Дело.Владелец = НСтр("ru = 'Работа программы'"); МодульТекущиеДелаСервер = ОбщегоНазначения.ОбщийМодуль("ТекущиеДелаСервер"); Если МодульТекущиеДелаСервер.ДелоОтключено("РекомендацияПоПовышениюСкоростиРаботы") Тогда Возврат; КонецЕсли; Идентификатор = "РекомендацияПоПовышениюСкоростиРаботы"; Дело = ТекущиеДела.Добавить(); Дело.Идентификатор = Идентификатор; Дело.ЕстьДела = ТребуетсяПоказРекомендацииПоОбъемуОперативнойПамяти(); Дело.Важное = Истина; Дело.Представление = НСтр("ru = 'Скорость работы снижена'"); Дело.Форма = "Обработка.РекомендацияПоПовышениюСкоростиРаботы.Форма.Форма"; Дело.Владелец = НСтр("ru = 'Работа программы'"); КонецПроцедуры // См. ПользователиПереопределяемый.ПриОпределенииНазначенияРолей Процедура ПриОпределенииНазначенияРолей(НазначениеРолей) Экспорт // ТолькоДляАдминистраторовСистемы. НазначениеРолей.ТолькоДляАдминистраторовСистемы.Добавить( Метаданные.Роли.АдминистраторСистемы.Имя); НазначениеРолей.ТолькоДляАдминистраторовСистемы.Добавить( Метаданные.Роли.Администрирование.Имя); НазначениеРолей.ТолькоДляАдминистраторовСистемы.Добавить( Метаданные.Роли.ОбновлениеКонфигурацииБазыДанных.Имя); // ТолькоДляПользователейСистемы. НазначениеРолей.ТолькоДляПользователейСистемы.Добавить( Метаданные.Роли.ЗапускТолстогоКлиента.Имя); НазначениеРолей.ТолькоДляПользователейСистемы.Добавить( Метаданные.Роли.ЗапускВнешнегоСоединения.Имя); НазначениеРолей.ТолькоДляПользователейСистемы.Добавить( Метаданные.Роли.ЗапускAutomation.Имя); НазначениеРолей.ТолькоДляПользователейСистемы.Добавить( Метаданные.Роли.РежимТехническогоСпециалиста.Имя); НазначениеРолей.ТолькоДляПользователейСистемы.Добавить( Метаданные.Роли.ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок.Имя); // ТолькоДляВнешнихПользователей. НазначениеРолей.ТолькоДляВнешнихПользователей.Добавить( Метаданные.Роли.БазовыеПраваВнешнихПользователейБСП.Имя); // СовместноДляПользователейИВнешнихПользователей. НазначениеРолей.СовместноДляПользователейИВнешнихПользователей.Добавить( Метаданные.Роли.ЗапускТонкогоКлиента.Имя); НазначениеРолей.СовместноДляПользователейИВнешнихПользователей.Добавить( Метаданные.Роли.ЗапускВебКлиента.Имя); НазначениеРолей.СовместноДляПользователейИВнешнихПользователей.Добавить( Метаданные.Роли.ЗапускМобильногоКлиента.Имя); НазначениеРолей.СовместноДляПользователейИВнешнихПользователей.Добавить( Метаданные.Роли.ВыводНаПринтерФайлБуферОбмена.Имя); НазначениеРолей.СовместноДляПользователейИВнешнихПользователей.Добавить( Метаданные.Роли.СохранениеДанныхПользователя.Имя); КонецПроцедуры // См. ОчередьЗаданийПереопределяемый.ПриПолученииСпискаШаблонов. Процедура ПриПолученииСпискаШаблонов(ШаблоныЗаданий) Экспорт ШаблоныЗаданий.Добавить(Метаданные.РегламентныеЗадания.УдалениеУстаревшихПараметровРаботыВерсийРасширений.Имя); КонецПроцедуры // См. ОбновлениеИнформационнойБазыБСП.ПриДобавленииОбработчиковОбновления. Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт Обработчик = Обработчики.Добавить(); Обработчик.Версия = "*"; Обработчик.Процедура = "СтандартныеПодсистемыСервер.УстановитьКонстантуНеИспользоватьРазделениеПоОбластямДанных"; Обработчик.Приоритет = 99; Обработчик.ОбщиеДанные = Истина; Обработчик.МонопольныйРежим = Истина; Обработчик = Обработчики.Добавить(); Обработчик.Версия = "*"; Обработчик.Процедура = "СтандартныеПодсистемыСервер.ПометитьЗаписиКэшаВерсийНеактуальными"; Обработчик.Приоритет = 99; Обработчик.ОбщиеДанные = Истина; Обработчик.РежимВыполнения = "Оперативно"; Обработчик = Обработчики.Добавить(); Обработчик.НачальноеЗаполнение = Истина; Обработчик.Процедура = "ОбновлениеИнформационнойБазыСлужебный.НачальноеЗаполнениеПредопределенныхДанных"; КонецПроцедуры // См. РегламентныеЗаданияПереопределяемый.ПриОпределенииНастроекРегламентныхЗаданий Процедура ПриОпределенииНастроекРегламентныхЗаданий(Настройки) Экспорт Зависимость = Настройки.Добавить(); Зависимость.РегламентноеЗадание = Метаданные.РегламентныеЗадания.ОбработкаСервисовИнтеграции; Зависимость.РаботаетСВнешнимиРесурсами = Истина; КонецПроцедуры // См. ИнтеграцияПодсистемБСП.ПриОпределенииОбъектовИсключаемыхИзПроверки Процедура ПриОпределенииОбъектовИсключаемыхИзПроверки(Объекты) Экспорт Объекты.Добавить(Метаданные.РегистрыСведений.ИдентификаторыОбъектовВерсийРасширений); КонецПроцедуры // Формирует текст для вывода пользователю при необходимости динамического обновления. // // Возвращаемое значение: // Строка // Функция ТекстСообщенияПриДинамическомОбновлении(ДинамическиеИзмененияКонфигурации) Экспорт Сообщения = Новый Массив; ДинамическиеИзмененияКонфигурации = ДинамическиеИзмененияКонфигурации; Если ДинамическиеИзмененияКонфигурации.КонфигурацияБазыДанныхИзмененаДинамически Тогда ТекстСообщенияКонфигурация = НСтр("ru = 'Версия программы обновлена (внесены изменения в конфигурацию информационной базы).'"); Сообщения.Добавить(ТекстСообщенияКонфигурация); КонецЕсли; Если ДинамическиеИзмененияКонфигурации.Исправления <> Неопределено Тогда Если ДинамическиеИзмененияКонфигурации.Исправления.Добавлено > 0 И ДинамическиеИзмененияКонфигурации.Исправления.Удалено > 0 Тогда ТекстСообщенияПатчи = НСтр("ru = 'Установлены новые исправления (патчи): %1, удалены: %2.'") + "Ссылка"; ИначеЕсли ДинамическиеИзмененияКонфигурации.Исправления.Добавлено = 1 Тогда ТекстСообщенияПатчи = НСтр("ru = 'Установлено новое исправление (патч).'") + "Ссылка"; ИначеЕсли ДинамическиеИзмененияКонфигурации.Исправления.Добавлено > 0 Тогда ТекстСообщенияПатчи = НСтр("ru = 'Установлены новые исправления (патчи): %1.'") + "Ссылка"; ИначеЕсли ДинамическиеИзмененияКонфигурации.Исправления.Удалено > 0 Тогда ТекстСообщенияПатчи = НСтр("ru = 'Удалены исправления (патчи): %2.'"); КонецЕсли; ТекстСообщенияПатчи = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстСообщенияПатчи, ДинамическиеИзмененияКонфигурации.Исправления.Добавлено, ДинамическиеИзмененияКонфигурации.Исправления.Удалено); Сообщения.Добавить(ТекстСообщенияПатчи); КонецЕсли; Если ДинамическиеИзмененияКонфигурации.Расширения <> Неопределено Тогда Если ДинамическиеИзмененияКонфигурации.Расширения.Добавлено > 0 Тогда ТекстСообщенияРасширения = НСтр("ru = 'Установлены новые расширения: %1.'"); ТекстСообщенияРасширения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстСообщенияРасширения, ДинамическиеИзмененияКонфигурации.Расширения.Добавлено); Сообщения.Добавить(ТекстСообщенияРасширения); КонецЕсли; Если ДинамическиеИзмененияКонфигурации.Расширения.Удалено > 0 Тогда ТекстСообщенияРасширения = НСтр("ru = 'Удалены расширения: %1.'"); ТекстСообщенияРасширения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстСообщенияРасширения, ДинамическиеИзмененияКонфигурации.Расширения.Удалено); Сообщения.Добавить(ТекстСообщенияРасширения); КонецЕсли; Если ДинамическиеИзмененияКонфигурации.Расширения.Изменено > 0 Тогда ТекстСообщенияРасширения = НСтр("ru = 'Изменены расширения: %1.'"); ТекстСообщенияРасширения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстСообщенияРасширения, ДинамическиеИзмененияКонфигурации.Расширения.Изменено); Сообщения.Добавить(ТекстСообщенияРасширения); КонецЕсли; КонецЕсли; Сообщения.Добавить(НСтр("ru = 'Для того чтобы применить, рекомендуется перезапустить программу и продолжить работу.'")); Сообщения.Добавить(" "); Возврат СтрСоединить(Сообщения, Символы.ПС); КонецФункции // Определяет формат сохранения в PDF в зависимости от используемой платформы. // // Возвращаемое значение: // ТипФайлаТабличногоДокумента. // Функция ТипФайлаТабличногоДокументаPDF() Экспорт Возврат ТипФайлаТабличногоДокумента["PDF_A_3"]; КонецФункции // Определяет пользовательское представление формата сохранения в PDF в зависимости от используемой платформы. // // Возвращаемое значение: // Строка. // Функция ПредставлениеТипаФайлаТабличногоДокументаPDF() Экспорт Возврат НСтр("ru = 'Документ PDF/A (.pdf)'"); КонецФункции Функция ЯзыкиКонфигурации() Экспорт Языки = Новый Массив; Для каждого Язык Из Метаданные.Языки Цикл Языки.Добавить(Язык.КодЯзыка); КонецЦикла; Возврат Языки; КонецФункции // Параметры: // Заголовки - Соответствие - см. в синтакс-помощнике описание параметра Заголовки объекта HTTPОтвет. // // Возвращаемое значение: // Соответствие // Функция HTTPЗаголовкиВНижнийРегистр(Заголовки) Экспорт Результат = Новый Соответствие; Для каждого Заголовок Из Заголовки Цикл Результат.Вставить(НРег(Заголовок.Ключ), Заголовок.Значение); КонецЦикла; Возврат Результат; КонецФункции // Параметры: // Идентификатор - Строка - идентификатор компоненты. // Местоположение - Строка - местоположение макета компоненты (без указания версии). // ВнешняяКомпонента - Неопределено // - Структура - данные внешней компоненты: // * Идентификатор - Строка - идентификатор компоненты в справочнике. // * Версия - Строка - версия. // * Местоположение - Строка - местоположение. // * Доступна - Булево - признак доступности. // // Возвращаемое значение: // Структура: // * Идентификатор - Строка - идентификатор компоненты в справочнике. // * Местоположение - Строка - макет компоненты, адрес ссылки в справочнике. // * Версия - Строка - версия. // Функция КомпонентаПоследнейВерсии(Идентификатор, Местоположение, ВнешняяКомпонента = Неопределено) Экспорт КомпонентаПоследнейВерсии = Новый Структура; КомпонентаПоследнейВерсии.Вставить("Идентификатор", Идентификатор); КомпонентаПоследнейВерсии.Вставить("Местоположение", ""); КомпонентаПоследнейВерсии.Вставить("Версия", ""); // Информация о внешней компоненте. Если ВнешняяКомпонента <> Неопределено И ВнешняяКомпонента.Доступна Тогда ПоследняяВерсияВнешнейКомпоненты = Новый Структура("Версия, Местоположение", ВнешняяКомпонента.Версия, ВнешняяКомпонента.Местоположение); Иначе ПоследняяВерсияВнешнейКомпоненты = Неопределено; КонецЕсли; // Информация о компоненте из макета. Если ЗначениеЗаполнено(Местоположение) Тогда ПоследняяВерсияКомпонентыИзМакета = СтандартныеПодсистемыПовтИсп.ПоследняяВерсияКомпонентыИзМакета( Местоположение); Иначе ПоследняяВерсияКомпонентыИзМакета = Неопределено; КонецЕсли; Если ПоследняяВерсияВнешнейКомпоненты <> Неопределено И ПоследняяВерсияКомпонентыИзМакета <> Неопределено Тогда ЧастиВерсии = СтрРазделить(ПоследняяВерсияВнешнейКомпоненты.Версия, "."); Если ЧастиВерсии.Количество() = 4 Тогда Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ПоследняяВерсияВнешнейКомпоненты.Версия, ПоследняяВерсияКомпонентыИзМакета.Версия) > 0 Тогда ЗаполнитьЗначенияСвойств(КомпонентаПоследнейВерсии, ПоследняяВерсияВнешнейКомпоненты); Иначе ЗаполнитьЗначенияСвойств(КомпонентаПоследнейВерсии, ПоследняяВерсияКомпонентыИзМакета); КонецЕсли; Иначе // Если номер версии компоненты не соответствует шаблону, используется компонента из справочника. ЗаполнитьЗначенияСвойств(КомпонентаПоследнейВерсии, ПоследняяВерсияВнешнейКомпоненты); КонецЕсли; Возврат КомпонентаПоследнейВерсии; ИначеЕсли ПоследняяВерсияКомпонентыИзМакета <> Неопределено Тогда ЗаполнитьЗначенияСвойств(КомпонентаПоследнейВерсии, ПоследняяВерсияКомпонентыИзМакета); Возврат КомпонентаПоследнейВерсии; ИначеЕсли ПоследняяВерсияВнешнейКомпоненты <> Неопределено Тогда ЗаполнитьЗначенияСвойств(КомпонентаПоследнейВерсии, ПоследняяВерсияВнешнейКомпоненты); Возврат КомпонентаПоследнейВерсии; КонецЕсли; ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru='Не существует внешняя компонента с идентификатором %1'"), Идентификатор); КонецФункции #КонецОбласти #Область СлужебныеПроцедурыИФункции // Процедура является обработчиком одноименного события, возникающего при обмене данными в распределенной // информационной базе. // // Параметры: // см. описание обработчика события ПриОтправкеДанныхГлавному() в синтакс-помощнике. // Процедура ПриОтправкеДанныхГлавному(ЭлементДанных, ОтправкаЭлемента, Знач Получатель) Если ОтправкаЭлемента = ОтправкаЭлементаДанных.Игнорировать Тогда Возврат; КонецЕсли; // Отправка идентификаторов объектов метаданных выполняется в другой секции сообщения обмена. ИгнорироватьОтправкуИдентификаторовОбъектовМетаданных(ЭлементДанных, ОтправкаЭлемента); Если ОтправкаЭлемента = ОтправкаЭлементаДанных.Игнорировать Тогда Возврат; КонецЕсли; ИнтеграцияПодсистемБСП.ПриОтправкеДанныхГлавному(ЭлементДанных, ОтправкаЭлемента, Получатель); // Вызов переопределяемого обработчика для выполнения прикладной логики обмена РИБ. ОбщегоНазначенияПереопределяемый.ПриОтправкеДанныхГлавному(ЭлементДанных, ОтправкаЭлемента, Получатель); Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными") Тогда МодульОбменДаннымиСервер = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСервер"); МодульОбменДаннымиСервер.РассчитатьПроцентВыгрузкиРИБ(Получатель, Ложь); КонецЕсли; КонецПроцедуры // Заполняет структуру параметров, необходимых для работы клиентского кода // данной подсистемы при запуске конфигурации, т.е. в обработчиках событий. // - ПередНачаломРаботыСистемы, // - ПриНачалеРаботыСистемы. // // Важно: при запуске недопустимо использовать команды сброса кэша // повторно используемых модулей, иначе запуск может привести // к непредсказуемым ошибкам и лишним серверным вызовам. // // Параметры: // Параметры - Структура - структура параметров. // // Возвращаемое значение: // Булево - Ложь, если дальнейшее заполнение параметров необходимо прервать. // Функция ДобавитьПараметрыРаботыКлиентаПриЗапуске(Параметры) Экспорт ЭтоВызовПередНачаломРаботыСистемы = Параметры.ПолученныеПараметрыКлиента <> Неопределено; Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса"); ЭтоРазделеннаяКонфигурация = МодульРаботаВМоделиСервиса.ЭтоРазделеннаяКонфигурация(); Иначе ЭтоРазделеннаяКонфигурация = Ложь; КонецЕсли; // Обязательные параметры для продолжения работы. Параметры.Вставить("РазделениеВключено", ОбщегоНазначения.РазделениеВключено()); Параметры.Вставить("ДоступноИспользованиеРазделенныхДанных", ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных()); Параметры.Вставить("ЭтоРазделеннаяКонфигурация", ЭтоРазделеннаяКонфигурация); Параметры.Вставить("ЕстьДоступДляОбновленияВерсииПлатформы", Пользователи.ЭтоПолноправныйПользователь(,Истина)); Параметры.Вставить("ИменаПодсистем", СтандартныеПодсистемыПовтИсп.ИменаПодсистем()); Параметры.Вставить("ЭтоБазоваяВерсияКонфигурации", ЭтоБазоваяВерсияКонфигурации()); Параметры.Вставить("ЭтоУчебнаяПлатформа", ЭтоУчебнаяПлатформа()); Параметры.Вставить("ИмяТекущегоПользователя", ТекущийПользователь().Имя); Параметры.Вставить("ИмяCOMСоединителя", ОбщегоНазначенияКлиентСервер.ИмяCOMСоединителя()); Параметры.Вставить("КодОсновногоЯзыка", ОбщегоНазначения.КодОсновногоЯзыка()); Параметры.Вставить("ЗапрашиватьПодтверждениеПриЗавершенииПрограммы", ЗапрашиватьПодтверждениеПриЗавершенииПрограммы()); ОбщиеПараметры = ОбщегоНазначения.ОбщиеПараметрыБазовойФункциональности(); Параметры.Вставить("МинимальнаяВерсияПлатформы", ОбщиеПараметры.МинимальнаяВерсияПлатформы); Параметры.Вставить("РекомендуемаяВерсияПлатформы", ОбщиеПараметры.РекомендуемаяВерсияПлатформы); // Устарели. Для обратной совместимости. Параметры.Вставить("МинимальноНеобходимаяВерсияПлатформы", ОбщиеПараметры.МинимальноНеобходимаяВерсияПлатформы); Параметры.Вставить("РаботаВПрограммеЗапрещена", ОбщиеПараметры.РаботаВПрограммеЗапрещена); Параметры.Вставить("РекомендуемыйОбъемОперативнойПамяти", ОбщиеПараметры.РекомендуемыйОбъемОперативнойПамяти); Параметры.Вставить("ТребуетсяПоказРекомендацииПоОбъемуОперативнойПамяти", ТребуетсяПоказРекомендацииПоОбъемуОперативнойПамяти() И Не ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ТекущиеДела")); Параметры.Вставить("ЭтоСеансВнешнегоПользователя", Пользователи.ЭтоСеансВнешнегоПользователя()); Параметры.Вставить("ИнформационнаяБазаФайловая", ОбщегоНазначения.ИнформационнаяБазаФайловая()); Если ЭтоВызовПередНачаломРаботыСистемы Тогда Параметры.Вставить("ЭлементыСтиля", НаборЭлементовСтиля()); КонецЕсли; Если ЭтоВызовПередНачаломРаботыСистемы И Не Параметры.ПолученныеПараметрыКлиента.Свойство("ОпцииИнтерфейса") Тогда Параметры.Вставить("ОпцииИнтерфейса", СтандартныеПодсистемыПовтИсп.ОпцииИнтерфейса()); КонецЕсли; Если ЭтоВызовПередНачаломРаботыСистемы Тогда ОшибкаНедостаточноПравДляВходаВПрограмму = ПользователиСлужебный.ОшибкаНедостаточноПравДляВходаВПрограмму( Не Параметры.ПолученныеПараметрыКлиента.Свойство("ОшибкаНедостаточноПравДляВходаВПрограмму")); Если ЗначениеЗаполнено(ОшибкаНедостаточноПравДляВходаВПрограмму) Тогда Параметры.Вставить("ОшибкаНедостаточноПравДляВходаВПрограмму", ОшибкаНедостаточноПравДляВходаВПрограмму); Возврат Ложь; КонецЕсли; КонецЕсли; Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РегламентныеЗадания") Тогда МодульБлокировкаРаботыСВнешнимиРесурсами = ОбщегоНазначения.ОбщийМодуль("БлокировкаРаботыСВнешнимиРесурсами"); МодульБлокировкаРаботыСВнешнимиРесурсами.ПриДобавленииПараметровРаботыКлиентаПриЗапуске( Параметры, ЭтоВызовПередНачаломРаботыСистемы); Если РегламентныеЗаданияСервер.РаботаСВнешнимиРесурсамиЗаблокирована() Тогда Параметры.Вставить("РаботаСВнешнимиРесурсамиЗаблокирована"); КонецЕсли; КонецЕсли; Если Не ОбновлениеИнформационнойБазыСлужебный.ДобавитьПараметрыРаботыКлиентаПриЗапуске(Параметры) И ЭтоВызовПередНачаломРаботыСистемы Тогда Возврат Ложь; КонецЕсли; Если ЭтоВызовПередНачаломРаботыСистемы И Не Параметры.ПолученныеПараметрыКлиента.Свойство("ПоказатьНерекомендуемуюВерсиюПлатформы") И ПоказатьНерекомендуемуюВерсиюПлатформы(Параметры) Тогда Параметры.Вставить("ПоказатьНерекомендуемуюВерсиюПлатформы"); СтандартныеПодсистемыВызовСервера.СкрытьРабочийСтолПриНачалеРаботыСистемы(); Возврат Ложь; КонецЕсли; Если ЭтоВызовПередНачаломРаботыСистемы И Не Параметры.ПолученныеПараметрыКлиента.Свойство("ВосстановитьСвязьСГлавнымУзлом") И Не ОбщегоНазначения.РазделениеВключено() Тогда УстановитьПривилегированныйРежим(Истина); ВосстановитьСвязьСГлавнымУзлом = ПланыОбмена.ГлавныйУзел() = Неопределено И ЗначениеЗаполнено(Константы.ГлавныйУзел.Получить()); УстановитьПривилегированныйРежим(Ложь); Если ВосстановитьСвязьСГлавнымУзлом Тогда Параметры.Вставить("ВосстановитьСвязьСГлавнымУзлом", Пользователи.ЭтоПолноправныйПользователь(, Истина)); СтандартныеПодсистемыВызовСервера.СкрытьРабочийСтолПриНачалеРаботыСистемы(); Возврат Ложь; КонецЕсли; КонецЕсли; Если ЭтоВызовПередНачаломРаботыСистемы И Не Параметры.ПолученныеПараметрыКлиента.Свойство("ВыбратьНачальныеРегиональныеНастройкиИБ") И ТребуетсяУстановкаРегиональныхНастроекИнформационнойБазы() Тогда Параметры.Вставить("ВыбратьНачальныеРегиональныеНастройкиИБ", Пользователи.ЭтоПолноправныйПользователь(, Истина, Ложь)); СтандартныеПодсистемыВызовСервера.СкрытьРабочийСтолПриНачалеРаботыСистемы(); Возврат Ложь; КонецЕсли; Если ЭтоВызовПередНачаломРаботыСистемы И ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса") Тогда ОписаниеОшибки = ""; МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса"); МодульРаботаВМоделиСервиса.ПриПроверкеБлокировкиОбластиДанныхПриЗапуске(ОписаниеОшибки); Если Не ПустаяСтрока(ОписаниеОшибки) Тогда Параметры.Вставить("ОбластьДанныхЗаблокирована", ОписаниеОшибки); // Работа будет завершена. Возврат Ложь; КонецЕсли; КонецЕсли; Если Не Параметры.РазделениеВключено И ОбновлениеИнформационнойБазы.НеобходимоОбновлениеИнформационнойБазы() И ОбновлениеИнформационнойБазыСлужебный.СтатусНевыполненныхОбработчиков(Истина) = "СтатусНеВыполнено" Тогда Параметры.Вставить("НеобходимоВыполнитьОбработчикиОтложенногоОбновления"); КонецЕсли; Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ПрофилиБезопасности") Тогда МодульРаботаВБезопасномРежимеСлужебный = ОбщегоНазначения.ОбщийМодуль("РаботаВБезопасномРежимеСлужебный"); МодульРаботаВБезопасномРежимеСлужебный.ПриДобавленииПараметровРаботыКлиентаПриЗапуске(Параметры, Истина); КонецЕсли; Если ЭтоВызовПередНачаломРаботыСистемы И НЕ Параметры.ПолученныеПараметрыКлиента.Свойство("ПовторитьЗагрузкуСообщенияОбменаДаннымиПередЗапуском") И ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ() И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными") Тогда МодульОбменДаннымиСлужебный = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСлужебный"); Если МодульОбменДаннымиСлужебный.ПовторитьЗагрузкуСообщенияОбменаДаннымиПередЗапуском() Тогда Параметры.Вставить("ПовторитьЗагрузкуСообщенияОбменаДаннымиПередЗапуском"); Возврат Ложь; КонецЕсли; КонецЕсли; // Проверка необходимости предварительного обновления параметров работы программы. Если ЭтоВызовПередНачаломРаботыСистемы И НЕ Параметры.ПолученныеПараметрыКлиента.Свойство("НеобходимоОбновлениеПараметровРаботыПрограммы") Тогда Если РегистрыСведений.ПараметрыРаботыПрограммы.НеобходимоОбновление() Тогда // Будет выполнено предварительное обновление. Параметры.Вставить("НеобходимоОбновлениеПараметровРаботыПрограммы"); Возврат Ложь; КонецЕсли; КонецЕсли; // Обязательные параметры для всех режимов работы. Параметры.Вставить("ПодробнаяИнформация", Метаданные.ПодробнаяИнформация); Если ОбновлениеИнформационнойБазыСлужебный.НеобходимоОбновлениеНеразделенныхДанныхИнформационнойБазы() Тогда Параметры.Вставить("НеобходимоОбновлениеНеразделенныхДанныхИнформационнойБазы"); КонецЕсли; Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ПрофилиБезопасности") Тогда МодульРаботаВБезопасномРежимеСлужебный = ОбщегоНазначения.ОбщийМодуль("РаботаВБезопасномРежимеСлужебный"); МодульРаботаВБезопасномРежимеСлужебный.ПриДобавленииПараметровРаботыКлиентаПриЗапуске(Параметры); КонецЕсли; Если Параметры.РазделениеВключено И Не Параметры.ДоступноИспользованиеРазделенныхДанных Тогда Возврат Ложь; КонецЕсли; // Параметры для работы в локальном режиме или // в сеансе с установленными значениями разделителей в модели сервиса. Если ОбновлениеИнформационнойБазы.НеобходимоОбновлениеИнформационнойБазы() Тогда Параметры.Вставить("НеобходимоОбновлениеИнформационнойБазы"); СтандартныеПодсистемыВызовСервера.СкрытьРабочийСтолПриНачалеРаботыСистемы(); КонецЕсли; Если Не Параметры.РазделениеВключено И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными") Тогда МодульОбменДаннымиСервер = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСервер"); Если МодульОбменДаннымиСервер.ЗагрузитьСообщениеОбменаДанными() Тогда Параметры.Вставить("ЗагрузитьСообщениеОбменаДанными"); КонецЕсли; КонецЕсли; Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаВМоделиСервиса.ОбменДаннымиВМоделиСервиса") Тогда МодульАвтономнаяРабота = ОбщегоНазначения.ОбщийМодуль("АвтономнаяРабота"); Если МодульАвтономнаяРабота.ПродолжитьНастройкуАвтономногоРабочегоМеста(Параметры) Тогда Возврат Ложь; КонецЕсли; КонецЕсли; Отказ = Ложь; Если ЭтоВызовПередНачаломРаботыСистемы Тогда ПользователиСлужебный.ПриДобавленииПараметровРаботыКлиентаПриЗапуске(Параметры, Отказ, Истина); КонецЕсли; Если Отказ Тогда Возврат Ложь; КонецЕсли; ДобавитьОбщиеПараметрыРаботыКлиента(Параметры); Если ЭтоВызовПередНачаломРаботыСистемы И Параметры.Свойство("НеобходимоОбновлениеИнформационнойБазы") Тогда // Не следует добавлять остальные параметры до окончания обновления ИБ, // так как они могут рассчитывать, что обновление ИБ уже выполнено. Возврат Ложь; КонецЕсли; Возврат Истина; КонецФункции // Заполняет структуру параметров, необходимых для работы клиентского кода // данной подсистемы. // // Параметры: // Параметры - Структура // Процедура ДобавитьПараметрыРаботыКлиента(Параметры) Параметры.Вставить("ИменаПодсистем", СтандартныеПодсистемыПовтИсп.ИменаПодсистем()); Параметры.Вставить("ДоступноИспользованиеРазделенныхДанных", ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных()); Параметры.Вставить("РазделениеВключено", ОбщегоНазначения.РазделениеВключено()); Параметры.Вставить("ЭтоБазоваяВерсияКонфигурации", ЭтоБазоваяВерсияКонфигурации()); Параметры.Вставить("ЭтоУчебнаяПлатформа", ЭтоУчебнаяПлатформа()); Параметры.Вставить("ИмяCOMСоединителя", ОбщегоНазначенияКлиентСервер.ИмяCOMСоединителя()); Параметры.Вставить("ЭлементыСтиля", НаборЭлементовСтиля()); ДобавитьОбщиеПараметрыРаботыКлиента(Параметры); Параметры.Вставить("ИмяКонфигурации", Метаданные.Имя); Параметры.Вставить("СинонимКонфигурации", Метаданные.Синоним); Параметры.Вставить("ВерсияКонфигурации", Метаданные.Версия); Параметры.Вставить("ПодробнаяИнформация", Метаданные.ПодробнаяИнформация); Параметры.Вставить("КодОсновногоЯзыка", ОбщегоНазначения.КодОсновногоЯзыка()); Параметры.Вставить("ЗапрашиватьПодтверждениеПриЗавершенииПрограммы", ЗапрашиватьПодтверждениеПриЗавершенииПрограммы()); Параметры.Вставить("ИнформационнаяБазаФайловая", ОбщегоНазначения.ИнформационнаяБазаФайловая()); Если РегламентныеЗаданияСервер.РаботаСВнешнимиРесурсамиЗаблокирована() Тогда Параметры.Вставить("РаботаСВнешнимиРесурсамиЗаблокирована"); КонецЕсли; Параметры.Вставить("ВерсияРежимаСовместимости", ВерсияРежимаСовместимости()); КонецПроцедуры // Заполняет структуру параметров, необходимых для работы клиентского кода // при запуске конфигурации и в дальнейшем во время работы с ней. // // Параметры: // Параметры - Структура - структура параметров. // Процедура ДобавитьОбщиеПараметрыРаботыКлиента(Параметры) Если Не Параметры.РазделениеВключено Или Параметры.ДоступноИспользованиеРазделенныхДанных Тогда УстановитьПривилегированныйРежим(Истина); Параметры.Вставить("АвторизованныйПользователь", Пользователи.АвторизованныйПользователь()); Параметры.Вставить("ЗаголовокПриложения", СокрЛП(Константы.ЗаголовокСистемы.Получить())); УстановитьПривилегированныйРежим(Ложь); КонецЕсли; Параметры.Вставить("ЭтоГлавныйУзел", НЕ ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ()); Параметры.Вставить("ТребуетсяОбновлениеКонфигурацииУзлаРИБ", ОбщегоНазначения.ТребуетсяОбновлениеКонфигурацииПодчиненногоУзлаРИБ()); КонецПроцедуры // Возвращает номера версий, поддерживаемых программным интерфейсом ИмяИнтерфейса. // См. ОбщегоНазначения.ПолучитьВерсииИнтерфейсаЧерезВнешнееСоединение. // // Параметры: // ИмяИнтерфейса - Строка - имя программного интерфейса. // // Возвращаемое значение: // Массив - список версий типа Строка. // Функция ПоддерживаемыеВерсии(ИмяИнтерфейса) Экспорт МассивВерсий = Неопределено; СтруктураПоддерживаемыхВерсий = Новый Структура; ИнтеграцияПодсистемБСП.ПриОпределенииПоддерживаемыхВерсийПрограммныхИнтерфейсов(СтруктураПоддерживаемыхВерсий); СтруктураПоддерживаемыхВерсий.Свойство(ИмяИнтерфейса, МассивВерсий); Если МассивВерсий = Неопределено Тогда Возврат ОбщегоНазначения.ЗначениеВСтрокуXML(Новый Массив); Иначе Возврат ОбщегоНазначения.ЗначениеВСтрокуXML(МассивВерсий); КонецЕсли; КонецФункции // Устанавливает общую форму ПустойРабочийСтол на рабочий стол. Процедура УстановитьПустуюФормуНаРабочийСтол() Экспорт КлючОбъекта = "Общее/НастройкиНачальнойСтраницы"; ТекущиеНастройки = ХранилищеСистемныхНастроек.Загрузить(КлючОбъекта); Если ТипЗнч(ТекущиеНастройки) = Тип("НастройкиНачальнойСтраницы") Тогда ТекущийСоставФорм = ТекущиеНастройки.ПолучитьСоставФорм(); Если ТекущийСоставФорм.ПраваяКолонка.Количество() = 0 И ТекущийСоставФорм.ЛеваяКолонка.Количество() = 1 И ТекущийСоставФорм.ЛеваяКолонка[0] = "ОбщаяФорма.ПустойРабочийСтол" Тогда Возврат; КонецЕсли; КонецЕсли; СоставФорм = Новый СоставФормНачальнойСтраницы; СоставФорм.ЛеваяКолонка.Добавить("ОбщаяФорма.ПустойРабочийСтол"); Настройки = Новый НастройкиНачальнойСтраницы; Настройки.УстановитьСоставФорм(СоставФорм); ХранилищеСистемныхНастроек.Сохранить(КлючОбъекта, "", Настройки); КонецПроцедуры // Обработчик одноименного регламентного задания. // Процедура ОбработкаСервисовИнтеграции() Экспорт ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.ОбработкаСервисовИнтеграции); Если ОбщегоНазначения.РазделениеВключено() И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда Возврат; КонецЕсли; РежимСовместимости = ВерсияРежимаСовместимости(); Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(РежимСовместимости, "8.3.17.0") < 0 Тогда Возврат; КонецЕсли; // АПК:487-выкл - нет выполнения произвольного кода. Выполнить("СервисыИнтеграции.ВыполнитьОбработку()"); // АПК:487-вкл КонецПроцедуры //////////////////////////////////////////////////////////////////////////////// // Обновление информационной базы. // Устанавливает значение константам НеИспользоватьРазделениеПоОбластямДанных и // СтандартныеПодсистемыВАвтономномРежиме на основании значения ИспользоватьРазделениеПоОбластямДанных. // Процедура УстановитьКонстантуНеИспользоватьРазделениеПоОбластямДанных(Параметры) Экспорт НовыеЗначения = Новый Соответствие; Если Константы.ИспользоватьРазделениеПоОбластямДанных.Получить() Тогда НовыеЗначения.Вставить("НеИспользоватьРазделениеПоОбластямДанных", Ложь); НовыеЗначения.Вставить("СтандартныеПодсистемыВАвтономномРежиме", Ложь); ИначеЕсли ОбщегоНазначения.ЭтоАвтономноеРабочееМесто() Тогда НовыеЗначения.Вставить("НеИспользоватьРазделениеПоОбластямДанных", Ложь); НовыеЗначения.Вставить("СтандартныеПодсистемыВАвтономномРежиме", Истина); Иначе НовыеЗначения.Вставить("НеИспользоватьРазделениеПоОбластямДанных", Истина); НовыеЗначения.Вставить("СтандартныеПодсистемыВАвтономномРежиме", Ложь); КонецЕсли; ЭтоОбменДаннымиВМоделиСервиса = ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаВМоделиСервиса.ОбменДаннымиВМоделиСервиса"); Для каждого НовоеЗначение Из НовыеЗначения Цикл Если ЭтоОбменДаннымиВМоделиСервиса И НовоеЗначение.Ключ = "СтандартныеПодсистемыВАвтономномРежиме" Тогда ПредыдущееЗначение = ОбщегоНазначения.ЭтоАвтономноеРабочееМесто(); // Всегда синхронизируем константу СтандартныеПодсистемыВАвтономномРежиме с ЭтоАвтономноеРабочееМесто Константы[НовоеЗначение.Ключ].Установить(НовоеЗначение.Значение); Иначе ПредыдущееЗначение = Константы[НовоеЗначение.Ключ].Получить(); КонецЕсли; Если ПредыдущееЗначение <> НовоеЗначение.Значение Тогда Если НЕ Параметры.МонопольныйРежим Тогда Параметры.МонопольныйРежим = Истина; Возврат; // Требуется изменение значения, поэтому монопольный режим. КонецЕсли; Константы[НовоеЗначение.Ключ].Установить(НовоеЗначение.Значение); Если ЭтоОбменДаннымиВМоделиСервиса И НовоеЗначение.Ключ = "СтандартныеПодсистемыВАвтономномРежиме" И ПредыдущееЗначение Тогда МодульАвтономнаяРабота = ОбщегоНазначения.ОбщийМодуль("АвтономнаяРабота"); МодульАвтономнаяРабота.ВыключитьСвойствоИБ(); КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры // Сбрасывает дату обновления всех записей кэша версий, таким // образом все записи кэша начинают считаться неактуальными. // Процедура ПометитьЗаписиКэшаВерсийНеактуальными() Экспорт НачатьТранзакцию(); Попытка НаборЗаписей = РегистрыСведений.КэшПрограммныхИнтерфейсов.СоздатьНаборЗаписей(); Блокировка = Новый БлокировкаДанных; Блокировка.Добавить("РегистрСведений.КэшПрограммныхИнтерфейсов"); Блокировка.Заблокировать(); НаборЗаписей.Прочитать(); Для каждого Запись Из НаборЗаписей Цикл Запись.ДатаОбновления = Неопределено; КонецЦикла; ОбновлениеИнформационнойБазы.ЗаписатьДанные(НаборЗаписей); ЗафиксироватьТранзакцию(); Исключение ОтменитьТранзакцию(); ВызватьИсключение; КонецПопытки; КонецПроцедуры // См. ОбщегоНазначенияПереопределяемый.ПриДобавленииПереименованийОбъектовМетаданных. Процедура ПриДобавленииПереименованийОбъектовМетаданных(Итог) Экспорт Библиотека = "СтандартныеПодсистемы"; СтароеИмя = "Роль.БазовыеПрава"; НовоеИмя = "Роль.БазовыеПраваБСП"; ОбщегоНазначения.ДобавитьПереименование(Итог, "3.0.1.19", СтароеИмя, НовоеИмя, Библиотека); СтароеИмя = "Роль.БазовыеПраваВнешнегоПользователя"; НовоеИмя = "Роль.БазовыеПраваВнешнихПользователейБСП"; ОбщегоНазначения.ДобавитьПереименование(Итог, "3.0.1.19", СтароеИмя, НовоеИмя, Библиотека); СтароеИмя = "Роль.РежимВсеФункции"; НовоеИмя = "Роль.РежимТехническогоСпециалиста"; ОбщегоНазначения.ДобавитьПереименование(Итог, "3.1.5.153", СтароеИмя, НовоеИмя, Библиотека); КонецПроцедуры //////////////////////////////////////////////////////////////////////////////// // Обработчики подписок на события. // Обработчик события ПередЗаписью предопределенных элементов. Процедура ЗапретитьПометкуУдаленияПредопределенныхЭлементовПередЗаписью(Источник, Отказ) Экспорт Если Источник.ОбменДанными.Загрузка Тогда Возврат; КонецЕсли; Если Источник.ПометкаУдаления <> Истина Тогда Возврат; КонецЕсли; // Для определения предопределенных в подсистемах Свойства и КонтактнаяИнформация // зачитываются другие реквизиты. Параметры = Новый Структура("ИмяПредопределенногоНабора, ИмяПредопределенногоВида", "", ""); ЗаполнитьЗначенияСвойств(Параметры, Источник); Если (Источник.ИмяПредопределенныхДанных = "" И Параметры.ИмяПредопределенногоНабора = "" И Параметры.ИмяПредопределенногоВида = "") Тогда Возврат; КонецЕсли; Если Источник.ЭтоНовый() Тогда ВызватьИсключение НСтр("ru = 'Недопустимо создавать предопределенный элемент, помеченный на удаление.'"); КонецЕсли; ИмяРеквизита = ""; Если Параметры.ИмяПредопределенногоНабора <> "" Тогда ИмяРеквизита = "ИмяПредопределенногоНабора"; ИначеЕсли Параметры.ИмяПредопределенногоВида <> "" Тогда ИмяРеквизита = "ИмяПредопределенногоВида"; КонецЕсли; СтарыеСвойства = ОбщегоНазначения.ЗначенияРеквизитовОбъекта( Источник.Ссылка, "ПометкаУдаления, ИмяПредопределенныхДанных" + ?(ИмяРеквизита <> "", ", " + ИмяРеквизита, "")); Если (СтарыеСвойства.ИмяПредопределенныхДанных <> "" Или ИмяРеквизита <> "" И СтарыеСвойства[ИмяРеквизита] <> "") И СтарыеСвойства.ПометкаУдаления <> Истина Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Недопустимо помечать на удаление предопределенный элемент: |""%1"".'"), Строка(Источник.Ссылка)); ИначеЕсли (ИмяРеквизита <> "" И Параметры[ИмяРеквизита] <> "" И СтарыеСвойства[ИмяРеквизита] = "" Или СтарыеСвойства.ИмяПредопределенныхДанных = "") И СтарыеСвойства.ПометкаУдаления = Истина Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Недопустимо связывать с именем предопределенного элемент, помеченный на удаление: |""%1"".'"), Строка(Источник.Ссылка)); КонецЕсли; КонецПроцедуры // Обработчик события ПередУдалением предопределенных элементов. Процедура ЗапретитьУдалениеПредопределенныхЭлементовПередУдалением(Источник, Отказ) Экспорт Если Источник.ОбменДанными.Загрузка Тогда Возврат; КонецЕсли; // Для определения предопределенных в подсистемах Свойства и КонтактнаяИнформация // зачитываются другие реквизиты. Параметры = Новый Структура("ИмяПредопределенногоНабора, ИмяПредопределенногоВида", "", ""); ЗаполнитьЗначенияСвойств(Параметры, Источник); Если Источник.ИмяПредопределенныхДанных = "" И Параметры.ИмяПредопределенногоНабора = "" И Параметры.ИмяПредопределенногоВида = "" Тогда Возврат; КонецЕсли; ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Недопустимо удалять предопределенный элемент |""%1"".'"), Строка(Источник.Ссылка)); КонецПроцедуры //////////////////////////////////////////////////////////////////////////////// // Обработка подписок на события планов обмена РИБ. // Процедура является обработчиком одноименного события, возникающего при обмене данными в распределенной // информационной базе. // См. описание параметров в обработчике события ПриОтправкеДанныхПодчиненному в синтакс-помощнике. // // Параметры: // Источник - ПланОбменаОбъект // ЭлементДанных - Произвольный // ОтправкаЭлемента - ОтправкаЭлементаДанных // СозданиеНачальногоОбраза - Булево // Процедура ПриОтправкеДанныхПодчиненномуСобытие(Источник, ЭлементДанных, ОтправкаЭлемента, СозданиеНачальногоОбраза) Экспорт ПриОтправкеДанныхПодчиненному(ЭлементДанных, ОтправкаЭлемента, СозданиеНачальногоОбраза, Источник); Если ОтправкаЭлемента <> ОтправкаЭлементаДанных.Игнорировать Тогда // Вызов переопределяемого обработчика для выполнения прикладной логики обмена РИБ. ОбщегоНазначенияПереопределяемый.ПриОтправкеДанныхПодчиненному(Источник, ЭлементДанных, ОтправкаЭлемента, СозданиеНачальногоОбраза); КонецЕсли; КонецПроцедуры // Процедура является обработчиком одноименного события, возникающего при обмене данными в распределенной // информационной базе. // См. описание параметров в обработчике события ПриОтправкеДанныхГлавному в синтакс-помощнике. // // Параметры: // Источник - ПланОбменаОбъект // ЭлементДанных - Произвольный // ОтправкаЭлемента - ОтправкаЭлементаДанных // Процедура ПриОтправкеДанныхГлавномуСобытие(Источник, ЭлементДанных, ОтправкаЭлемента) Экспорт ПриОтправкеДанныхГлавному(ЭлементДанных, ОтправкаЭлемента, Источник); Если ОтправкаЭлемента <> ОтправкаЭлементаДанных.Игнорировать Тогда // Вызов переопределяемого обработчика для выполнения прикладной логики обмена РИБ. ОбщегоНазначенияПереопределяемый.ПриОтправкеДанныхГлавному(Источник, ЭлементДанных, ОтправкаЭлемента); КонецЕсли; КонецПроцедуры // Процедура является обработчиком одноименного события, возникающего при обмене данными в распределенной // информационной базе. // См. описание параметров в обработчике события ПриПолученииДанныхОтПодчиненного в синтакс-помощнике. // // Параметры: // Источник - ПланОбменаОбъект // ЭлементДанных - Произвольный // ПолучениеЭлемента - ПолучениеЭлементаДанных // ОтправкаНазад - Булево // Процедура ПриПолученииДанныхОтПодчиненногоСобытие(Источник, ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад) Экспорт ПриПолученииДанныхОтПодчиненного(ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад, Источник); Если ПолучениеЭлемента <> ПолучениеЭлементаДанных.Игнорировать Тогда // Вызов переопределяемого обработчика для выполнения прикладной логики обмена РИБ. ОбщегоНазначенияПереопределяемый.ПриПолученииДанныхОтПодчиненного(Источник, ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад); КонецЕсли; КонецПроцедуры // Процедура является обработчиком одноименного события, возникающего при обмене данными в распределенной // информационной базе. // См. описание обработчика события ПриПолученииДанныхОтГлавного в синтакс-помощнике. // // Параметры: // Источник - ПланОбменаОбъект // ЭлементДанных - Произвольный // ПолучениеЭлемента - ПолучениеЭлементаДанных // ОтправкаНазад - Булево // Процедура ПриПолученииДанныхОтГлавногоСобытие(Источник, ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад) Экспорт ПриПолученииДанныхОтГлавного(ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад, Источник); Если ПолучениеЭлемента <> ПолучениеЭлементаДанных.Игнорировать Тогда // Вызов переопределяемого обработчика для выполнения прикладной логики обмена РИБ. ОбщегоНазначенияПереопределяемый.ПриПолученииДанныхОтГлавного(Источник, ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад); КонецЕсли; КонецПроцедуры // Процедура-обработчик подписки на событие ПередЗаписью для ПланОбменаОбъект. // Используется для вызова обработчика события ПослеПолученияДанных при обмене в распределенной ИБ. // // Параметры: // Источник - ПланОбменаОбъект // Отказ - Булево // Процедура ПослеПолученияДанных(Источник, Отказ) Экспорт Если Источник.ОбменДанными.Загрузка Тогда Возврат; КонецЕсли; Если Не Источник.Метаданные().РаспределеннаяИнформационнаяБаза Тогда Возврат; КонецЕсли; Если Источник.ЭтоНовый() Или Источник.НомерПринятого = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Источник.Ссылка, "НомерПринятого") Тогда Возврат; КонецЕсли; ПолучениеИзГлавногоУзла = (ПланыОбмена.ГлавныйУзел() = Источник.Ссылка); ИнтеграцияПодсистемБСП.ПослеПолученияДанных(Источник, Отказ, ПолучениеИзГлавногоУзла); КонецПроцедуры //////////////////////////////////////////////////////////////////////////////// // ВСПОМОГАТЕЛЬНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ // Возвращаемое значение: // Массив из ОбъектМетаданных // Функция ОбъектыМетаданныхВсехПредопределенныхДанных() РазделениеВключено = ОбщегоНазначения.РазделениеВключено(); ЭтоРазделенныйСеанс = ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных(); КоллекцииМетаданных = Новый Массив; КоллекцииМетаданных.Добавить(Метаданные.Справочники); КоллекцииМетаданных.Добавить(Метаданные.ПланыВидовХарактеристик); КоллекцииМетаданных.Добавить(Метаданные.ПланыСчетов); КоллекцииМетаданных.Добавить(Метаданные.ПланыВидовРасчета); ОбъектыМетаданных = Новый Массив; Для Каждого Коллекция Из КоллекцииМетаданных Цикл Для Каждого ОбъектМетаданных Из Коллекция Цикл Если РазделениеВключено Тогда МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса"); ЭтоРазделенныйОбъектМетаданных = МодульРаботаВМоделиСервиса.ЭтоРазделенныйОбъектМетаданных(ОбъектМетаданных); Если ( ЭтоРазделенныйСеанс И Не ЭтоРазделенныйОбъектМетаданных) Или (Не ЭтоРазделенныйСеанс И ЭтоРазделенныйОбъектМетаданных) Тогда Продолжить; КонецЕсли; КонецЕсли; ОбъектыМетаданных.Добавить(ОбъектМетаданных); КонецЦикла; КонецЦикла; Возврат ОбъектыМетаданных; КонецФункции Процедура УстановитьИнициализациюВсехПредопределенныхДанных(ОбъектыМетаданных) РазделениеВключено = ОбщегоНазначения.РазделениеВключено(); ЭтоРазделенныйСеанс = ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных(); Для Каждого ОбъектМетаданных Из ОбъектыМетаданных Цикл Менеджер = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ОбъектМетаданных.ПолноеИмя()); Менеджер.УстановитьИнициализациюПредопределенныхДанных(Истина); КонецЦикла; Если Не РазделениеВключено Или Не ЭтоРазделенныйСеанс Тогда УстановитьОбновлениеПредопределенныхДанныхИнформационнойБазы(ОбновлениеПредопределенныхДанных.Авто); КонецЕсли; КонецПроцедуры Процедура СоздатьНедостающиеПредопределенныеДанные(ОбъектыМетаданных) Запрос = Новый Запрос; ТекстЗапроса = "ВЫБРАТЬ | ПсевдонимЗаданнойТаблицы.Ссылка КАК Ссылка, | ПсевдонимЗаданнойТаблицы.ВерсияДанных КАК ВерсияДанных, | ЕСТЬNULL(ПсевдонимЗаданнойТаблицы.Родитель.ИмяПредопределенныхДанных, """") КАК ИмяРодителя, | ПсевдонимЗаданнойТаблицы.ИмяПредопределенныхДанных КАК Имя |ИЗ | &ТекущаяТаблица КАК ПсевдонимЗаданнойТаблицы |ГДЕ | ПсевдонимЗаданнойТаблицы.Предопределенный"; ОписанияСохраненных = Новый Массив; ТаблицыБезСохраненных = Новый Массив; Для Каждого ОбъектМетаданных Из ОбъектыМетаданных Цикл Если ОбъектМетаданных.ОбновлениеПредопределенныхДанных = Метаданные.СвойстваОбъектов.ОбновлениеПредопределенныхДанных.НеОбновлятьАвтоматически Тогда Продолжить; КонецЕсли; ПолноеИмя = ОбъектМетаданных.ПолноеИмя(); Запрос.Текст = СтрЗаменить(ТекстЗапроса, "&ТекущаяТаблица", ПолноеИмя); Если Метаданные.ПланыСчетов.Содержит(ОбъектМетаданных) Или Метаданные.ПланыВидовРасчета.Содержит(ОбъектМетаданных) Или Не ОбъектМетаданных.Иерархический Тогда Запрос.Текст = СтрЗаменить(Запрос.Текст, "ЕСТЬNULL(ПсевдонимЗаданнойТаблицы.Родитель.ИмяПредопределенныхДанных, """")", """"""); КонецЕсли; // АПК:1328-выкл - №648.1.1 В вызывающей процедуре установлена исключительная блокировка. ТаблицаИмен = Запрос.Выполнить().Выгрузить(); // АПК:1328-вкл. ТаблицаИмен.Индексы.Добавить("Имя"); Имена = ОбъектМетаданных.ПолучитьИменаПредопределенных(); СохранитьСуществующиеПредопределенныеОбъектыПередСозданиемНедостающих(ОбъектМетаданных, ПолноеИмя, ТаблицаИмен, Имена, Запрос, ОписанияСохраненных, ТаблицыБезСохраненных); КонецЦикла; // Восстановление предопределенных элементов, существовавших до инициализации. Для Каждого ОписаниеСохраненных Из ОписанияСохраненных Цикл Менеджер = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ОписаниеСохраненных.ПолноеИмя); Менеджер.УстановитьИнициализациюПредопределенныхДанных(Ложь); ИнициализироватьПредопределенныеДанные(); Запрос.Текст = ОписаниеСохраненных.ТекстЗапроса; // АПК:1328-выкл - №648.1.1 В вызывающей процедуре установлена исключительная блокировка. ТаблицаИмен = Запрос.Выполнить().Выгрузить(); // АПК:1328-вкл. ТаблицаИмен.Индексы.Добавить("Имя"); Для Каждого ОписаниеСохраненного Из ОписаниеСохраненных.ТаблицаИмен Цикл Если Не ОписаниеСохраненного.ОбъектСуществует Тогда Продолжить; КонецЕсли; Строка = ТаблицаИмен.Найти(ОписаниеСохраненного.Имя, "Имя"); Если Строка <> Неопределено Тогда НовыйОбъект = Строка.Ссылка.ПолучитьОбъект(); Если ОписаниеСохраненных.ЭтоПланСчетов Тогда Если ОписаниеСохраненного.Объект.ВерсияДанных <> Строка.ВерсияДанных Тогда ОбновитьОбъектСчета(ОписаниеСохраненного.Объект); КонецЕсли; ДополнитьНовыеВидыСубконтоСчета(ОписаниеСохраненного.Объект, НовыйОбъект); КонецЕсли; // АПК:1327-выкл - №648.1.1 В вызывающей процедуре установлена исключительная блокировка. ОбновлениеИнформационнойБазы.УдалитьДанные(НовыйОбъект); // АПК:1327-вкл. Строка.Имя = ""; КонецЕсли; // АПК:1327-выкл - №648.1.1 В вызывающей процедуре установлена исключительная блокировка. ОбновлениеИнформационнойБазы.ЗаписатьДанные(ОписаниеСохраненного.Объект); // АПК:1327-вкл. КонецЦикла; Для Каждого Строка Из ТаблицаИмен Цикл Если Не ЗначениеЗаполнено(Строка.Имя) Или Не ЗначениеЗаполнено(Строка.ИмяРодителя) Тогда Продолжить; КонецЕсли; СтрокаРодителя = ОписаниеСохраненных.ТаблицаИмен.Найти(Строка.ИмяРодителя, "Имя"); // СправочникСсылка, ПланВидовХарактеристикСсылка, ПланСчетовСсылка, ПланВидовРасчетаСсылка Если СтрокаРодителя <> Неопределено Тогда НовыйОбъект = Строка.Ссылка.ПолучитьОбъект(); НовыйОбъект.Родитель = СтрокаРодителя.Ссылка; // АПК:1327-выкл - №648.1.1 В вызывающей процедуре установлена исключительная блокировка. ОбновлениеИнформационнойБазы.ЗаписатьДанные(НовыйОбъект); // АПК:1327-вкл. КонецЕсли; КонецЦикла; КонецЦикла; Для Каждого ПолноеИмя Из ТаблицыБезСохраненных Цикл Менеджер = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмя); Менеджер.УстановитьИнициализациюПредопределенныхДанных(Ложь); КонецЦикла; ИнициализироватьПредопределенныеДанные(); КонецПроцедуры // Параметры: // СтарыйОбъект - ПланСчетовОбъект // Процедура ОбновитьОбъектСчета(СтарыйОбъект) НовыйОбъект = СтарыйОбъект.Ссылка.ПолучитьОбъект(); НовыйОбъект.ИмяПредопределенныхДанных = СтарыйОбъект.ИмяПредопределенныхДанных; Для Каждого СтрокаВидаСубконто Из СтарыйОбъект.ВидыСубконто Цикл Если СтрокаВидаСубконто.Предопределенное Тогда НоваяСтрокаВидаСубконто = НовыйОбъект.ВидыСубконто.Найти( СтрокаВидаСубконто.ВидСубконто, "ВидСубконто"); Если НоваяСтрокаВидаСубконто <> Неопределено Тогда НоваяСтрокаВидаСубконто.Предопределенное = Истина; КонецЕсли; КонецЕсли; КонецЦикла; СтарыйОбъект = НовыйОбъект; КонецПроцедуры // Параметры: // Счет - ПланСчетовОбъект // ОбразецСчета - ПланСчетовОбъект // Процедура ДополнитьНовыеВидыСубконтоСчета(Счет, ОбразецСчета) Для Каждого Строка Из ОбразецСчета.ВидыСубконто Цикл Индекс = ОбразецСчета.ВидыСубконто.Индекс(Строка); Если Счет.ВидыСубконто.Количество() > Индекс Тогда Если Счет.ВидыСубконто[Индекс].ВидСубконто <> Строка.ВидСубконто Тогда ЗаписьЖурналаРегистрации( НСтр("ru = 'Обмен данными.Отключение связи с главным узлом'", ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка, Счет.Метаданные(), Счет, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'У счета ""%1"" субконто №%2 ""%3"" не совпадает с предопределенным субконто ""%4"".'"), Строка(Счет), Индекс + 1, Строка(Счет.ВидыСубконто[Индекс].ВидСубконто), Строка(Строка.ВидСубконто)), РежимТранзакцииЗаписиЖурналаРегистрации.Транзакционная); ИначеЕсли Не Счет.ВидыСубконто[Индекс].Предопределенное Тогда Счет.ВидыСубконто[Индекс].Предопределенное = Истина; КонецЕсли; Иначе ЗаполнитьЗначенияСвойств(Счет.ВидыСубконто.Добавить(), Строка); КонецЕсли; КонецЦикла; КонецПроцедуры Процедура СохранитьСуществующиеПредопределенныеОбъектыПередСозданиемНедостающих( ОбъектМетаданных, ПолноеИмя, ТаблицаИмен, Имена, Запрос, ОписанияСохраненных, ТаблицыБезСохраненных) ТребуетсяИнициализация = Ложь; ПредопределенныеСуществуют = Ложь; ТаблицаИмен.Колонки.Добавить("ОбъектСуществует", Новый ОписаниеТипов("Булево")); Для Каждого Имя Из Имена Цикл Строки = ТаблицаИмен.НайтиСтроки(Новый Структура("Имя", Имя)); Если Строки.Количество() = 0 Тогда ТребуетсяИнициализация = Истина; Иначе Для Каждого Строка Из Строки Цикл Строка.ОбъектСуществует = Истина; КонецЦикла; ПредопределенныеСуществуют = Истина; КонецЕсли; КонецЦикла; Если Не ТребуетсяИнициализация Тогда Возврат; КонецЕсли; Если ПредопределенныеСуществуют Тогда ЭтоПланСчетов = Метаданные.ПланыСчетов.Содержит(ОбъектМетаданных); ОписаниеСохраненных = Новый Структура; ОписаниеСохраненных.Вставить("ПолноеИмя", ПолноеИмя); ОписаниеСохраненных.Вставить("ТекстЗапроса", Запрос.Текст); ОписаниеСохраненных.Вставить("ТаблицаИмен", ТаблицаИмен); ОписаниеСохраненных.Вставить("ЭтоПланСчетов", ЭтоПланСчетов); ОписанияСохраненных.Добавить(ОписаниеСохраненных); ТаблицаИмен.Колонки.Добавить("Объект"); Для Каждого Строка Из ТаблицаИмен Цикл Объект = Строка.Ссылка.ПолучитьОбъект(); Объект.ИмяПредопределенныхДанных = ""; Если ЭтоПланСчетов Тогда СтрокиПредопределенныхВидовСубконто = Новый Массив; Для Каждого СтрокаВидаСубконто Из Объект.ВидыСубконто Цикл Если СтрокаВидаСубконто.Предопределенное Тогда СтрокаВидаСубконто.Предопределенное = Ложь; СтрокиПредопределенныхВидовСубконто.Добавить(СтрокаВидаСубконто); КонецЕсли; КонецЦикла; КонецЕсли; // АПК:1327-выкл - №648.1.1 В вызывающей процедуре установлена исключительная блокировка. ОбновлениеИнформационнойБазы.ЗаписатьДанные(Объект); // АПК:1327-вкл. Если ЭтоПланСчетов Тогда Для Каждого СтрокаВидаСубконто Из СтрокиПредопределенныхВидовСубконто Цикл СтрокаВидаСубконто.Предопределенное = Истина; КонецЦикла; КонецЕсли; Если Строка.ОбъектСуществует Тогда Объект.ИмяПредопределенныхДанных = Строка.Имя; КонецЕсли; Строка.Объект = Объект; КонецЦикла; Иначе ТаблицыБезСохраненных.Добавить(ПолноеИмя); КонецЕсли; КонецПроцедуры //////////////////////////////////////////////////////////////////////////////// // ВСПОМОГАТЕЛЬНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ Процедура ПередЗапускомПрограммы() // Привилегированный режим (установлен платформой). Если ТекущийРежимЗапуска() = Неопределено И ДлительныеОперации.ЭтоЗапускБезВызоваПередЗапускомПрограммы() Тогда Возврат; КонецЕсли; // Проверка основного языка программирования, установленного в конфигурации. ТекущийЯзыкВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка["Русский"]; Если Метаданные.ВариантВстроенногоЯзыка <> ТекущийЯзыкВстроенногоЯзыка Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Вариант встроенного языка конфигурации ""%1"" не поддерживается. |Используйте вариант языка ""%2"".'"), Метаданные.ВариантВстроенногоЯзыка, Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка["Русский"]); КонецЕсли; // Проверка настройки совместимости конфигурации с версией платформы. СистемнаяИнформация = Новый СистемнаяИнформация; МинимальнаяВерсияПлатформы = "8.3.17.1851"; Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(СистемнаяИнформация.ВерсияПриложения, МинимальнаяВерсияПлатформы) < 0 Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Для запуска необходима версия платформы 1С:Предприятие %1 или выше.'"), МинимальнаяВерсияПлатформы); КонецЕсли; Режимы = Метаданные.СвойстваОбъектов.РежимСовместимости; ТекущийРежим = Метаданные.РежимСовместимости; ПоддерживаемаяВерсияПлатформы = "8.3.16"; ВерсияПлатформы = ОбщегоНазначенияКлиентСервер.ВерсияКонфигурацииБезНомераСборки(СистемнаяИнформация.ВерсияПриложения); Если ТекущийРежим = Режимы.НеИспользовать Тогда ПоддерживаемыеВерсииПлатформы = СтрРазделить("8.3.14, 8.3.15, 8.3.16, 8.3.17", ", ", Ложь); Если ПоддерживаемыеВерсииПлатформы.Найти(ВерсияПлатформы) <> Неопределено Тогда НеПоддерживаемаяВерсияПлатформы = ""; Иначе НеПоддерживаемаяВерсияПлатформы = ВерсияПлатформы; КонецЕсли; ИначеЕсли ТекущийРежим = Режимы.Версия8_1 Тогда НеПоддерживаемаяВерсияПлатформы = "8.1" ИначеЕсли ТекущийРежим = Режимы.Версия8_2_13 Тогда НеПоддерживаемаяВерсияПлатформы = "8.2.13" ИначеЕсли ТекущийРежим = Режимы.Версия8_2_16 Тогда НеПоддерживаемаяВерсияПлатформы = "8.2.16"; ИначеЕсли ТекущийРежим = Режимы.Версия8_3_1 Тогда НеПоддерживаемаяВерсияПлатформы = "8.3.1"; ИначеЕсли ТекущийРежим = Режимы.Версия8_3_2 Тогда НеПоддерживаемаяВерсияПлатформы = "8.3.2"; ИначеЕсли ТекущийРежим = Режимы.Версия8_3_3 Тогда НеПоддерживаемаяВерсияПлатформы = "8.3.3"; ИначеЕсли ТекущийРежим = Режимы.Версия8_3_4 Тогда НеПоддерживаемаяВерсияПлатформы = "8.3.4"; ИначеЕсли ТекущийРежим = Режимы.Версия8_3_5 Тогда НеПоддерживаемаяВерсияПлатформы = "8.3.5"; ИначеЕсли ТекущийРежим = Режимы.Версия8_3_6 Тогда НеПоддерживаемаяВерсияПлатформы = "8.3.6"; ИначеЕсли ТекущийРежим = Режимы.Версия8_3_7 Тогда НеПоддерживаемаяВерсияПлатформы = "8.3.7"; ИначеЕсли ТекущийРежим = Режимы.Версия8_3_8 Тогда НеПоддерживаемаяВерсияПлатформы = "8.3.8"; ИначеЕсли ТекущийРежим = Режимы.Версия8_3_9 Тогда НеПоддерживаемаяВерсияПлатформы = "8.3.9"; ИначеЕсли ТекущийРежим = Режимы.Версия8_3_10 Тогда НеПоддерживаемаяВерсияПлатформы = "8.3.10"; ИначеЕсли ТекущийРежим = Режимы.Версия8_3_11 Тогда НеПоддерживаемаяВерсияПлатформы = "8.3.11"; ИначеЕсли ТекущийРежим = Режимы.Версия8_3_12 Тогда НеПоддерживаемаяВерсияПлатформы = "8.3.12"; ИначеЕсли ТекущийРежим = Режимы.Версия8_3_13 Тогда НеПоддерживаемаяВерсияПлатформы = "8.3.13"; Иначе ТекущийРежимСтрокой = Строка(ТекущийРежим); Если СтрЗаканчиваетсяНа(ТекущийРежимСтрокой, "8_3_14") Или СтрЗаканчиваетсяНа(ТекущийРежимСтрокой, "8_3_15") Или СтрЗаканчиваетсяНа(ТекущийРежимСтрокой, "8_3_16") Или СтрЗаканчиваетсяНа(ТекущийРежимСтрокой, "8_3_17") Тогда НеПоддерживаемаяВерсияПлатформы = ""; Иначе НеПоддерживаемаяВерсияПлатформы = ТекущийРежимСтрокой; КонецЕсли; КонецЕсли; Если ЗначениеЗаполнено(НеПоддерживаемаяВерсияПлатформы) Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Режим совместимости конфигурации с 1С:Предприятием версии %1 не поддерживается. |Для запуска установите в конфигурации режим совместимости ""Не использовать"" при разработке на версии %2 |(или ""Версия %2"" при разработке на более старших версиях).'"), НеПоддерживаемаяВерсияПлатформы, ПоддерживаемаяВерсияПлатформы); КонецЕсли; // Проверка заполнения версии конфигурации. Если ПустаяСтрока(Метаданные.Версия) Тогда ВызватьИсключение НСтр("ru = 'Не заполнено свойство конфигурации Версия.'"); Иначе Попытка НулеваяВерсия = ОбщегоНазначенияКлиентСервер.СравнитьВерсии(Метаданные.Версия, "0.0.0.0") = 0; Исключение ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не правильно заполнено свойство конфигурации Версия: ""%1"". |Правильный формат, например: ""1.2.3.45"".'"), Метаданные.Версия); КонецПопытки; Если НулеваяВерсия Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не правильно заполнено свойство конфигурации Версия: ""%1"". |Версия не может быть нулевой.'"), Метаданные.Версия); КонецЕсли; КонецЕсли; ТекущийПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь(); Если Не ТекущийПользовательИБ.АутентификацияСтандартная И Не ТекущийПользовательИБ.АутентификацияОС И Не ТекущийПользовательИБ.АутентификацияOpenID Тогда ВызватьИсключение НСтр("ru = 'Вход в программу запрещен. Обратитесь к администратору.'"); КонецЕсли; Если Не Метаданные.ОсновныеРоли.Содержит(Метаданные.Роли.АдминистраторСистемы) Или Не Метаданные.ОсновныеРоли.Содержит(Метаданные.Роли.ПолныеПрава) Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'В конфигурации в свойстве %1 не указаны стандартные роли %2 и %3.'"), "ОсновныеРоли", Метаданные.Роли.АдминистраторСистемы.Имя, Метаданные.Роли.ПолныеПрава.Имя); КонецЕсли; // Проверка возможности выполнения обработчиков установки параметров сеанса для запуска программы. ПроверитьВозможностьЗапуска(); Если Не ЗначениеЗаполнено(ПользователиИнформационнойБазы.ТекущийПользователь().Имя) И (Не ОбщегоНазначения.РазделениеВключено() Или Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных()) И ОбновлениеИнформационнойБазыСлужебный.ВерсияИБ("СтандартныеПодсистемы", ОбщегоНазначения.РазделениеВключено()) = "0.0.0.0" Тогда ПользователиСлужебный.УстановитьНачальныеНастройки(""); КонецЕсли; ИнтеграцияПодсистемБСП.ПередЗапускомПрограммы(); ОбщегоНазначенияПереопределяемый.ПередЗапускомПрограммы(); СкорректироватьНачальнуюСтраницуНеразделенногоПользователя(); ОбработатьОчередьСкопированныхНастроек(); КонецПроцедуры // Для процедуры ПередЗапускомПрограммы. Процедура СкорректироватьНачальнуюСтраницуНеразделенногоПользователя() Если ТекущийРежимЗапуска() = Неопределено Или Не ОбщегоНазначения.РазделениеВключено() Тогда Возврат; КонецЕсли; Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса"); СеансЗапущенБезРазделителей = МодульРаботаВМоделиСервиса.СеансЗапущенБезРазделителей(); Иначе СеансЗапущенБезРазделителей = Ложь; КонецЕсли; Если Не СеансЗапущенБезРазделителей Тогда Возврат; КонецЕсли; КлючОбъекта = "БазоваяФункциональность"; КлючНастроек = "СоставФормНачальнойСтраницыВМетаданных"; ПредыдущийСоставФормВМетаданных = ХранилищеОбщихНастроек.Загрузить(КлючОбъекта, КлючНастроек); Если ПредыдущийСоставФормВМетаданных = Неопределено Тогда // Очистка начальной страницы при первом входе. УстановитьПустуюФормуНаРабочийСтол(); Иначе УстановитьПустуюФормуНаПустойРабочийСтол(); КонецЕсли; // Компенсация изменения состава форм в метаданных начальной страницы. НовыеНастройки = Новый НастройкиНачальнойСтраницы; СоставФормВМетаданных = НовыеНастройки.ПолучитьСоставФорм(); Если ТипЗнч(ПредыдущийСоставФормВМетаданных) <> Тип("Структура") Или Не ПредыдущийСоставФормВМетаданных.Свойство("ЛеваяКолонка") Или ТипЗнч(ПредыдущийСоставФормВМетаданных.ЛеваяКолонка) <> Тип("Массив") Или Не ПредыдущийСоставФормВМетаданных.Свойство("ПраваяКолонка") Или ТипЗнч(ПредыдущийСоставФормВМетаданных.ПраваяКолонка) <> Тип("Массив") Тогда ПредыдущийСоставФормВМетаданных = Новый СоставФормНачальнойСтраницы; ИначеЕсли СоставФормСовпадает(ПредыдущийСоставФормВМетаданных.ЛеваяКолонка, СоставФормВМетаданных.ЛеваяКолонка) И СоставФормСовпадает(ПредыдущийСоставФормВМетаданных.ПраваяКолонка, СоставФормВМетаданных.ПраваяКолонка) Тогда // Состав форм в метаданных начальной страницы не изменился. Возврат; КонецЕсли; КомпенсироватьИзмененияСоставаФормВМетаданныхНачальнойСтраницы(ПредыдущийСоставФормВМетаданных); СохраняемыйСоставФормВМетаданных = Новый Структура("ЛеваяКолонка, ПраваяКолонка"); ЗаполнитьЗначенияСвойств(СохраняемыйСоставФормВМетаданных, СоставФормВМетаданных); ХранилищеОбщихНастроек.Сохранить(КлючОбъекта, КлючНастроек, СохраняемыйСоставФормВМетаданных); КонецПроцедуры // Для процедуры СкорректироватьНачальнуюСтраницуНеразделенногоПользователя. Функция СоставФормСовпадает(ПредыдущиеФормыВМетаданных, ФормыВМетаданных) Если ПредыдущиеФормыВМетаданных.Количество() <> ФормыВМетаданных.Количество() Тогда Возврат Ложь; КонецЕсли; Для Каждого ИмяФормы Из ФормыВМетаданных Цикл Если ПредыдущиеФормыВМетаданных.Найти(ИмяФормы) = Неопределено Тогда Возврат Ложь; КонецЕсли; КонецЦикла; Возврат Истина; КонецФункции // Для процедуры СкорректироватьНачальнуюСтраницуНеразделенногоПользователя. Процедура КомпенсироватьИзмененияСоставаФормВМетаданныхНачальнойСтраницы(ПредыдущийСоставФормВМетаданных) // При компенсации учитывается, что настройки начальной страницы могут // быть сохранены в рамках процедуры скрытия рабочего стола. КлючОбъекта = "Общее/НастройкиНачальнойСтраницы"; КлючОбъектаХранения = "Общее/НастройкиНачальнойСтраницыПередОчисткой"; СохраненныеНастройки = ХранилищеСистемныхНастроек.Загрузить(КлючОбъектаХранения, ""); НастройкиСохранены = ТипЗнч(СохраненныеНастройки) = Тип("ХранилищеЗначения"); Если НастройкиСохранены Тогда ТекущиеНастройки = СохраненныеНастройки.Получить(); Иначе ТекущиеНастройки = ХранилищеСистемныхНастроек.Загрузить(КлючОбъекта); КонецЕсли; Если ТипЗнч(ТекущиеНастройки) = Тип("НастройкиНачальнойСтраницы") Тогда СоставФорм = ТекущиеНастройки.ПолучитьСоставФорм(); Иначе СоставФорм = Новый СоставФормНачальнойСтраницы; КонецЕсли; НовыеНастройки = Новый НастройкиНачальнойСтраницы; СоставФормВМетаданных = НовыеНастройки.ПолучитьСоставФорм(); УдалитьНовыеФормыНачальнойСтраницы(СоставФорм.ЛеваяКолонка, ПредыдущийСоставФормВМетаданных.ЛеваяКолонка, СоставФормВМетаданных.ЛеваяКолонка); УдалитьНовыеФормыНачальнойСтраницы(СоставФорм.ПраваяКолонка, ПредыдущийСоставФормВМетаданных.ПраваяКолонка, СоставФормВМетаданных.ПраваяКолонка); ТекущиеНастройки = Новый НастройкиНачальнойСтраницы; ТекущиеНастройки.УстановитьСоставФорм(СоставФорм); Если НастройкиСохранены Тогда СохраняемыеНастройки = Новый ХранилищеЗначения(ТекущиеНастройки); ХранилищеСистемныхНастроек.Сохранить(КлючОбъектаХранения, "", СохраняемыеНастройки); УстановитьПустуюФормуНаРабочийСтол(); Иначе ХранилищеСистемныхНастроек.Сохранить(КлючОбъекта, "", ТекущиеНастройки); КонецЕсли; КонецПроцедуры // Для процедуры КомпенсироватьИзмененияСоставаФормВМетаданныхНачальнойСтраницы. Процедура УдалитьНовыеФормыНачальнойСтраницы(ТекущиеФормы, ПредыдущиеФормыВМетаданных, ФормыВМетаданных) Для Каждого ИмяФормы Из ФормыВМетаданных Цикл Если ПредыдущиеФормыВМетаданных.Найти(ИмяФормы) <> Неопределено Тогда Продолжить; КонецЕсли; Индекс = ТекущиеФормы.Найти(ИмяФормы); Если Индекс <> Неопределено Тогда ТекущиеФормы.Удалить(Индекс); КонецЕсли; КонецЦикла; КонецПроцедуры Процедура ОбработатьОчередьСкопированныхНастроек() Если ТекущийРежимЗапуска() = Неопределено Тогда Возврат; КонецЕсли; ОчередьНастроек = ХранилищеОбщихНастроек.Загрузить("ОчередьНастроек", "НеПримененныеНастройки"); Если ТипЗнч(ОчередьНастроек) <> Тип("ХранилищеЗначения") Тогда Возврат; КонецЕсли; ОчередьНастроек = ОчередьНастроек.Получить(); Если ТипЗнч(ОчередьНастроек) <> Тип("Соответствие") Тогда Возврат; КонецЕсли; Для Каждого ЭлементОчереди Из ОчередьНастроек Цикл Попытка Настройка = ХранилищеСистемныхНастроек.Загрузить(ЭлементОчереди.Ключ, ЭлементОчереди.Значение); Исключение Продолжить; КонецПопытки; ХранилищеСистемныхНастроек.Сохранить(ЭлементОчереди.Ключ, ЭлементОчереди.Значение, Настройка); КонецЦикла; ХранилищеОбщихНастроек.Сохранить("ОчередьНастроек", "НеПримененныеНастройки", Неопределено); КонецПроцедуры Процедура ВыполнитьОбработчикиУстановкиПараметровСеанса(ИменаПараметровСеанса, Обработчики, УстановленныеПараметры) // Массив с ключами параметров сеанса // задаются начальным словом в имени параметра сеанса и символом "*". ПараметрыСеансаКлючи = Новый Массив; Для Каждого Запись Из Обработчики Цикл Если СтрНайти(Запись.Ключ, "*") > 0 Тогда КлючПараметра = СокрЛП(Запись.Ключ); ПараметрыСеансаКлючи.Добавить(Лев(КлючПараметра, СтрДлина(КлючПараметра)-1)); КонецЕсли; КонецЦикла; Для каждого ИмяПараметра Из ИменаПараметровСеанса Цикл Если УстановленныеПараметры.Найти(ИмяПараметра) <> Неопределено Тогда Продолжить; КонецЕсли; Обработчик = Обработчики.Получить(ИмяПараметра); Если Обработчик <> Неопределено Тогда ПараметрыОбработчика = Новый Массив(); ПараметрыОбработчика.Добавить(ИмяПараметра); ПараметрыОбработчика.Добавить(УстановленныеПараметры); ОбщегоНазначения.ВыполнитьМетодКонфигурации(Обработчик, ПараметрыОбработчика); Продолжить; КонецЕсли; Для Каждого ИмяКлючаПараметра Из ПараметрыСеансаКлючи Цикл Если СтрНачинаетсяС(ИмяПараметра, ИмяКлючаПараметра) Тогда Обработчик = Обработчики.Получить(ИмяКлючаПараметра + "*"); ПараметрыОбработчика = Новый Массив(); ПараметрыОбработчика.Добавить(ИмяПараметра); ПараметрыОбработчика.Добавить(УстановленныеПараметры); ОбщегоНазначения.ВыполнитьМетодКонфигурации(Обработчик, ПараметрыОбработчика); КонецЕсли; КонецЦикла; КонецЦикла; КонецПроцедуры Процедура ИгнорироватьОтправкуИдентификаторовОбъектовМетаданных(ЭлементДанных, ОтправкаЭлемента, Знач СозданиеНачальногоОбраза = Ложь) Если Не СозданиеНачальногоОбраза И ОбъектМетаданных(ЭлементДанных) = Метаданные.Справочники.ИдентификаторыОбъектовМетаданных Тогда ОтправкаЭлемента = ОтправкаЭлементаДанных.Игнорировать; КонецЕсли; КонецПроцедуры Процедура ИгнорироватьПолучениеИдентификаторовОбъектовМетаданных(ЭлементДанных, ПолучениеЭлемента) Если ОбъектМетаданных(ЭлементДанных) = Метаданные.Справочники.ИдентификаторыОбъектовМетаданных Тогда ПолучениеЭлемента = ПолучениеЭлементаДанных.Игнорировать; КонецЕсли; КонецПроцедуры Функция ОбъектМетаданных(Знач ЭлементДанных) Возврат ?(ТипЗнч(ЭлементДанных) = Тип("УдалениеОбъекта"), ЭлементДанных.Ссылка.Метаданные(), ЭлементДанных.Метаданные()); КонецФункции Функция СозданиеНачальногоОбраза(Знач ЭлементДанных) Возврат ?(ТипЗнч(ЭлементДанных) = Тип("УдалениеОбъекта"), Ложь, ЭлементДанных.ДополнительныеСвойства.Свойство("СозданиеНачальногоОбраза")); КонецФункции Функция ПоказатьНерекомендуемуюВерсиюПлатформы(Параметры) Если Параметры.РазделениеВключено Тогда Возврат Ложь; КонецЕсли; // Проверка, что пользователь не внешний. УстановитьПривилегированныйРежим(Истина); Запрос = Новый Запрос; Запрос.УстановитьПараметр("ИдентификаторПользователяИБ", ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор); Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 | ИСТИНА КАК ЗначениеИстина |ИЗ | Справочник.ВнешниеПользователи КАК ВнешниеПользователи |ГДЕ | ВнешниеПользователи.ИдентификаторПользователяИБ = &ИдентификаторПользователяИБ"; Если НЕ Запрос.Выполнить().Пустой() Тогда Возврат Ложь; КонецЕсли; СистемнаяИнформация = Новый СистемнаяИнформация; Текущая = СистемнаяИнформация.ВерсияПриложения; Минимальная = Параметры.МинимальнаяВерсияПлатформы; Рекомендуемая = Параметры.РекомендуемаяВерсияПлатформы; Возврат ОбщегоНазначенияКлиентСервер.СравнитьВерсии(Текущая, Минимальная) < 0 Или ОбщегоНазначенияКлиентСервер.СравнитьВерсии(Текущая, Рекомендуемая) < 0; КонецФункции Функция ПараметрыАдминистрированияПоУмолчанию() ПараметрыАдминистрированияКластера = АдминистрированиеКластера.ПараметрыАдминистрированияКластера(); ПараметрыАдминистрированияИБ = АдминистрированиеКластера.ПараметрыАдминистрированияИнформационнойБазыКластера(); // Объединяем структуры параметров. СтруктураПараметровАдминистрирования = ПараметрыАдминистрированияКластера; Для Каждого Элемент Из ПараметрыАдминистрированияИБ Цикл СтруктураПараметровАдминистрирования.Вставить(Элемент.Ключ, Элемент.Значение); КонецЦикла; СтруктураПараметровАдминистрирования.Вставить("ПринятоРешениеПоОткрытиюВнешнихОтчетовИОбработок", Ложь); Возврат СтруктураПараметровАдминистрирования; КонецФункции Процедура ПрочитатьПараметрыИзСтрокиСоединения(СтруктураПараметровАдминистрирования) ПодстрокиСтрокиСоединения = СтрРазделить(СтрокаСоединенияИнформационнойБазы(), ";"); СтрокаИмениСервера = СтроковыеФункцииКлиентСервер.СократитьДвойныеКавычки(Сред(ПодстрокиСтрокиСоединения[0], 7)); СтруктураПараметровАдминистрирования.ИмяВКластере = СтроковыеФункцииКлиентСервер.СократитьДвойныеКавычки(Сред(ПодстрокиСтрокиСоединения[1], 6)); СписокСерверовКластера = СтрРазделить(СтрокаИмениСервера, ","); Если СписокСерверовКластера.Количество() = 1 Тогда СписокСерверовКластера = СтрРазделить(СтрокаИмениСервера, ";"); КонецЕсли; ИмяСервера = СписокСерверовКластера[0]; // Протокол может быть только tcp. Можно отбросить. Если СтрНачинаетсяС(ВРег(ИмяСервера), "TCP://") Тогда ИмяСервера = Сред(ИмяСервера, 7); КонецЕсли; // Если в качестве имени сервера передается адрес IPv6, то порт может быть только после закрывающей квадратной скобки. НачальнаяПозиция = СтрНайти(ИмяСервера, "]"); Если НачальнаяПозиция <> 0 Тогда РазделительПорта = СтрНайти(ИмяСервера, ":",, НачальнаяПозиция); Иначе РазделительПорта = СтрНайти(ИмяСервера, ":"); КонецЕсли; Если РазделительПорта > 0 Тогда АдресАгентаСервера = Сред(ИмяСервера, 1, РазделительПорта - 1); ПортКластера = Число(Сред(ИмяСервера, РазделительПорта + 1)); Если СтруктураПараметровАдминистрирования.ПортКластера = 1541 Тогда СтруктураПараметровАдминистрирования.ПортКластера = ПортКластера; КонецЕсли; Иначе АдресАгентаСервера = ИмяСервера; КонецЕсли; СтруктураПараметровАдминистрирования.АдресАгентаСервера = АдресАгентаСервера; КонецПроцедуры // Проверяет возможность выполнения обработчиков установки параметров сеанса, // обработчиков обновления и других базовых механизмов конфигурации, // выполняющих код конфигурации по полному имени процедуры. // // В случае, если при текущих настройках профилей безопасности (в кластере серверов и в информационной базе) // выполнение обработчиков невозможно - генерируется исключение, // содержащее описание причины и перечень действий по ее устранению. // Процедура ПроверитьВозможностьЗапуска() Если ОбщегоНазначения.ИнформационнаяБазаФайловая(СтрокаСоединенияИнформационнойБазы()) Тогда Возврат; КонецЕсли; Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ПрофилиБезопасности") Тогда МодульРаботаВБезопасномРежиме = ОбщегоНазначения.ОбщийМодуль("РаботаВБезопасномРежиме"); ПрофильИнформационнойБазы = МодульРаботаВБезопасномРежиме.ПрофильБезопасностиИнформационнойБазы(); Иначе ПрофильИнформационнойБазы = ""; КонецЕсли; Если ЗначениеЗаполнено(ПрофильИнформационнойБазы) Тогда // Информационная база настроена на использование с профилем безопасности, в котором запрещен // полный доступ к внешним модулям. УстановитьБезопасныйРежим(ПрофильИнформационнойБазы); Если БезопасныйРежим() <> ПрофильИнформационнойБазы Тогда // Профиль ИБ не доступен для выполнения обработчиков. УстановитьБезопасныйРежим(Ложь); Попытка ДоступенПривилегированныйРежим = ВозможноВыполнениеОбработчиковБезУстановкиБезопасногоРежима(); Исключение ДоступенПривилегированныйРежим = Ложь; КонецПопытки; Если Не ДоступенПривилегированныйРежим Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Невозможно установить параметры сеанса по причине: профиль безопасности %1 отсутствует в кластере серверов 1С:Предприятия, или для него запрещено использование в качестве профиля безопасности безопасного режима. | |Для восстановления работоспособности программы отключите использование профиля безопасности через консоль кластера и заново настройте профили безопасности с помощью интерфейса конфигурации (соответствующие команды находятся в разделе настроек программы).'"), ПрофильИнформационнойБазы); КонецЕсли; КонецЕсли; ДоступенПривилегированныйРежим = ДоступенПереходВПривилегированныйРежим(); УстановитьБезопасныйРежим(Ложь); Если Не ДоступенПривилегированныйРежим Тогда // Профиль ИБ доступен для выполнения обработчиков, но в нем невозможна установка привилегированного режима. ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Невозможно установить параметры сеанса по причине: профиль безопасности %1 не содержит разрешения на установку привилегированного режима. Возможно, он был отредактирован через консоль кластера. | |Для восстановления работоспособности программы отключите использование профиля безопасности через консоль кластера и заново настройте профили безопасности с помощью интерфейса конфигурации (соответствующие команды находятся в разделе настроек программы).'"), ПрофильИнформационнойБазы); КонецЕсли; Иначе // Информационная база не настроена на использование с профилем безопасности, в котором запрещен // полный доступ к внешним модулям. Попытка ДоступенПривилегированныйРежим = ВозможноВыполнениеОбработчиковБезУстановкиБезопасногоРежима(); Исключение ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Невозможно установить параметры сеанса по причине: %1. | |Возможно, для информационной базы через консоль кластера был установлен профиль безопасности, не допускающий выполнения внешних модулей без установки безопасного режима. В этом случае для восстановления работоспособности программы отключите использование профиля безопасности через консоль кластера и заново настройте профили безопасности с помощью интерфейса конфигурации (соответствующие команды находятся в разделе настроек программы). При этом программа будет автоматически корректно настроена на использование совместно с включенными профилями безопасности.'"), КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); КонецПопытки; КонецЕсли; КонецПроцедуры // Проверяет возможность выполнения обработчиков без установки безопасного режима. // // Возвращаемое значение: // Булево // Функция ВозможноВыполнениеОбработчиковБезУстановкиБезопасногоРежима() // Вызов ОбщегоНазначения.ВычислитьВБезопасномРежиме не требуется, // т.к. это проверка установки привилегированного режима в функции Вычислить без установки безопасного режима. Возврат Вычислить("ДоступенПереходВПривилегированныйРежим()"); // АПК:488 КонецФункции // Проверяет возможность перехода в привилегированный режим из текущего безопасного режима. // // Возвращаемое значение: // Булево // Функция ДоступенПереходВПривилегированныйРежим() УстановитьПривилегированныйРежим(Истина); Возврат ПривилегированныйРежим(); КонецФункции // Для процедуры ЗарегистрироватьИзменениеПриоритетныхДанныхДляПодчиненныхУзловРИБ. Процедура ЗарегистрироватьИзменениеПредопределенных(УзлыПлановОбменаРИБ, КоллекцияМетаданных) Запрос = Новый Запрос; Для Каждого ОбъектМетаданных Из КоллекцияМетаданных Цикл УзлыРИБ = Новый Массив; Для Каждого УзлыПланаОбмена Из УзлыПлановОбменаРИБ Цикл Если Не УзлыПланаОбмена.Ключ.Содержит(ОбъектМетаданных) Тогда Продолжить; КонецЕсли; Для Каждого УзелРИБ Из УзлыПланаОбмена.Значение Цикл УзлыРИБ.Добавить(УзелРИБ); КонецЦикла; КонецЦикла; Если УзлыРИБ.Количество() = 0 Тогда Продолжить; КонецЕсли; Запрос.Текст = "ВЫБРАТЬ | ТекущаяТаблица.Ссылка КАК Ссылка |ИЗ | &ТекущаяТаблица КАК ТекущаяТаблица |ГДЕ | ТекущаяТаблица.Предопределенный"; Запрос.Текст = СтрЗаменить(Запрос.Текст, "&ТекущаяТаблица", ОбъектМетаданных.ПолноеИмя()); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл ПланыОбмена.ЗарегистрироватьИзменения(УзлыРИБ, Выборка.Ссылка); КонецЦикла; КонецЦикла; КонецПроцедуры // Для процедуры УстановитьКлючНазначенияФормы. Процедура УстановитьКлючНазначенияИспользованияФормы(Форма, Ключ, УстановитьНастройки) Если Не ЗначениеЗаполнено(Ключ) Или Форма.КлючНазначенияИспользования = Ключ Тогда Возврат; КонецЕсли; Если Не УстановитьНастройки Тогда Форма.КлючНазначенияИспользования = Ключ; Возврат; КонецЕсли; ТипыНастроек = Новый Массив; // Русский вариант. ТипыНастроек.Добавить("/КлючТекущегоВарианта"); ТипыНастроек.Добавить("/КлючТекущихПользовательскихНастроек"); ТипыНастроек.Добавить("/ТекущиеПользовательскиеНастройки"); ТипыНастроек.Добавить("/КлючТекущихНастроекДанных"); ТипыНастроек.Добавить("/ТекущиеДанные"); ТипыНастроек.Добавить("/НастройкиФормы"); // Английский вариант. ТипыНастроек.Добавить("/CurrentVariantKey"); ТипыНастроек.Добавить("/CurrentUserSettingsKey"); ТипыНастроек.Добавить("/CurrentUserSettings"); ТипыНастроек.Добавить("/CurrentDataSettingsKey"); ТипыНастроек.Добавить("/CurrentData"); ТипыНастроек.Добавить("/FormSettings"); Если ХранилищеСистемныхНастроек.Загрузить(Ключ, "КлючНазначенияИспользованияФормы") <> Истина И ПравоДоступа("СохранениеДанныхПользователя", Метаданные) Тогда УстановитьНастройкиДляКлюча(Ключ, ТипыНастроек, Форма.ИмяФормы, Форма.КлючНазначенияИспользования); ХранилищеСистемныхНастроек.Сохранить(Ключ, "КлючНазначенияИспользованияФормы", Истина); КонецЕсли; Форма.КлючНазначенияИспользования = Ключ; КонецПроцедуры // Для процедуры УстановитьКлючНазначенияФормы. Процедура УстановитьКлючСохраненияПоложенияОкнаФормы(Форма, Ключ, УстановитьНастройки) Если Не ЗначениеЗаполнено(Ключ) Или Форма.КлючСохраненияПоложенияОкна = Ключ Тогда Возврат; КонецЕсли; Если Не УстановитьНастройки Тогда Форма.КлючСохраненияПоложенияОкна = Ключ; Возврат; КонецЕсли; ТипыНастроек = Новый Массив; // Русский вариант. ТипыНастроек.Добавить("/НастройкиОкна"); ТипыНастроек.Добавить("/Такси/НастройкиОкна"); ТипыНастроек.Добавить("/НастройкиОкнаВебКлиента"); ТипыНастроек.Добавить("/Такси/НастройкиОкнаВебКлиента"); // Английский вариант. ТипыНастроек.Добавить("/WindowSettings"); ТипыНастроек.Добавить("/Taxi/WindowSettings"); ТипыНастроек.Добавить("/WebClientWindowSettings"); ТипыНастроек.Добавить("/Taxi/WebClientWindowSettings"); Если ХранилищеСистемныхНастроек.Загрузить(Ключ, "КлючСохраненияПоложенияОкнаФормы") <> Истина И ПравоДоступа("СохранениеДанныхПользователя", Метаданные) Тогда УстановитьНастройкиДляКлюча(Ключ, ТипыНастроек, Форма.ИмяФормы, Форма.КлючСохраненияПоложенияОкна); ХранилищеСистемныхНастроек.Сохранить(Ключ, "КлючСохраненияПоложенияОкнаФормы", Истина); КонецЕсли; Форма.КлючСохраненияПоложенияОкна = Ключ; КонецПроцедуры // Для процедур УстановитьКлючНазначенияИспользованияФормы, УстановитьКлючСохраненияПоложенияОкнаФормы. Процедура УстановитьНастройкиДляКлюча(Ключ, ТипыНастроек, ИмяФормы, ТекущийКлюч) Если Не ПравоДоступа("СохранениеДанныхПользователя", Метаданные) Тогда Возврат; КонецЕсли; НовыйКлюч = "/" + Ключ; Отбор = Новый Структура; Отбор.Вставить("Пользователь", ПользователиИнформационнойБазы.ТекущийПользователь().Имя); Для каждого ТипНастроек Из ТипыНастроек Цикл Отбор.Вставить("КлючОбъекта", ИмяФормы + НовыйКлюч + ТипНастроек); Выборка = ХранилищеСистемныхНастроек.Выбрать(Отбор); Если Выборка.Следующий() Тогда Возврат; // Настройки для ключа уже установлены. КонецЕсли; КонецЦикла; Если ЗначениеЗаполнено(ТекущийКлюч) Тогда ТекущийКлюч = "/" + ТекущийКлюч; КонецЕсли; // Установка начальных настроек ключа копированием от текущего ключа. Для Каждого ТипНастроек Из ТипыНастроек Цикл Отбор.Вставить("КлючОбъекта", ИмяФормы + ТекущийКлюч + ТипНастроек); Выборка = ХранилищеСистемныхНастроек.Выбрать(Отбор); КлючОбъекта = ИмяФормы + НовыйКлюч + ТипНастроек; Пока Выборка.Следующий() Цикл ОписаниеНастроек = Новый ОписаниеНастроек; ОписаниеНастроек.Представление = Выборка.Представление; ХранилищеСистемныхНастроек.Сохранить(КлючОбъекта, Выборка.КлючНастроек, Выборка.Настройки, ОписаниеНастроек); КонецЦикла; КонецЦикла; КонецПроцедуры // Многоязычные конфигурации Функция ТребуетсяУстановкаРегиональныхНастроекИнформационнойБазы() Экспорт Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда МодульМультиязычностьСервер = ОбщегоНазначения.ОбщийМодуль("МультиязычностьСервер"); Возврат МодульМультиязычностьСервер.ТребуетсяУстановкаРегиональныхНастроекИнформационнойБазы(); КонецЕсли; Возврат Ложь; КонецФункции //////////////////////////////////////////////////////////////////////////////// // Другие процедуры и функции. Функция ЭлементыСтиля() Экспорт НаборЭлементовСтиля = Новый Структура; Для каждого ЭлементСтиля Из Метаданные.ЭлементыСтиля Цикл НаборЭлементовСтиля.Вставить(ЭлементСтиля.Имя, ЭлементСтиля.Значение); КонецЦикла; Возврат Новый ФиксированнаяСтруктура(НаборЭлементовСтиля); КонецФункции // Возвращает сериализуемый набор элементов стиля. // // Возвращаемое значение: // Структура: // * Ключ - Строка - имя элемента стиля. // * Значение - Строка // - ОбъектМетаданныхЭлементСтиля - элемент стиля. Для толстого клиента обычного приложения // элемент стиля преобразуется в системное строковое представление переданного значения. // Функция НаборЭлементовСтиля() НаборЭлементовСтиля = Новый Структура; Для каждого ЭлементСтиля Из Метаданные.ЭлементыСтиля Цикл Если ТекущийРежимЗапуска() = РежимЗапускаКлиентскогоПриложения.ОбычноеПриложение Тогда НаборЭлементовСтиля.Вставить(ЭлементСтиля.Имя, Новый ХранилищеЗначения(ЭлементСтиля.Значение)); Иначе НаборЭлементовСтиля.Вставить(ЭлементСтиля.Имя, ЭлементСтиля.Значение); КонецЕсли; КонецЦикла; Возврат Новый ФиксированнаяСтруктура(НаборЭлементовСтиля); КонецФункции // Для процедуры ПриЗаполненииРазрешенийНаДоступКВнешнимРесурсам. Процедура ДобавитьЗапросРазрешенийНаИспользованиеРасширений(ЗапросыРазрешений) Если ОбщегоНазначения.РазделениеВключено() И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда Возврат; КонецЕсли; Разрешения = Новый Массив; ВсеРасширения = РасширенияКонфигурации.Получить(); МодульРаботаВБезопасномРежиме = ОбщегоНазначения.ОбщийМодуль("РаботаВБезопасномРежиме"); Для Каждого Расширение Из ВсеРасширения Цикл Разрешения.Добавить(МодульРаботаВБезопасномРежиме.РазрешениеНаИспользованиеВнешнегоМодуля( Расширение.Имя, Base64Строка(Расширение.ХешСумма))); КонецЦикла; ЗапросыРазрешений.Добавить(МодульРаботаВБезопасномРежиме.ЗапросНаИспользованиеВнешнихРесурсов(Разрешения, ОбщегоНазначения.ИдентификаторОбъектаМетаданных("РегистрСведений.ПараметрыРаботыВерсийРасширений"))); КонецПроцедуры Функция ТребуетсяПоказРекомендацииПоОбъемуОперативнойПамяти() Если ОбщегоНазначения.ЭтоВебКлиент() Или Не ОбщегоНазначения.ИнформационнаяБазаФайловая() Тогда Возврат Ложь; КонецЕсли; ОперативнаяПамять = ПараметрыКлиентаНаСервере().Получить("ОперативнаяПамять"); Если ТипЗнч(ОперативнаяПамять) <> Тип("Число") Тогда Возврат Ложь; // Параметр клиента на сервере не заполнен (нет клиентского приложения). КонецЕсли; РекомендуемыйОбъем = ОбщегоНазначения.ОбщиеПараметрыБазовойФункциональности().РекомендуемыйОбъемОперативнойПамяти; СохраненнаяРекомендация = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить("ОбщиеНастройкиПользователя", "РекомендацияПоОбъемуОперативнойПамяти"); Рекомендация = Новый Структура; Рекомендация.Вставить("Показывать", Истина); Рекомендация.Вставить("ДатаПредыдущегоПоказа", Дата(1, 1, 1)); Если ТипЗнч(СохраненнаяРекомендация) = Тип("Структура") Тогда ЗаполнитьЗначенияСвойств(Рекомендация, СохраненнаяРекомендация); КонецЕсли; Возврат ОперативнаяПамять < РекомендуемыйОбъем И (Рекомендация.Показывать Или (ТекущаяДатаСеанса() - Рекомендация.ДатаПредыдущегоПоказа) > 60*60*24*60) КонецФункции Процедура ИгнорироватьОтправкуДанныхОбработанныхВЦентральномУзлеРИБПриОбновленииИБ(ЭлементДанных, СозданиеНачальногоОбраза, Получатель) Если Получатель <> Неопределено И Не СозданиеНачальногоОбраза И ТипЗнч(ЭлементДанных) = Тип("РегистрСведенийНаборЗаписей.ДанныеОбработанныеВЦентральномУзлеРИБ") Тогда Индекс = ЭлементДанных.Количество() - 1; Пока Индекс > 0 Цикл СтрокаНабора = ЭлементДанных[Индекс]; Если СтрокаНабора.УзелПланаОбмена <> Получатель Тогда ЭлементДанных.Удалить(СтрокаНабора); КонецЕсли; Индекс = Индекс - 1; КонецЦикла; КонецЕсли; КонецПроцедуры #КонецОбласти