Files
SSL/SSL/src/CommonModules/ОбщегоНазначенияСлужебныйКлиент/Module.bsl
T
2022-11-17 09:29:00 +03:00

1548 lines
94 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2022, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////
#Область СлужебныйПрограммныйИнтерфейс
// Проверяет, является ли переданная строка внутренней навигационной ссылкой.
//
// Параметры:
// Строка - Строка - навигационная ссылка.
//
// Возвращаемое значение:
// Булево - результат проверки.
//
Функция ЭтоНавигационнаяСсылка(Строка) Экспорт
Возврат СтрНачинаетсяС(Строка, "e1c:")
Или СтрНачинаетсяС(Строка, "e1cib/")
Или СтрНачинаетсяС(Строка, "e1ccs/");
КонецФункции
// Конвертирует параметры запуска текущего сеанса в передаваемые параметры в скрипт
// Например, на вход программа может быть запущена с ключом:
// /C "ПараметрыЗапускаИзВнешнейОперации=/TestClient -TPort 48050 /C РежимОтладки;РежимОтладки"
// то в скрипт будет передана строка: "/TestClient -TPort 48050 /C РежимОтладки".
//
// Возвращаемое значение:
// Строка - значение параметра.
//
Функция ПараметрыЗапускаПредприятияИзСкрипта() Экспорт
Перем ЗначениеПараметра;
ПараметрыЗапуска = СтроковыеФункцииКлиентСервер.ПараметрыИзСтроки(ПараметрЗапуска);
Если Не ПараметрыЗапуска.Свойство("ПараметрыЗапускаИзВнешнейОперации", ЗначениеПараметра) Тогда
ЗначениеПараметра = "";
КонецЕсли;
Возврат ЗначениеПараметра;
КонецФункции
// Сокращает имя файла с расширением.
// Сокращение имени, производится, когда имя файла с расширением превышает размер 255 байт.
// Сокращение ими файла достигая за счет сокращения имени файла без расширения и
// добавления значения хеш функции сокращенной строки.
//
// Параметры:
// ИмяФайла - Строка - имя файла с расширением
Процедура СократитьИмяФайла(ИмяФайла) Экспорт
#Если ВебКлиент Тогда
Возврат;
#КонецЕсли
ОграничениеВБайтах = 255;
Если РазмерСтрокиВБайтах(ИмяФайла) <= ОграничениеВБайтах Тогда
Возврат;
КонецЕсли;
Файл = Новый Файл(ИмяФайла);
ИмяБезРасширения = Файл.ИмяБезРасширения;
ОграничениеВБайтах = ОграничениеВБайтах - РазмерСтрокиВБайтах(Файл.Расширение);
ДлинаСтроки = СтрДлина(ИмяБезРасширения);
ИспользуемоеКоличествоСимволов = ОграничениеВБайтах - 32;
БольшееКоличествоСимволов = Мин(ДлинаСтроки, ОграничениеВБайтах);
МеньшееКоличествоСимволов = Цел((ОграничениеВБайтах - 32)/4);
Уменьшить = Истина;
Пока Истина Цикл
Если Уменьшить Тогда
ИспользуемоеКоличествоСимволов = МеньшееКоличествоСимволов + Цел((ИспользуемоеКоличествоСимволов-МеньшееКоличествоСимволов)/2);
Иначе
ИспользуемоеКоличествоСимволов = ИспользуемоеКоличествоСимволов + Цел((БольшееКоличествоСимволов - ИспользуемоеКоличествоСимволов)/2);
КонецЕсли;
РазмерСтрокиВБайтах = РазмерСтрокиВБайтах(ИмяБезРасширения)+32;
Если РазмерСтрокиВБайтах = ОграничениеВБайтах Или БольшееКоличествоСимволов - МеньшееКоличествоСимволов = 1 Тогда
Прервать;
КонецЕсли;
Если РазмерСтрокиВБайтах > ОграничениеВБайтах Тогда
Уменьшить = Истина;
БольшееКоличествоСимволов = ИспользуемоеКоличествоСимволов;
Иначе
Уменьшить = Ложь;
МеньшееКоличествоСимволов = ИспользуемоеКоличествоСимволов;
КонецЕсли;
КонецЦикла;
СокращеннаяСтрока = СократитьСтрокуСИпользованиемХеш(ИмяБезРасширения, ИспользуемоеКоличествоСимволов);
ИмяФайла = СокращеннаяСтрока+Файл.Расширение;
КонецПроцедуры
#Область ВнешниеКомпоненты
// Контекст подключения компоненты.
//
// Возвращаемое значение:
// Структура - контекст подключения компоненты:
// * Оповещение - Неопределено, ОписаниеОповещения - оповещение.
// * Идентификатор - Строка - идентификатор объекта компоненты, идентификатор внешней компоненты.
// * Версия - Неопределено, Строка - версия компоненты.
// * Местоположение - Строка - местоположение макета или ссылка на внешнюю компоненту.
// * ИсходноеМестоположение - Строка - местоположение начального вызова, для хранения кэша.
// * Кэшировать - Булево - признак сохранения подключенной компоненты в кэше.
// * ПредложитьУстановить - Булево - предлагать устанавливать компоненту.
// * ПредложитьЗагрузить - Булево - предлагать загружать компоненту с сайта ИТС.
// * ТекстПояснения - Строка - для чего нужна компонента и что не будет работать, если ее не устанавливать.
// * ИдентификаторыСозданияОбъектов - Массив -идентификатор создания экземпляра модуля объекта,
// используется только для компонент, у которых есть несколько идентификаторов создания объектов,
// при задании параметр Идентификатор будет игнорироваться.
// * ВыполненПоискНовойВерсии - Булево - поиск новой версии компоненты производился.
//
Функция КонтекстПодключенияКомпоненты() Экспорт
Контекст = Новый Структура;
Контекст.Вставить("Оповещение", Неопределено);
Контекст.Вставить("Идентификатор", Неопределено);
Контекст.Вставить("Версия", "");
Контекст.Вставить("Местоположение", "");
Контекст.Вставить("ИсходноеМестоположение", "");
Контекст.Вставить("Кэшировать", Истина);
Контекст.Вставить("ПредложитьУстановить", Истина);
Контекст.Вставить("ПредложитьЗагрузить", Ложь);
Контекст.Вставить("ТекстПояснения", "");
Контекст.Вставить("ИдентификаторыСозданияОбъектов", Новый Массив);
Контекст.Вставить("ВыполненПоискНовойВерсии", Ложь);
Возврат Контекст;
КонецФункции
// Параметры:
// Контекст - см. КонтекстПодключенияКомпоненты.
//
Процедура ПодключитьКомпоненту(Контекст) Экспорт
Если ПустаяСтрока(Контекст.Идентификатор) Тогда
КомпонентаСодержитЕдинственныйКлассОбъектов = (Контекст.ИдентификаторыСозданияОбъектов.Количество() = 0);
Если КомпонентаСодержитЕдинственныйКлассОбъектов Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не удалось подключить внешнюю компоненту ""%1"" в клиентском приложении
|по причине:
|Недопустимо одновременно не указывать %2 и %3.'"),
Контекст.Местоположение, "Идентификатор", "ИдентификаторыСозданияОбъектов");
Иначе
// В случае, когда в компоненте есть несколько классов объектов
// Идентификатор используется только для отображения компоненты в текстах ошибок.
// Следует собрать идентификатор для отображения.
Контекст.Идентификатор = СтрСоединить(Контекст.ИдентификаторыСозданияОбъектов, ", ");
КонецЕсли;
КонецЕсли;
ПроверитьМестоположениеКомпоненты(Контекст.Идентификатор, Контекст.Местоположение);
Если Не Контекст.ВыполненПоискНовойВерсии Тогда
Если Контекст.Кэшировать Тогда
ПодключаемыйМодуль = ПолучитьОбъектКомпонентыИзКэша(Контекст.Местоположение);
Если ПодключаемыйМодуль <> Неопределено Тогда
ПодключитьКомпонентуОповеститьОПодключении(ПодключаемыйМодуль, Контекст);
Возврат;
КонецЕсли;
КонецЕсли;
// Проверка факта подключения внешней компоненты в этом сеансе ранее.
СимволическоеИмя = ПолучитьСимволическоеИмяКомпонентыИзКэша(Контекст.Местоположение);
Если СимволическоеИмя <> Неопределено Тогда
// Если в кэше уже есть символическое имя - значит к этому сеансу ранее компонента уже подключалась.
Подключено = Истина;
Контекст.Вставить("СимволическоеИмя", СимволическоеИмя);
ПодключитьКомпонентуПослеПопыткиПодключения(Подключено, Контекст);
Возврат;
КонецЕсли;
// Поиск более свежей версии компоненты в макетах и справочнике.
Если ЭтоМакет(Контекст.Местоположение) Тогда
Контекст.ИсходноеМестоположение = Контекст.Местоположение;
Оповещение = Новый ОписаниеОповещения("ПодключитьПослеПоискаВнешнейКомпоненты", ЭтотОбъект, Контекст);
Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.ВнешниеКомпоненты") Тогда
МодульВнешниеКомпонентыСлужебныйКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль(
"ВнешниеКомпонентыСлужебныйКлиент");
КонтекстПроверкиКомпоненты = КонтекстПодключенияКомпоненты();
КонтекстПроверкиКомпоненты.Идентификатор = Контекст.Идентификатор;
КонтекстПроверкиКомпоненты.Версия = Неопределено;
КонтекстПроверкиКомпоненты.ПредложитьУстановить = Контекст.ПредложитьУстановить;
КонтекстПроверкиКомпоненты.ПредложитьЗагрузить = Контекст.ПредложитьЗагрузить;
КонтекстПроверкиКомпоненты.ТекстПояснения = Контекст.ТекстПояснения;
КонтекстПроверкиКомпоненты.ИсходноеМестоположение = Контекст.ИсходноеМестоположение;
КонтекстПроверкиКомпоненты.ИдентификаторыСозданияОбъектов = Контекст.ИдентификаторыСозданияОбъектов;
МодульВнешниеКомпонентыСлужебныйКлиент.ПроверитьДоступностьКомпоненты(Оповещение,
КонтекстПроверкиКомпоненты);
Иначе
ВыполнитьОбработкуОповещения(Оповещение, Неопределено);
КонецЕсли;
Возврат;
КонецЕсли;
КонецЕсли;
// Генерация уникального имени.
СимволическоеИмя = "С" + СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "");
Контекст.Вставить("СимволическоеИмя", СимволическоеИмя);
Оповещение = Новый ОписаниеОповещения(
"ПодключитьКомпонентуПослеПопыткиПодключения", ЭтотОбъект, Контекст,
"ПодключитьКомпонентуПриОбработкеОшибки", ЭтотОбъект);
НачатьПодключениеВнешнейКомпоненты(Оповещение, Контекст.Местоположение, СимволическоеИмя);
КонецПроцедуры
// Продолжение процедуры ПодключитьКомпоненту.
Процедура ПодключитьКомпонентуОповеститьОПодключении(ПодключаемыйМодуль, Контекст) Экспорт
Результат = РезультатПодключенияКомпоненты();
Результат.Подключено = Истина;
Результат.ПодключаемыйМодуль = ПодключаемыйМодуль;
ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат);
КонецПроцедуры
// Продолжение процедуры ПодключитьКомпоненту.
Процедура ПодключитьКомпонентуОповеститьОбОшибке(ОписаниеОшибки, Контекст) Экспорт
Если Не ПустаяСтрока(ОписаниеОшибки) Тогда
ЖурналРегистрацииКлиент.ДобавитьСообщениеДляЖурналаРегистрации(
НСтр("ru = 'Подключение внешней компоненты на клиенте'", ОбщегоНазначенияКлиент.КодОсновногоЯзыка()),
"Ошибка", ОписаниеОшибки,, Истина);
КонецЕсли;
Оповещение = Контекст.Оповещение;
Результат = РезультатПодключенияКомпоненты();
Результат.ОписаниеОшибки = ОписаниеОшибки;
ВыполнитьОбработкуОповещения(Оповещение, Результат);
КонецПроцедуры
// Параметры:
// Контекст - Структура:
// * Оповещение - ОписаниеОповещения
// * Местоположение - Строка
// * ТекстПояснения - Строка
// * Идентификатор - Строка
//
Процедура УстановитьКомпоненту(Контекст) Экспорт
ПроверитьМестоположениеКомпоненты(Контекст.Идентификатор, Контекст.Местоположение);
// Проверка факта подключения внешней компоненты в этом сеансе ранее.
СимволическоеИмя = ПолучитьСимволическоеИмяКомпонентыИзКэша(Контекст.Местоположение);
Если СимволическоеИмя = Неопределено Тогда
Оповещение = Новый ОписаниеОповещения(
"УстановитьКомпонентуПослеОтветаНаВопросОбУстановке", ЭтотОбъект, Контекст);
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ТекстПояснения", Контекст.ТекстПояснения);
ОткрытьФорму("ОбщаяФорма.ВопросОбУстановкеВнешнейКомпоненты",
ПараметрыФормы,,,,, Оповещение);
Иначе
// Если в кэше уже есть символическое имя - значит к этому сеансу ранее компонента уже подключалась,
// значит внешняя компонента уже установлена.
Результат = РезультатУстановкиКомпоненты();
Результат.Вставить("Установлено", Истина);
ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат);
КонецЕсли;
КонецПроцедуры
// Продолжение процедуры УстановитьКомпоненту.
Процедура УстановитьКомпонентуОповеститьОбОшибке(ОписаниеОшибки, Контекст) Экспорт
Оповещение = Контекст.Оповещение;
Результат = РезультатУстановкиКомпоненты();
Результат.ОписаниеОшибки = ОписаниеОшибки;
ВыполнитьОбработкуОповещения(Оповещение, Результат);
КонецПроцедуры
#КонецОбласти
#Область ТабличныйДокумент
////////////////////////////////////////////////////////////////////////////////
// Функции для работы с табличными документами.
// Выполняет расчет и вывод показателей выделенных областей ячеек табличного документа.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - форма, в которой выводятся значения расчетных показателей.
// ИмяТабличногоДокумента - Строка - имя реквизита формы типа ТабличныйДокумент, показатели которого рассчитываются.
// ТекущаяКоманда - Строка - имя команды расчета показателя, например, "РассчитатьСумму".
// Определяет, какой показатель является основным.
// МинимальноеКоличество - Число
//
Процедура РассчитатьПоказатели(Форма, ИмяТабличногоДокумента, ТекущаяКоманда = "", МинимальноеКоличество = 0) Экспорт
Элементы = Форма.Элементы;
ТабличныйДокумент = Форма[ИмяТабличногоДокумента];
ПолеТабличногоДокумента = Элементы[ИмяТабличногоДокумента];
Если Не ЗначениеЗаполнено(ТекущаяКоманда) Тогда
ТекущаяКоманда = ТекущаяКомандаРасчетаПоказателей(Элементы);
КонецЕсли;
ПараметрыРасчета = ОбщегоНазначенияКлиентСервер.ПараметрыРасчетаПоказателейЯчеек(ПолеТабличногоДокумента);
Если ПараметрыРасчета.РассчитатьНаСервере Тогда
ДлительнаяОперация = СтандартныеПодсистемыВызовСервера.РасчетныеПоказателиЯчеек(
ТабличныйДокумент, ПараметрыРасчета.ВыделенныеОбласти, Форма.УникальныйИдентификатор);
Если ДлительнаяОперация = Неопределено Тогда
Возврат;
КонецЕсли;
ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(Форма);
ПараметрыОжидания.ФормаВладелец = Форма;
ПараметрыОжидания.ВыводитьОкноОжидания = Ложь;
ДополнительныеПараметры = Новый Структура;
ДополнительныеПараметры.Вставить("Форма", Форма);
ДополнительныеПараметры.Вставить("ТекущаяКоманда", ТекущаяКоманда);
ДополнительныеПараметры.Вставить("МинимальноеКоличество", МинимальноеКоличество);
ОповещениеОЗавершении = Новый ОписаниеОповещения("ПродолжитьРасчетПоказателей", ЭтотОбъект, ДополнительныеПараметры);
ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, ОповещениеОЗавершении, ПараметрыОжидания);
Иначе
РасчетныеПоказатели = ОбщегоНазначенияКлиентСервер.РасчетныеПоказателиЯчеек(
ТабличныйДокумент, ПолеТабличногоДокумента, ПараметрыРасчета);
ЗавершитьРасчетПоказателей(Форма, ТекущаяКоманда, МинимальноеКоличество, РасчетныеПоказатели);
КонецЕсли;
КонецПроцедуры
// Управляет признаком видимости панели расчетных показателей.
//
// Параметры:
// ЭлементыФормы - ЭлементыФормы
// Видимость - Булево - признак включения / выключения видимости панели показателей.
// См. также Синтакс-помощник: ГруппаФормы.Видимость.
//
Процедура УстановитьВидимостьПанелиПоказателей(ЭлементыФормы, Видимость = Ложь) Экспорт
ЭлементыФормы.ОбластьПоказателей.Видимость = Видимость;
ИзменитьСвойствоЭлементаРасчетаПоказателей(ЭлементыФормы, "РассчитатьВсеПоказатели", "Пометка", Видимость);
КонецПроцедуры
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
#Область Данные
#Область СкопироватьРекурсивно
Функция СкопироватьСтруктуру(СтруктураИсточник, ФиксироватьДанные) Экспорт
СтруктураРезультат = Новый Структура;
Для Каждого КлючИЗначение Из СтруктураИсточник Цикл
СтруктураРезультат.Вставить(КлючИЗначение.Ключ,
ОбщегоНазначенияКлиент.СкопироватьРекурсивно(КлючИЗначение.Значение, ФиксироватьДанные));
КонецЦикла;
Если ФиксироватьДанные = Истина
Или ФиксироватьДанные = Неопределено
И ТипЗнч(СтруктураИсточник) = Тип("ФиксированнаяСтруктура") Тогда
Возврат Новый ФиксированнаяСтруктура(СтруктураРезультат);
КонецЕсли;
Возврат СтруктураРезультат;
КонецФункции
Функция СкопироватьСоответствие(СоответствиеИсточник, ФиксироватьДанные) Экспорт
СоответствиеРезультат = Новый Соответствие;
Для Каждого КлючИЗначение Из СоответствиеИсточник Цикл
СоответствиеРезультат.Вставить(КлючИЗначение.Ключ,
ОбщегоНазначенияКлиент.СкопироватьРекурсивно(КлючИЗначение.Значение, ФиксироватьДанные));
КонецЦикла;
Если ФиксироватьДанные = Истина
Или ФиксироватьДанные = Неопределено
И ТипЗнч(СоответствиеИсточник) = Тип("ФиксированноеСоответствие") Тогда
Возврат Новый ФиксированноеСоответствие(СоответствиеРезультат);
КонецЕсли;
Возврат СоответствиеРезультат;
КонецФункции
Функция СкопироватьМассив(МассивИсточник, ФиксироватьДанные) Экспорт
МассивРезультат = Новый Массив;
Для Каждого Элемент Из МассивИсточник Цикл
МассивРезультат.Добавить(ОбщегоНазначенияКлиент.СкопироватьРекурсивно(Элемент, ФиксироватьДанные));
КонецЦикла;
Если ФиксироватьДанные = Истина
Или ФиксироватьДанные = Неопределено
И ТипЗнч(МассивИсточник) = Тип("ФиксированныйМассив") Тогда
Возврат Новый ФиксированныйМассив(МассивРезультат);
КонецЕсли;
Возврат МассивРезультат;
КонецФункции
Функция СкопироватьСписокЗначений(СписокИсточник, ФиксироватьДанные) Экспорт
СписокРезультат = Новый СписокЗначений;
Для Каждого ЭлементСписка Из СписокИсточник Цикл
СписокРезультат.Добавить(
ОбщегоНазначенияКлиент.СкопироватьРекурсивно(ЭлементСписка.Значение, ФиксироватьДанные),
ЭлементСписка.Представление,
ЭлементСписка.Пометка,
ЭлементСписка.Картинка);
КонецЦикла;
Возврат СписокРезультат;
КонецФункции
#КонецОбласти
#КонецОбласти
#Область Формы
Функция ИмяОбъектаМетаданных(Тип) Экспорт
ИмяПараметра = "СтандартныеПодсистемы.ИменаОбъектовМетаданных";
Если ПараметрыПриложения[ИмяПараметра] = Неопределено Тогда
ПараметрыПриложения.Вставить(ИмяПараметра, Новый Соответствие);
КонецЕсли;
ИменаОбъектовМетаданных = ПараметрыПриложения[ИмяПараметра];
Результат = ИменаОбъектовМетаданных[Тип];
Если Результат = Неопределено Тогда
Результат = СтандартныеПодсистемыВызовСервера.ИмяОбъектаМетаданных(Тип);
ИменаОбъектовМетаданных.Вставить(Тип, Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПодтвердитьЗакрытиеФормы() Экспорт
ИмяПараметра = "СтандартныеПодсистемы.ПараметрыПодтвержденияЗакрытияФормы";
Если ПараметрыПриложения[ИмяПараметра] = Неопределено Тогда
ПараметрыПриложения.Вставить(ИмяПараметра, Неопределено);
КонецЕсли;
Параметры = ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПодтвержденияЗакрытияФормы"];
Если Параметры = Неопределено Тогда
Возврат;
КонецЕсли;
Оповещение = Новый ОписаниеОповещения("ПодтвердитьЗакрытиеФормыЗавершение", ЭтотОбъект, Параметры);
Если ПустаяСтрока(Параметры.ТекстПредупреждения) Тогда
ТекстВопроса = НСтр("ru = 'Данные были изменены. Сохранить изменения?'");
Иначе
ТекстВопроса = Параметры.ТекстПредупреждения;
КонецЕсли;
ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНетОтмена, ,
КодВозвратаДиалога.Да);
КонецПроцедуры
Процедура ПодтвердитьЗакрытиеФормыЗавершение(Ответ, Параметры) Экспорт
ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПодтвержденияЗакрытияФормы"] = Неопределено;
Если Ответ = КодВозвратаДиалога.Да Тогда
ВыполнитьОбработкуОповещения(Параметры.ОповещениеСохранитьИЗакрыть);
ИначеЕсли Ответ = КодВозвратаДиалога.Нет Тогда
Форма = Параметры.ОповещениеСохранитьИЗакрыть.Модуль;
Форма.Модифицированность = Ложь;
Форма.Закрыть();
Иначе
Форма = Параметры.ОповещениеСохранитьИЗакрыть.Модуль;
Форма.Модифицированность = Истина;
КонецЕсли;
КонецПроцедуры
Процедура ПодтвердитьЗакрытиеПроизвольнойФормы() Экспорт
ИмяПараметра = "СтандартныеПодсистемы.ПараметрыПодтвержденияЗакрытияФормы";
Если ПараметрыПриложения[ИмяПараметра] = Неопределено Тогда
ПараметрыПриложения.Вставить(ИмяПараметра, Неопределено);
КонецЕсли;
Параметры = ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПодтвержденияЗакрытияФормы"];
Если Параметры = Неопределено Тогда
Возврат;
КонецЕсли;
ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыПодтвержденияЗакрытияФормы"] = Неопределено;
РежимВопроса = РежимДиалогаВопрос.ДаНет;
Оповещение = Новый ОписаниеОповещения("ПодтвердитьЗакрытиеПроизвольнойФормыЗавершение", ЭтотОбъект, Параметры);
ПоказатьВопрос(Оповещение, Параметры.ТекстПредупреждения, РежимВопроса);
КонецПроцедуры
Процедура ПодтвердитьЗакрытиеПроизвольнойФормыЗавершение(Ответ, Параметры) Экспорт
Форма = Параметры.Форма;
Если Ответ = КодВозвратаДиалога.Да
Или Ответ = КодВозвратаДиалога.ОК Тогда
Форма[Параметры.ИмяРеквизитаЗакрытьФормуБезПодтверждения] = Истина;
Если Параметры.ОписаниеОповещенияЗакрыть <> Неопределено Тогда
ВыполнитьОбработкуОповещения(Параметры.ОписаниеОповещенияЗакрыть);
КонецЕсли;
Форма.Закрыть();
Иначе
Форма[Параметры.ИмяРеквизитаЗакрытьФормуБезПодтверждения] = Ложь;
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ФормыРедактирования
Процедура КомментарийЗавершениеВвода(Знач ВведенныйТекст, Знач ДополнительныеПараметры) Экспорт
Если ВведенныйТекст = Неопределено Тогда
Возврат;
КонецЕсли;
РеквизитФормы = ДополнительныеПараметры.ФормаВладелец;
ПутьКРеквизитуФормы = СтрРазделить(ДополнительныеПараметры.ИмяРеквизита, ".");
// Если реквизит вида "Объект.Комментарий" и т.п.
Если ПутьКРеквизитуФормы.Количество() > 1 Тогда
Для Индекс = 0 По ПутьКРеквизитуФормы.Количество() - 2 Цикл
РеквизитФормы = РеквизитФормы[ПутьКРеквизитуФормы[Индекс]];
КонецЦикла;
КонецЕсли;
РеквизитФормы[ПутьКРеквизитуФормы[ПутьКРеквизитуФормы.Количество() - 1]] = ВведенныйТекст;
ДополнительныеПараметры.ФормаВладелец.Модифицированность = Истина;
КонецПроцедуры
#КонецОбласти
#Область ВнешниеКомпоненты
// Продолжение процедуры ПодключитьКомпоненту.
//
// Параметры:
// Результат - Неопределено - если нет подсистемы ВнешниеКомпоненты
// - см. ВнешниеКомпонентыСлужебныйКлиент.РезультатДоступностиКомпоненты
// Контекст - см. ОбщегоНазначенияСлужебныйКлиент.КонтекстПодключенияКомпоненты
//
Процедура ПодключитьПослеПоискаВнешнейКомпоненты(Результат, Контекст) Экспорт
Контекст.ВыполненПоискНовойВерсии = Истина;
Если Результат = Неопределено Или Результат.КомпонентаПоследнейВерсии = Неопределено Тогда
КомпонентаПоследнейВерсии = СтандартныеПодсистемыВызовСервера.КомпонентаПоследнейВерсии(
Контекст.Идентификатор, Контекст.ИсходноеМестоположение, Результат);
Иначе
КомпонентаПоследнейВерсии = Результат.КомпонентаПоследнейВерсии;
КонецЕсли;
Контекст.Местоположение = КомпонентаПоследнейВерсии.Местоположение;
Контекст.Версия = КомпонентаПоследнейВерсии.Версия;
ПодключитьКомпоненту(Контекст);
КонецПроцедуры
// Продолжение процедуры ПодключитьКомпоненту.
Процедура ПодключитьКомпонентуПослеПопыткиПодключения(Подключено, Контекст) Экспорт
Если Подключено Тогда
// Сохранение факта подключения внешней компоненты к этому сеансу.
ИсходноеМестоположение = ?(ЗначениеЗаполнено(Контекст.ИсходноеМестоположение),
Контекст.ИсходноеМестоположение, Контекст.Местоположение);
ЗаписатьСимволическоеИмяКомпонентыВКэш(ИсходноеМестоположение, Контекст.СимволическоеИмя);
ПодключаемыйМодуль = Неопределено;
Попытка
ПодключаемыйМодуль = НовыйОбъектКомпоненты(Контекст);
Исключение
// Текст ошибки уже скомпонован в НовыйОбъектКомпоненты, требуется только оповестить.
ТекстОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
ПодключитьКомпонентуОповеститьОбОшибке(ТекстОшибки, Контекст);
Возврат;
КонецПопытки;
Если Контекст.Кэшировать Тогда
ЗаписатьОбъектКомпонентыВКэш(ИсходноеМестоположение, ПодключаемыйМодуль)
КонецЕсли;
ПодключитьКомпонентуОповеститьОПодключении(ПодключаемыйМодуль, Контекст);
Иначе
Если Контекст.ПредложитьУстановить Тогда
ПодключитьКомпонентуНачатьУстановку(Контекст);
Иначе
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не удалось подключить внешнюю компоненту ""%1"".
|Возможно компонента не предназначена для клиентского приложения %2.
|
|Техническая информация:
|%3
|Метод %4 вернул Ложь.'"),
Контекст.Идентификатор, ВидПриложения(), Контекст.Местоположение, "НачатьПодключениеВнешнейКомпоненты");
ПодключитьКомпонентуОповеститьОбОшибке(ТекстОшибки, Контекст);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ВидПриложения()
СистемнаяИнформация = Новый СистемнаяИнформация();
Результат = "";
#Если ВебКлиент Тогда
Результат = НСтр("ru = 'Веб-клиент'") + СистемнаяИнформация.ИнформацияПрограммыПросмотра;
#ИначеЕсли ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
Результат = НСтр("ru = 'Толстый клиент'");
#ИначеЕсли ТонкийКлиент Тогда
Результат = НСтр("ru = 'Тонкий клиент'");
#КонецЕсли
Возврат Результат + " (" + СистемнаяИнформация.ТипПлатформы + ")";
КонецФункции
// Продолжение процедуры ПодключитьКомпоненту.
Процедура ПодключитьКомпонентуНачатьУстановку(Контекст)
Оповещение = Новый ОписаниеОповещения(
"ПодключитьКомпонентуПослеУстановки", ЭтотОбъект, Контекст);
КонтекстУстановки = Новый Структура;
КонтекстУстановки.Вставить("Оповещение", Оповещение);
КонтекстУстановки.Вставить("Местоположение", Контекст.Местоположение);
КонтекстУстановки.Вставить("ТекстПояснения", Контекст.ТекстПояснения);
КонтекстУстановки.Вставить("Идентификатор", Контекст.Идентификатор);
УстановитьКомпоненту(КонтекстУстановки);
КонецПроцедуры
// Продолжение процедуры ПодключитьКомпоненту.
Процедура ПодключитьКомпонентуПослеУстановки(Результат, Контекст) Экспорт
Если Результат.Установлено Тогда
// Одна попытка установки уже прошла, если компонента не подключится в этот раз,
// то и предлагать ее установить еще раз не следует.
Контекст.ПредложитьУстановить = Ложь;
ПодключитьКомпоненту(Контекст);
Иначе
// Расшифровка ОписаниеОшибки не нужна, текст уже сформирован при установке.
// При отказе от установки пользователем ОписаниеОшибки - пустая строка.
ПодключитьКомпонентуОповеститьОбОшибке(Результат.ОписаниеОшибки, Контекст);
КонецЕсли;
КонецПроцедуры
// Продолжение процедуры ПодключитьКомпоненту.
//
// Параметры:
// ИнформацияОбОшибке- ИнформацияОбОшибке
// СтандартнаяОбработка - Булево
// Контекст - см. ПодключитьКомпоненту.Контекст
//
Процедура ПодключитьКомпонентуПриОбработкеОшибки(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт
СтандартнаяОбработка = Ложь;
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не удалось подключить внешнюю компоненту ""%1"" на клиенте
|%2
|по причине:
|%3'"),
Контекст.Идентификатор,
Контекст.Местоположение,
КраткоеПредставлениеОшибки(ИнформацияОбОшибке));
ПодключитьКомпонентуОповеститьОбОшибке(ТекстОшибки, Контекст);
КонецПроцедуры
// Создает экземпляр внешней компоненты (или несколько)
Функция НовыйОбъектКомпоненты(Контекст)
КомпонентаСодержитЕдинственныйКлассОбъектов = (Контекст.ИдентификаторыСозданияОбъектов.Количество() = 0);
Если КомпонентаСодержитЕдинственныйКлассОбъектов Тогда
Попытка
ПодключаемыйМодуль = Новый("AddIn." + Контекст.СимволическоеИмя + "." + Контекст.Идентификатор);
Если ПодключаемыйМодуль = Неопределено Тогда
ВызватьИсключение НСтр("ru = 'Оператор Новый вернул Неопределено'");
КонецЕсли;
Исключение
ПодключаемыйМодуль = Неопределено;
ТекстОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Если ПодключаемыйМодуль = Неопределено Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не удалось создать объект внешней компоненты ""%1"", подключенной на клиенте
|%2,
|по причине:
|%3'"),
Контекст.Идентификатор,
Контекст.Местоположение,
ТекстОшибки);
КонецЕсли;
Иначе
ПодключаемыеМодули = Новый Соответствие;
Для каждого ИдентификаторОбъекта Из Контекст.ИдентификаторыСозданияОбъектов Цикл
Попытка
ПодключаемыйМодуль = Новый("AddIn." + Контекст.СимволическоеИмя + "." + ИдентификаторОбъекта);
Если ПодключаемыйМодуль = Неопределено Тогда
ВызватьИсключение НСтр("ru = 'Оператор Новый вернул Неопределено'");
КонецЕсли;
Исключение
ПодключаемыйМодуль = Неопределено;
ТекстОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Если ПодключаемыйМодуль = Неопределено Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не удалось создать объект ""%1"" внешней компоненты ""%2"", подключенной на клиенте
|%3,
|по причине:
|%4'"),
ИдентификаторОбъекта,
Контекст.Идентификатор,
Контекст.Местоположение,
ТекстОшибки);
КонецЕсли;
ПодключаемыеМодули.Вставить(ИдентификаторОбъекта, ПодключаемыйМодуль);
КонецЦикла;
ПодключаемыйМодуль = Новый ФиксированноеСоответствие(ПодключаемыеМодули);
КонецЕсли;
Возврат ПодключаемыйМодуль;
КонецФункции
// Продолжение процедуры ПодключитьКомпоненту.
Функция РезультатПодключенияКомпоненты()
Результат = Новый Структура;
Результат.Вставить("Подключено", Ложь);
Результат.Вставить("ОписаниеОшибки", "");
Результат.Вставить("ПодключаемыйМодуль", Неопределено);
Возврат Результат;
КонецФункции
// Продолжение процедуры УстановитьКомпоненту.
Процедура УстановитьКомпонентуПослеОтветаНаВопросОбУстановке(Ответ, Контекст) Экспорт
// Результат:
// - КодВозвратаДиалога.Да - Установить.
// - КодВозвратаДиалога.Отмена - Отклонить.
// - Неопределено - Закрыто окно.
Если Ответ = КодВозвратаДиалога.Да Тогда
УстановитьКомпонентуНачатьУстановку(Контекст);
Иначе
Результат = РезультатУстановкиКомпоненты();
ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат);
КонецЕсли;
КонецПроцедуры
// Продолжение процедуры УстановитьКомпоненту.
Процедура УстановитьКомпонентуНачатьУстановку(Контекст)
Оповещение = Новый ОписаниеОповещения(
"УстановитьКомпонентуПослеПопыткиУстановки", ЭтотОбъект, Контекст,
"УстановитьКомпонентуПриОбработкеОшибки", ЭтотОбъект);
НачатьУстановкуВнешнейКомпоненты(Оповещение, Контекст.Местоположение);
КонецПроцедуры
// Продолжение процедуры УстановитьКомпоненту.
Процедура УстановитьКомпонентуПослеПопыткиУстановки(Контекст) Экспорт
Результат = РезультатУстановкиКомпоненты();
Результат.Вставить("Установлено", Истина);
ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат);
КонецПроцедуры
// Продолжение процедуры УстановитьКомпоненту.
//
// Параметры:
// ИнформацияОбОшибке - ИнформацияОбОшибке
// СтандартнаяОбработка - Булево
// Контекст - см. ПодключитьКомпоненту.Контекст
//
Процедура УстановитьКомпонентуПриОбработкеОшибки(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт
СтандартнаяОбработка = Ложь;
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не удалось установить внешнюю компоненту ""%1"" на клиенте
|%2
|по причине:
|%3'"),
Контекст.Идентификатор,
Контекст.Местоположение,
КраткоеПредставлениеОшибки(ИнформацияОбОшибке));
Результат = РезультатУстановкиКомпоненты();
Результат.ОписаниеОшибки = ТекстОшибки;
ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат);
КонецПроцедуры
// Продолжение процедуры УстановитьКомпоненту.
Функция РезультатУстановкиКомпоненты()
Результат = Новый Структура;
Результат.Вставить("Установлено", Ложь);
Результат.Вставить("ОписаниеОшибки", "");
Возврат Результат;
КонецФункции
Процедура ПроверитьМестоположениеКомпоненты(Идентификатор, Местоположение)
Если ЭтоМакет(Местоположение) Тогда
Возврат;
КонецЕсли;
Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.ВнешниеКомпоненты") Тогда
МодульВнешниеКомпонентыСлужебныйКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("ВнешниеКомпонентыСлужебныйКлиент");
МодульВнешниеКомпонентыСлужебныйКлиент.ПроверитьМестоположениеКомпоненты(Идентификатор, Местоположение);
Иначе
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не удалось подключить внешнюю компоненту ""%1"" в клиентском приложении
|по причине:
|указано некорректное местоположение внешней компоненты
|%2'"),
Идентификатор, Местоположение);
КонецЕсли;
КонецПроцедуры
Функция ЭтоМакет(Местоположение)
Если СтрНайти(Местоположение, "/") > 0 Тогда
Возврат Ложь;
КонецЕсли;
ШагиПути = СтрРазделить(Местоположение, ".");
Количество = ШагиПути.Количество();
Если Не Количество = 2 И Не Количество = 4 Тогда
Возврат Ложь;
КонецЕсли;
Если Количество = 2 И Не ВРег(ШагиПути[0]) = "ОБЩИЙМАКЕТ" Тогда
Возврат Ложь;
КонецЕсли;
Если Количество = 4 И Не ВРег(ШагиПути[2]) = "МАКЕТ" Тогда
Возврат Ложь;
КонецЕсли;
Для каждого ШагПути Из ШагиПути Цикл
Если Не ИмяСоответствуетТребованиямИменованияСвойств(ШагПути) Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Функция ИмяСоответствуетТребованиямИменованияСвойств(Имя)
Буквы = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ";
Цифры = "1234567890";
Если Имя = "" Или СтрНайти(Буквы + "_", ВРег(Лев(Имя, 1))) = 0 Тогда
Возврат Ложь;
КонецЕсли;
Возврат СтрРазделить(ВРег(Имя), Буквы + Цифры + "_", Ложь).Количество() = 0;
КонецФункции
// Получает из кэша символическое имя внешней компоненты, если она была ранее подключена.
Функция ПолучитьСимволическоеИмяКомпонентыИзКэша(КлючОбъекта)
СимволическоеИмя = Неопределено;
КэшированныеСимволическоеИмена = ПараметрыПриложения["СтандартныеПодсистемы.ВнешниеКомпоненты.СимволическиеИмена"];
Если ТипЗнч(КэшированныеСимволическоеИмена) = Тип("ФиксированноеСоответствие") Тогда
СимволическоеИмя = КэшированныеСимволическоеИмена.Получить(КлючОбъекта);
КонецЕсли;
Возврат СимволическоеИмя;
КонецФункции
// Записывает в кэш символическое имя внешней компоненты.
Процедура ЗаписатьСимволическоеИмяКомпонентыВКэш(КлючОбъекта, СимволическоеИмя)
Соответствие = Новый Соответствие;
КэшированныеСимволическоеИмена = ПараметрыПриложения["СтандартныеПодсистемы.ВнешниеКомпоненты.СимволическиеИмена"];
Если ТипЗнч(КэшированныеСимволическоеИмена) = Тип("ФиксированноеСоответствие") Тогда
Если КэшированныеСимволическоеИмена.Получить(КлючОбъекта) <> Неопределено Тогда // Уже есть в кэше.
Возврат;
КонецЕсли;
Для каждого Элемент Из КэшированныеСимволическоеИмена Цикл
Соответствие.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
КонецЕсли;
Соответствие.Вставить(КлючОбъекта, СимволическоеИмя);
ПараметрыПриложения.Вставить("СтандартныеПодсистемы.ВнешниеКомпоненты.СимволическиеИмена",
Новый ФиксированноеСоответствие(Соответствие));
КонецПроцедуры
// Получает из кэша объект - экземпляр внешней компоненты
Функция ПолучитьОбъектКомпонентыИзКэша(КлючОбъекта)
ПодключаемыйМодуль = Неопределено;
КэшированныеОбъекты = ПараметрыПриложения["СтандартныеПодсистемы.ВнешниеКомпоненты.Объекты"];
Если ТипЗнч(КэшированныеОбъекты) = Тип("ФиксированноеСоответствие") Тогда
ПодключаемыйМодуль = КэшированныеОбъекты.Получить(КлючОбъекта);
КонецЕсли;
Возврат ПодключаемыйМодуль;
КонецФункции
// Записывает в кэш экземпляр внешней компоненты
Процедура ЗаписатьОбъектКомпонентыВКэш(КлючОбъекта, ПодключаемыйМодуль)
Соответствие = Новый Соответствие;
КэшированныеОбъекты = ПараметрыПриложения["СтандартныеПодсистемы.ВнешниеКомпоненты.Объекты"];
Если ТипЗнч(КэшированныеОбъекты) = Тип("ФиксированноеСоответствие") Тогда
Для каждого Элемент Из КэшированныеОбъекты Цикл
Соответствие.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
КонецЕсли;
Соответствие.Вставить(КлючОбъекта, ПодключаемыйМодуль);
ПараметрыПриложения.Вставить("СтандартныеПодсистемы.ВнешниеКомпоненты.Объекты",
Новый ФиксированноеСоответствие(Соответствие));
КонецПроцедуры
#КонецОбласти
#Область ВнешнееСоединение
// Продолжение процедуры ОбщегоНазначенияКлиент.ЗарегистрироватьCOMСоединитель.
Процедура ЗарегистрироватьCOMСоединительПриПроверкеРегистрации(Результат, Контекст) Экспорт
ПриложениеЗапущено = Результат.ПриложениеЗапущено;
ОписаниеОшибки = Результат.ОписаниеОшибки;
КодВозврата = Результат.КодВозврата;
ВыполнитьПерезагрузкуСеанса = Контекст.ВыполнитьПерезагрузкуСеанса;
Если ПриложениеЗапущено Тогда
Если ВыполнитьПерезагрузкуСеанса Тогда
Оповещение = Новый ОписаниеОповещения("ЗарегистрироватьCOMСоединительПриПроверкеОтветаОПерезапускеСеанса",
ОбщегоНазначенияСлужебныйКлиент, Контекст);
ТекстВопроса =
НСтр("ru = 'Для завершения перерегистрации компоненты comcntr перезапустите программу.
|Перезапустить сейчас?'");
ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет);
Иначе
Оповещение = Контекст.Оповещение;
Зарегистрировано = Истина;
ВыполнитьОбработкуОповещения(Оповещение, Зарегистрировано);
КонецЕсли;
Иначе
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Ошибка при регистрации компоненты comcntr.
|Код ошибки regsvr32: %1'"),
КодВозврата);
Если КодВозврата = 1 Тогда
ТекстСообщения = ТекстСообщения + " " + НСтр("ru = 'Ошибка разбора командной строки.'");
ИначеЕсли КодВозврата = 2 Тогда
ТекстСообщения = ТекстСообщения + " " + НСтр("ru = 'Ошибка инициализации COM библиотеки.'");
ИначеЕсли КодВозврата = 3 Тогда
ТекстСообщения = ТекстСообщения + " " + НСтр("ru = 'Ошибка загрузки модуля из COM библиотеки.'");
ИначеЕсли КодВозврата = 4 Тогда
ТекстСообщения = ТекстСообщения + " " + НСтр("ru = 'Ошибка получения адреса функции или переменной из СOM-библиотеки.'");
ИначеЕсли КодВозврата = 5 Тогда
ТекстСообщения = ТекстСообщения + " " + НСтр("ru = 'Ошибка исполнения функции регистрации.'");
Иначе
ТекстСообщения = ТекстСообщения + Символы.ПС + ОписаниеОшибки;
КонецЕсли;
ЖурналРегистрацииКлиент.ДобавитьСообщениеДляЖурналаРегистрации(
НСтр("ru = 'Регистрация компоненты comcntr'", ОбщегоНазначенияКлиент.КодОсновногоЯзыка()),
"Ошибка",
ТекстСообщения,,
Истина);
Оповещение = Новый ОписаниеОповещения("ЗарегистрироватьCOMСоединительОповеститьОбОшибке",
ОбщегоНазначенияСлужебныйКлиент, Контекст);
ПоказатьПредупреждение(Оповещение, ТекстСообщения);
КонецЕсли;
КонецПроцедуры
// Продолжение процедуры ОбщегоНазначенияКлиент.ЗарегистрироватьCOMСоединитель.
Процедура ЗарегистрироватьCOMСоединительПриПроверкеОтветаОПерезапускеСеанса(Ответ, Контекст) Экспорт
Если Ответ = КодВозвратаДиалога.Да Тогда
ПараметрыПриложения.Вставить("СтандартныеПодсистемы.ПропуститьПредупреждениеПередЗавершениемРаботыСистемы", Истина);
ЗавершитьРаботуСистемы(Истина, Истина);
Иначе
ЗарегистрироватьCOMСоединительОповеститьОбОшибке(Контекст);
КонецЕсли;
КонецПроцедуры
// Продолжение процедуры ОбщегоНазначенияКлиент.ЗарегистрироватьCOMСоединитель.
Процедура ЗарегистрироватьCOMСоединительОповеститьОбОшибке(Контекст) Экспорт
Оповещение = Контекст.Оповещение;
Если Оповещение <> Неопределено Тогда
Зарегистрировано = Ложь;
ВыполнитьОбработкуОповещения(Оповещение, Зарегистрировано);
КонецЕсли;
КонецПроцедуры
// Продолжение процедуры ОбщегоНазначенияКлиент.ЗарегистрироватьCOMСоединитель.
//
// Возвращаемое значение:
// Булево
//
Функция ЗарегистрироватьCOMСоединительДоступнаРегистрация() Экспорт
#Если ВебКлиент Или МобильныйКлиент Тогда
Возврат Ложь;
#Иначе
ПараметрыРаботыКлиентаПриЗапуске = СтандартныеПодсистемыКлиент.ПараметрыРаботыКлиентаПриЗапуске();
Возврат Не ОбщегоНазначенияКлиент.КлиентПодключенЧерезВебСервер()
И Не ПараметрыРаботыКлиентаПриЗапуске.ЭтоБазоваяВерсияКонфигурации
И Не ПараметрыРаботыКлиентаПриЗапуске.ЭтоУчебнаяПлатформа;
#КонецЕсли
КонецФункции
#КонецОбласти
#Область ТабличныйДокумент
Процедура ПродолжитьРасчетПоказателей(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда
Возврат;
КонецЕсли;
Если Результат.Статус = "Ошибка" Тогда
ВызватьИсключение Результат.КраткоеПредставлениеОшибки;
КонецЕсли;
Если Результат.Статус <> "Выполнено" Тогда
Возврат;
КонецЕсли;
РасчетныеПоказатели = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
ЗавершитьРасчетПоказателей(
ДополнительныеПараметры.Форма,
ДополнительныеПараметры.ТекущаяКоманда,
ДополнительныеПараметры.МинимальноеКоличество,
РасчетныеПоказатели);
КонецПроцедуры
Процедура ЗавершитьРасчетПоказателей(Форма, ТекущаяКоманда, МинимальноеКоличество, РасчетныеПоказатели)
Элементы = Форма.Элементы;
ЗаполнитьЗначенияСвойств(Форма, РасчетныеПоказатели);
КомандыПоказателей = КомандыПоказателей();
Для Каждого Команда Из КомандыПоказателей Цикл
ИзменитьСвойствоЭлементаРасчетаПоказателей(Элементы, Команда.Ключ, "Пометка", Ложь);
ЗначениеПоказателя = РасчетныеПоказатели[Команда.Значение];
Элементы[Команда.Значение].ФорматРедактирования = ФорматРедактированияПоказателя(ЗначениеПоказателя);
КонецЦикла;
ИзменитьСвойствоЭлементаРасчетаПоказателей(Элементы, ТекущаяКоманда, "Пометка", Истина);
ТекущийПоказатель = КомандыПоказателей[ТекущаяКоманда];
Если ТекущийПоказатель = Неопределено Тогда
Возврат;
КонецЕсли;
Если РасчетныеПоказатели.Количество >= МинимальноеКоличество Тогда
Форма.Показатель = Форма[ТекущийПоказатель];
Элементы.Показатель.ФорматРедактирования = Элементы[ТекущийПоказатель].ФорматРедактирования;
КонецЕсли;
ИзменитьСвойствоЭлементаРасчетаПоказателей(
Элементы, "КомандыВидовПоказателей", "Картинка", БиблиотекаКартинок[ТекущийПоказатель]);
ИзменитьСвойствоЭлементаРасчетаПоказателей(
Элементы, "ВыбратьПоказатель", "Картинка", БиблиотекаКартинок[ТекущийПоказатель]);
Форма.ОсновнойПоказатель = ТекущаяКоманда;
Форма.РазвернутьОбластьПоказателей = Элементы.РассчитатьВсеПоказатели.Пометка;
КонецПроцедуры
Функция ТекущаяКомандаРасчетаПоказателей(ЭлементыФормы)
Перем ТекущаяКоманда;
КомандыПоказателей = КомандыПоказателей();
Для Каждого Команда Из КомандыПоказателей Цикл
Если ЭлементыФормы[Команда.Ключ].Пометка Тогда
ТекущаяКоманда = Команда.Ключ;
Прервать;
КонецЕсли;
КонецЦикла;
Если ТекущаяКоманда = Неопределено Тогда
ТекущаяКоманда = "РассчитатьСумму";
КонецЕсли;
Возврат ТекущаяКоманда;
КонецФункции
// Определяет соответствие между командами расчета показателей и показателями.
//
// Возвращаемое значение:
// Соответствие из КлючИЗначение:
// * Ключ - Строка - имя команды;
// * Значение - Строка - имя показателя.
//
Функция КомандыПоказателей()
КомандыПоказателей = Новый Соответствие();
КомандыПоказателей.Вставить("РассчитатьСумму", "Сумма");
КомандыПоказателей.Вставить("РассчитатьКоличество", "Количество");
КомандыПоказателей.Вставить("РассчитатьСреднее", "Среднее");
КомандыПоказателей.Вставить("РассчитатьМинимум", "Минимум");
КомандыПоказателей.Вставить("РассчитатьМаксимум", "Максимум");
Возврат КомандыПоказателей;
КонецФункции
Функция ФорматРедактированияПоказателя(ЗначениеПоказателя)
ШаблонФорматаРедактирования = "ЧДЦ=%1; ЧРГ=' '; ЧН=0";
ЗначениеДробнойЧасти = Макс(ЗначениеПоказателя, -ЗначениеПоказателя) % 1;
РазрядностьДробнойЧасти = Мин(?(ЗначениеДробнойЧасти = 0, 0, СтрДлина(ЗначениеДробнойЧасти) - 2), 5);
ФорматРедактирования = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
ШаблонФорматаРедактирования, РазрядностьДробнойЧасти);
ПредставлениеПоказателя = Формат(ЗначениеПоказателя, ФорматРедактирования);
Пока РазрядностьДробнойЧасти > 0
И СтрЗаканчиваетсяНа(ПредставлениеПоказателя, "0") Цикл
ПредставлениеПоказателя = Сред(ПредставлениеПоказателя, 1, СтрДлина(ПредставлениеПоказателя) - 1);
РазрядностьДробнойЧасти = РазрядностьДробнойЧасти - 1;
КонецЦикла;
Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
ШаблонФорматаРедактирования, РазрядностьДробнойЧасти);
КонецФункции
Процедура ИзменитьСвойствоЭлементаРасчетаПоказателей(ЭлементыФормы, ИмяЭлемента, ИмяСвойства, ЗначениеСвойства)
СписокИменЭлементов = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1, %1%2", ИмяЭлемента, "Еще");
ИменаЭлементов = СтрРазделить(СписокИменЭлементов, ", ", Ложь);
Для Каждого Имя Из ИменаЭлементов Цикл
НайденныйЭлемент = ЭлементыФормы.Найти(Имя);
Если НайденныйЭлемент <> Неопределено Тогда
НайденныйЭлемент[ИмяСвойства] = ЗначениеСвойства;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
#КонецОбласти
#Область ХешСтрокиПоАлгоритмуMD5
// Возвращает хеш по алгоритму MD5 для произвольной строки.
//
// Параметры:
// Строка - Строка - произвольная строка любой длины
//
// Возвращаемое значение:
// Строка - хеш, вычисленный из строки
////
// Возвращает хеш по алгоритму MD5 для произвольной строки.
//
// Параметры:
// Строка - Строка - произвольная строка любой длины
//
// Возвращаемое значение:
// Строка - хеш, вычисленный из строки
Функция ВычислитьХешСтрокиПоАлгоритмуMD5(Знач Строка)
a = 1732584193; // 01 23 45 67; (шестнадцатеричное представление, сначала младший байт)
b = 4023233417; // 89 AB CD EF;
c = 2562383102; // FE DC BA 98;
d = 271733878; // 76 54 32 10;
X = Новый Массив(16); // X - блок данных размером 512 бит, массив из 32-битных слов
ПустойБайт = ПолучитьДвоичныеДанныеИзHexСтроки("00");
БайтОкончания = ПолучитьДвоичныеДанныеИзHexСтроки("80");
ДвоичныеДанные = ДобавитьКДвоичнымДанным(ПолучитьДвоичныеДанныеИзСтроки(Строка, "UTF-8"), БайтОкончания);
// разбиваем строку на блоки по 512 бит
МассивБлоковИзСтроки = РазделитьДвоичныеДанные(ДвоичныеДанные, 64);
ПоследнийБлок = МассивБлоковИзСтроки[МассивБлоковИзСтроки.ВГраница()];
Пока ПоследнийБлок.Размер() < 64 Цикл
ПоследнийБлок = ДобавитьКДвоичнымДанным(ПоследнийБлок, ПустойБайт);
КонецЦикла;
МассивБлоковИзСтроки[МассивБлоковИзСтроки.ВГраница()] = ПоследнийБлок;
ЧтениеДанных = Новый ЧтениеДанных(ПоследнийБлок);
ЧтениеДанных.Пропустить(55);
Если ЧтениеДанных.ПрочитатьЦелое64() <> 0 Тогда
МассивБлоковИзСтроки.Добавить(0);
КонецЕсли;
// для каждого блока производим расчет
Для НомерБлока = 0 По МассивБлоковИзСтроки.Количество() - 1 Цикл
Блок = МассивБлоковИзСтроки[НомерБлока];
Если Блок = 0 Тогда
X = Новый Массив(16);
Для НомерСлова = 0 По 15 Цикл
X[НомерСлова] = 0;
КонецЦикла;
Иначе
ЧтениеДанных = Новый ЧтениеДанных(Блок);
Для НомерСлова = 0 По 15 Цикл
Если ЧтениеДанных.ЧтениеЗавершено Тогда
X[НомерСлова] = 0;
Иначе
Слово = ЧтениеДанных.ПрочитатьЦелое32();
X[НомерСлова] = ?(Слово = Неопределено, 0, Слово);
КонецЕсли;
КонецЦикла;
КонецЕсли;
// в последний блок дописываем длину строки в битах
Если НомерБлока = МассивБлоковИзСтроки.Количество() - 1 Тогда
РазмерСтрокиВБитах = ПолучитьДвоичныеДанныеИзСтроки(Строка).Размер()* 8;
X[14] = РазмерСтрокиВБитах % Pow(2,32); // сначала младшие 4 байта
X[15] = Цел(РазмерСтрокиВБитах / Pow(2,32)) % Pow(2,64); // если длина превосходит (2^64 - 1) бит, то старшие биты откидываем
КонецЕсли;
РассчитатьБлок(a, b, c, d, X);
КонецЦикла;
Результат = ПолучитьHexСтрокуИзДвоичныхДанных(ЧислоВДвоичныеДанные(a))
+ ПолучитьHexСтрокуИзДвоичныхДанных(ЧислоВДвоичныеДанные(b))
+ ПолучитьHexСтрокуИзДвоичныхДанных(ЧислоВДвоичныеДанные(c))
+ ПолучитьHexСтрокуИзДвоичныхДанных(ЧислоВДвоичныеДанные(d));
Возврат Результат;
КонецФункции
Функция СократитьСтрокуСИпользованиемХеш(Строка, ИспользуемоеКоличествоСимволов)
Результат = Лев(Строка, ИспользуемоеКоличествоСимволов);
Результат = Результат + ВычислитьХешСтрокиПоАлгоритмуMD5(Сред(Строка, ИспользуемоеКоличествоСимволов+1));
Возврат Результат;
КонецФункции
Функция РазмерСтрокиВБайтах(Знач Строка)
Возврат ПолучитьДвоичныеДанныеИзСтроки(Строка, "UTF-8").Размер();
КонецФункции
Процедура РассчитатьБлок(a, b, c, d, X)
aa = a;
bb = b;
cc = c;
dd = d;
// раунд 1
ВыполнитьОперациюСФункциейF(a,b,c,d, X[ 0], 7, 3614090360); // 0xd76aa478 /* 1 */
ВыполнитьОперациюСФункциейF(d,a,b,c, X[ 1], 12, 3905402710); // 0xe8c7b756 /* 2 */
ВыполнитьОперациюСФункциейF(c,d,a,b, X[ 2], 17, 606105819); // 0x242070db /* 3 */
ВыполнитьОперациюСФункциейF(b,c,d,a, X[ 3], 22, 3250441966); // 0xc1bdceee /* 4 */
ВыполнитьОперациюСФункциейF(a,b,c,d, X[ 4], 7, 4118548399); // 0xf57c0faf /* 5 */
ВыполнитьОперациюСФункциейF(d,a,b,c, X[ 5], 12, 1200080426); // 0x4787c62a /* 6 */
ВыполнитьОперациюСФункциейF(c,d,a,b, X[ 6], 17, 2821735955); // 0xa8304613 /* 7 */
ВыполнитьОперациюСФункциейF(b,c,d,a, X[ 7], 22, 4249261313); // 0xfd469501 /* 8 */
ВыполнитьОперациюСФункциейF(a,b,c,d, X[ 8], 7, 1770035416); // 0x698098d8 /* 9 */
ВыполнитьОперациюСФункциейF(d,a,b,c, X[ 9], 12, 2336552879); // 0x8b44f7af /* 10 */
ВыполнитьОперациюСФункциейF(c,d,a,b, X[10], 17, 4294925233); // 0xffff5bb1 /* 11 */
ВыполнитьОперациюСФункциейF(b,c,d,a, X[11], 22, 2304563134); // 0x895cd7be /* 12 */
ВыполнитьОперациюСФункциейF(a,b,c,d, X[12], 7, 1804603682); // 0x6b901122 /* 13 */
ВыполнитьОперациюСФункциейF(d,a,b,c, X[13], 12, 4254626195); // 0xfd987193 /* 14 */
ВыполнитьОперациюСФункциейF(c,d,a,b, X[14], 17, 2792965006); // 0xa679438e /* 15 */
ВыполнитьОперациюСФункциейF(b,c,d,a, X[15], 22, 1236535329); // 0x49b40821 /* 16 */
// раунд 2
ВыполнитьОперациюСФункциейG(a,b,c,d, X[ 1], 5, 4129170786); // 0xf61e2562 /* 17 */
ВыполнитьОперациюСФункциейG(d,a,b,c, X[ 6], 9, 3225465664); // 0xc040b340 /* 18 */
ВыполнитьОперациюСФункциейG(c,d,a,b, X[11], 14, 643717713); // 0x265e5a51 /* 19 */
ВыполнитьОперациюСФункциейG(b,c,d,a, X[ 0], 20, 3921069994); // 0xe9b6c7aa /* 20 */
ВыполнитьОперациюСФункциейG(a,b,c,d, X[ 5], 5, 3593408605); // 0xd62f105d /* 21 */
ВыполнитьОперациюСФункциейG(d,a,b,c, X[10], 9, 38016083); // 0x2441453 /* 22 */
ВыполнитьОперациюСФункциейG(c,d,a,b, X[15], 14, 3634488961); // 0xd8a1e681 /* 23 */
ВыполнитьОперациюСФункциейG(b,c,d,a, X[ 4], 20, 3889429448); // 0xe7d3fbc8 /* 24 */
ВыполнитьОперациюСФункциейG(a,b,c,d, X[ 9], 5, 568446438); // 0x21e1cde6 /* 25 */
ВыполнитьОперациюСФункциейG(d,a,b,c, X[14], 9, 3275163606); // 0xc33707d6 /* 26 */
ВыполнитьОперациюСФункциейG(c,d,a,b, X[ 3], 14, 4107603335); // 0xf4d50d87 /* 27 */
ВыполнитьОперациюСФункциейG(b,c,d,a, X[ 8], 20, 1163531501); // 0x455a14ed /* 28 */
ВыполнитьОперациюСФункциейG(a,b,c,d, X[13], 5, 2850285829); // 0xa9e3e905 /* 29 */
ВыполнитьОперациюСФункциейG(d,a,b,c, X[ 2], 9, 4243563512); // 0xfcefa3f8 /* 30 */
ВыполнитьОперациюСФункциейG(c,d,a,b, X[ 7], 14, 1735328473); // 0x676f02d9 /* 31 */
ВыполнитьОперациюСФункциейG(b,c,d,a, X[12], 20, 2368359562); // 0x8d2a4c8a /* 32 */
// раунд 3
ВыполнитьОперациюСФункциейH(a,b,c,d, X[ 5], 4, 4294588738); // 0xfffa3942 /* 33 */
ВыполнитьОперациюСФункциейH(d,a,b,c, X[ 8], 11, 2272392833); // 0x8771f681 /* 34 */
ВыполнитьОперациюСФункциейH(c,d,a,b, X[11], 16, 1839030562); // 0x6d9d6122 /* 35 */
ВыполнитьОперациюСФункциейH(b,c,d,a, X[14], 23, 4259657740); // 0xfde5380c /* 36 */
ВыполнитьОперациюСФункциейH(a,b,c,d, X[ 1], 4, 2763975236); // 0xa4beea44 /* 37 */
ВыполнитьОперациюСФункциейH(d,a,b,c, X[ 4], 11, 1272893353); // 0x4bdecfa9 /* 38 */
ВыполнитьОперациюСФункциейH(c,d,a,b, X[ 7], 16, 4139469664); // 0xf6bb4b60 /* 39 */
ВыполнитьОперациюСФункциейH(b,c,d,a, X[10], 23, 3200236656); // 0xbebfbc70 /* 40 */
ВыполнитьОперациюСФункциейH(a,b,c,d, X[13], 4, 681279174); // 0x289b7ec6 /* 41 */
ВыполнитьОперациюСФункциейH(d,a,b,c, X[ 0], 11, 3936430074); // 0xeaa127fa /* 42 */
ВыполнитьОперациюСФункциейH(c,d,a,b, X[ 3], 16, 3572445317); // 0xd4ef3085 /* 43 */
ВыполнитьОперациюСФункциейH(b,c,d,a, X[ 6], 23, 76029189); // 0x4881d05 /* 44 */
ВыполнитьОперациюСФункциейH(a,b,c,d, X[ 9], 4, 3654602809); // 0xd9d4d039 /* 45 */
ВыполнитьОперациюСФункциейH(d,a,b,c, X[12], 11, 3873151461); // 0xe6db99e5 /* 46 */
ВыполнитьОперациюСФункциейH(c,d,a,b, X[15], 16, 530742520); // 0x1fa27cf8 /* 47 */
ВыполнитьОперациюСФункциейH(b,c,d,a, X[ 2], 23, 3299628645); // 0xc4ac5665 /* 48 */
// раунд 4
ВыполнитьОперациюСФункциейI(a,b,c,d, X[ 0], 6, 4096336452); // 0xf4292244 /* 49 */
ВыполнитьОперациюСФункциейI(d,a,b,c, X[ 7], 10, 1126891415); // 0x432aff97 /* 50 */
ВыполнитьОперациюСФункциейI(c,d,a,b, X[14], 15, 2878612391); // 0xab9423a7 /* 51 */
ВыполнитьОперациюСФункциейI(b,c,d,a, X[ 5], 21, 4237533241); // 0xfc93a039 /* 52 */
ВыполнитьОперациюСФункциейI(a,b,c,d, X[12], 6, 1700485571); // 0x655b59c3 /* 53 */
ВыполнитьОперациюСФункциейI(d,a,b,c, X[ 3], 10, 2399980690); // 0x8f0ccc92 /* 54 */
ВыполнитьОперациюСФункциейI(c,d,a,b, X[10], 15, 4293915773); // 0xffeff47d /* 55 */
ВыполнитьОперациюСФункциейI(b,c,d,a, X[ 1], 21, 2240044497); // 0x85845dd1 /* 56 */
ВыполнитьОперациюСФункциейI(a,b,c,d, X[ 8], 6, 1873313359); // 0x6fa87e4f /* 57 */
ВыполнитьОперациюСФункциейI(d,a,b,c, X[15], 10, 4264355552); // 0xfe2ce6e0 /* 58 */
ВыполнитьОперациюСФункциейI(c,d,a,b, X[ 6], 15, 2734768916); // 0xa3014314 /* 59 */
ВыполнитьОперациюСФункциейI(b,c,d,a, X[13], 21, 1309151649); // 0x4e0811a1 /* 60 */
ВыполнитьОперациюСФункциейI(a,b,c,d, X[ 4], 6, 4149444226); // 0xf7537e82 /* 61 */
ВыполнитьОперациюСФункциейI(d,a,b,c, X[11], 10, 3174756917); // 0xbd3af235 /* 62 */
ВыполнитьОперациюСФункциейI(c,d,a,b, X[ 2], 15, 718787259); // 0x2ad7d2bb /* 63 */
ВыполнитьОперациюСФункциейI(b,c,d,a, X[ 9], 21, 3951481745); // 0xeb86d391 /* 64 */
a = БинарнаяСумма(a, aa);
b = БинарнаяСумма(b, bb);
c = БинарнаяСумма(c, cc);
d = БинарнаяСумма(d, dd);
КонецПроцедуры
Процедура ВыполнитьОперациюСФункциейF(a, b, c, d, X, s, t)
ВыполнитьОперацию(ПобитовоеИли(ПобитовоеИ(b, c), ПобитовоеИ(ПобитовоеНе(b), d)), a, b, X, s, t);
КонецПроцедуры
Процедура ВыполнитьОперациюСФункциейG(a, b, c, d, X, s, t)
ВыполнитьОперацию(ПобитовоеИли(ПобитовоеИ(b, d), ПобитовоеИ(ПобитовоеНе(d), c)), a, b, X, s, t);
КонецПроцедуры
Процедура ВыполнитьОперациюСФункциейH(a, b, c, d, X, s, t)
ВыполнитьОперацию(ПобитовоеИсключительноеИли(ПобитовоеИсключительноеИли(b, c), d), a, b, X, s, t);
КонецПроцедуры
Процедура ВыполнитьОперациюСФункциейI(a, b, c, d, X, s, t)
ВыполнитьОперацию(ПобитовоеИсключительноеИли(ПобитовоеИли(ПобитовоеНе(d), b), c), a, b, X, s, t);
КонецПроцедуры
Процедура ВыполнитьОперацию(q, a, b, X, s, t)
a = БинарнаяСумма(ЦиклическийСдвигВлево(БинарнаяСумма(БинарнаяСумма(a, q), БинарнаяСумма(X, t)), s), b);
КонецПроцедуры
Функция ЦиклическийСдвигВлево(Число, КоличествоРазрядов)
Результат = Число;
Для НомерРазряда = 1 по КоличествоРазрядов Цикл
Бит = ПроверитьБит(Результат, 31);
Результат = ПобитовыйСдвигВлево(Результат, 1)% Pow(2,32);
Результат = УстановитьБит(Результат, 0, Бит);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ЧислоВДвоичныеДанные(Число)
Поток = Новый ПотокВПамяти(4);
ЗаписьДанных = Новый ЗаписьДанных(Поток);
ЗаписьДанных.ЗаписатьЦелое32(Число);
ЗаписьДанных.Закрыть();
ДвоичныеДанные = Поток.ЗакрытьИПолучитьДвоичныеДанные();
Возврат ДвоичныеДанные;
КонецФункции
Функция БинарнаяСумма(Аргумент1, Аргумент2)
Результат = (Аргумент1+Аргумент2)% Pow(2,32);
Возврат Результат;
КонецФункции
Функция ДобавитьКДвоичнымДанным(ДвоичныеДанные, Добавление)
МассивДвоичныхДанных = Новый Массив;
МассивДвоичныхДанных.Добавить(ДвоичныеДанные);
МассивДвоичныхДанных.Добавить(Добавление);
Возврат СоединитьДвоичныеДанные(МассивДвоичныхДанных);
КонецФункции
#КонецОбласти
#Область УстаревшиеПроцедурыИФункции
// Устарела. Используется в ОбщегоНазначенияКлиент.ПроверитьРасширениеРаботыСФайламиПодключено.
Процедура ПроверитьРасширениеРаботыСФайламиПодключеноЗавершение(РасширениеПодключено, ДополнительныеПараметры) Экспорт
Если РасширениеПодключено Тогда
ВыполнитьОбработкуОповещения(ДополнительныеПараметры.ОписаниеОповещенияОЗакрытии);
Возврат;
КонецЕсли;
ТекстСообщения = ДополнительныеПараметры.ТекстПредупреждения;
Если ПустаяСтрока(ТекстСообщения) Тогда
ТекстСообщения = НСтр("ru = 'Действие недоступно, так как не установлено расширение для работы с 1С:Предприятием.'")
КонецЕсли;
ПоказатьПредупреждение(, ТекстСообщения);
КонецПроцедуры
#КонецОбласти
#КонецОбласти