////////////////////////////////////////////////////////////////////////////////
// Подсистема "Инструменты разработчика"
// Авторское право (с) 2007-2021, Старых С.А.
// Лицензия MIT
// Разрешается повторное распространение и использование как в виде исходника так и в двоичной форме,
// с модификациями или без, при соблюдении следующих условий:
// - При повторном распространении исходного кода должно оставаться указанное выше уведомление об авторском
// праве, этот список условий и нижеследующий отказ от гарантий.
// - При повторном распространении двоичного кода должно воспроизводиться указанное выше уведомление об
// авторском праве, этот список условий и нижеследующий отказ от гарантий в документации и/или в других
// материалах, поставляемых при распространении.
//
// ЭТО ПРОГРАММА ПРЕДОСТАВЛЕНА БЕСПЛАТНО ДЕРЖАТЕЛЯМИ АВТОРСКИХ ПРАВ И/ИЛИ ДРУГИМИ СТОРОНАМИ "КАК ОНА ЕСТЬ"
// БЕЗ КАКОГО-ЛИБО ВИДА ГАРАНТИЙ, ВЫРАЖЕННЫХ ЯВНО ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ,
// ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ КОММЕРЧЕСКОЙ ЦЕННОСТИ И ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. НИ В КОЕМ СЛУЧАЕ,
// ЕСЛИ НЕ ТРЕБУЕТСЯ СООТВЕТСТВУЮЩИМ ЗАКОНОМ, ИЛИ НЕ УСТАНОВЛЕНО В УСТНОЙ ФОРМЕ, НИ ОДИН ДЕРЖАТЕЛЬ АВТОРСКИХ
// ПРАВ И НИ ОДНО ДРУГОЕ ЛИЦО, КОТОРОЕ МОЖЕТ ИЗМЕНЯТЬ И/ИЛИ ПОВТОРНО РАСПРОСТРАНЯТЬ ПРОГРАММУ, КАК БЫЛО
// РАЗРЕШЕНО ВЫШЕ, НЕ ОТВЕТСТВЕННЫ ПЕРЕД ВАМИ ЗА УБЫТКИ, ВКЛЮЧАЯ ЛЮБЫЕ ОБЩИЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ ИЛИ
// ПОСЛЕДОВАВШИЕ УБЫТКИ, ПРОИСТЕКАЮЩИЕ ИЗ ИСПОЛЬЗОВАНИЯ ИЛИ НЕВОЗМОЖНОСТИ ИСПОЛЬЗОВАНИЯ ПРОГРАММЫ (ВКЛЮЧАЯ,
// НО НЕ ОГРАНИЧИВАЯСЬ ПОТЕРЕЙ ДАННЫХ, ИЛИ ДАННЫМИ, СТАВШИМИ НЕПРАВИЛЬНЫМИ, ИЛИ ПОТЕРЯМИ ПРИНЕСЕННЫМИ ИЗ-ЗА
// ВАС ИЛИ ТРЕТЬИХ ЛИЦ, ИЛИ ОТКАЗОМ ПРОГРАММЫ РАБОТАТЬ СОВМЕСТНО С ДРУГИМИ ПРОГРАММАМИ), ДАЖЕ ЕСЛИ ТАКОЙ
// ДЕРЖАТЕЛЬ ИЛИ ДРУГОЕ ЛИЦО БЫЛИ ИЗВЕЩЕНЫ О ВОЗМОЖНОСТИ ТАКИХ УБЫТКОВ.
//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирПривилегированный Экспорт;
////////////////////////////////////////////////////////////////////////////////
// ОТЛАДКА
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
// Присваивает первому параметру второй.
// Удобно вызывать из отладчика через диалог "Вычислить выражение" (в 8.3 есть встроенный аналог) или в условной точке останова для модификации значения переменной без остановки.
//
// Параметры:
// П1 - Произвольный - Указатель на переменную, которой присваиваем значение;
// П2 - Произвольный - значение, которое присваиваем;
// ВернутьЛожь - Булево - если включено, то функция возвращает Ложь, что необходимо для использования в точке останова
//
// Возвращаемое значение:
// Значение параметра П1 после присвоения, либо Ложь.
//
Функция ПрЛкс(п1, Знач п2 = Неопределено, Знач ВернутьЛожь = Ложь) Экспорт
п1 = п2;
Если ВернутьЛожь Тогда
Возврат Ложь; // Чтобы в точке останова использовать
Иначе
Возврат п1;
КонецЕсли;
КонецФункции
// Выполняет программный код, переданный в параметре.
// Остальные параметры могут участвовать в теле этого кода. Вернуть результат можно через переменную Р.
// Удобно использовать в отладчике.
//
// Параметры:
// П1 - Произвольный - параметр1;
// П2 - Произвольный - параметр2;
// П3 - Произвольный - параметр3;
// П4 - Произвольный - параметр4;
//
// Возвращаемое значение:
// Неопределено - Не используется.
//
Функция ДуЛкс(Знач ТекстПрограммы, п1 = 0, п2 = 0, п3 = 0, п4 = 0) Экспорт
Перем Р;
Попытка
Выполнить(ТекстПрограммы);
Исключение
Возврат ОписаниеОшибки();
КонецПопытки;
Возврат Р;
КонецФункции
// На клиенте открывает консоль кода с передачей туда всех своих параметров. На сервере сразу выполняет код.
// Изменения параметров возвращаются в вызывающий контекст в модальном режиме.
//
// Параметры:
// ТекстПрограммы - Строка - программный код для передачи в консоль кода или выполнения;
// РежимОперации - Число - 0 - немодально, 1 - модально, 2 - неинтерактивно (на сервере всегда);
// СтрокаИменПараметров - Строка - имена параметров для консоли кода через запятую, если не указаны, то будут оригинальные П*;
// П* - Произвольный - параметры для использования при выполнении программного кода;
//
// Возвращаемое значение:
// Строка - описание ошибок.
//
Функция ОперироватьЛкс(Знач ТекстПрограммы = "", Знач РежимОперации = 0, СтрокаИменПараметров= "",
П1 = Null, П2 = Null, П3 = Null, П4 = Null, П5 = Null, П6 = Null, П7 = Null, П8 = Null, П9 = Null) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольКода) Тогда
Возврат СообщениеПользователюНетПраваИРЛкс();
КонецЕсли;
КонецЕсли;
#Если Сервер И Не Клиент Тогда
РежимОперации = 2;
#КонецЕсли
МассивИмен = СтрРазделитьЛкс(СтрокаИменПараметров, ",", Истина);
Если МассивИмен.Количество() > 0 Тогда
Если МассивИмен[0] = "" Тогда
МассивИмен.Удалить(0);
КонецЕсли;
КонецЕсли;
ЧислоПараметров = 9;
ПереданныеПараметры = Новый СписокЗначений;
Для Счетчик = 1 По ЧислоПараметров Цикл
ИмяПараметра = "П" + Счетчик;
ЗначениеПараметра = Вычислить(ИмяПараметра);
Если Ложь
Или ЗначениеПараметра <> Null // Опасный трюк в интерактивном режиме. Отрезает параметры, переданные, но имеющие значение Null.
Или РежимОперации = 2
Тогда
ПсевдонимПараметра = ИмяПараметра;
Если МассивИмен.Количество() > Счетчик - 1 Тогда
ПсевдонимПараметра = МассивИмен[Счетчик - 1];
КонецЕсли;
ПереданныеПараметры.Добавить(ЗначениеПараметра, ПсевдонимПараметра);
КонецЕсли;
КонецЦикла;
Если РежимОперации < 2 Тогда
#Если Клиент Тогда
ФормаОтладки = ПолучитьФормуЛкс("Обработка.ирКонсольКода.Форма", , , Новый УникальныйИдентификатор);
ФормаОтладки.мРежимРедактора = Истина;
ФормаОтладки.мСписокВнешнихПараметров = ПереданныеПараметры;
ФормаОтладки.ПараметрТекст = ТекстПрограммы;
Если РежимОперации = 0 Тогда
ФормаОтладки.Открыть();
Возврат Неопределено;
КонецЕсли;
ПолученныеПараметры = ФормаОтладки.ОткрытьМодально();
Если ПолученныеПараметры = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
#КонецЕсли
Иначе
ТекстПрограммы = ТекстПрограммы + ";";
Для Индекс = 0 По ПереданныеПараметры.Количество() - 1 Цикл
ВнешнийПараметр = ПереданныеПараметры[Индекс];
ТекстПрограммы = ВнешнийПараметр.Представление + "=" + "_АлгоритмОбъект[" + Индекс + "].Значение;" + Символы.ПС + ТекстПрограммы;
ТекстПрограммы = ТекстПрограммы + Символы.ПС + "_АлгоритмОбъект[" + Индекс + "].Значение = " + ВнешнийПараметр.Представление + ";";
КонецЦикла;
ВыполнитьАлгоритм(ТекстПрограммы, ПереданныеПараметры);
ПолученныеПараметры = ПереданныеПараметры;
КонецЕсли;
ОписаниеОшибок = "";
НовоеЗначение = Неопределено;
Для Счетчик = 1 По ЧислоПараметров Цикл
ИмяПараметра = "П" + Счетчик;
НовоеЗначение = Неопределено;
Если ПолученныеПараметры.Количество() > Счетчик - 1 Тогда
НовоеЗначение = ПолученныеПараметры[Счетчик - 1].Значение;
КонецЕсли;
Если Вычислить(ИмяПараметра) <> НовоеЗначение Тогда
Попытка
Выполнить(ИмяПараметра + " = НовоеЗначение");
Исключение
ПсевдонимПараметра = ИмяПараметра;
Если МассивИмен.Количество() > Счетчик - 1 Тогда
ПсевдонимПараметра = МассивИмен[Счетчик - 1];
КонецЕсли;
ОписаниеОшибки = "Ошибка возвращения параметра " + ПсевдонимПараметра + ": " + ОписаниеОшибки();
ОписаниеОшибок = ОписаниеОшибок + ОписаниеОшибки;
СообщитьЛкс(ОписаниеОшибки);
КонецПопытки;
КонецЕсли;
КонецЦикла;
Возврат ОписаниеОшибок;
КонецФункции
// Подготавливает строку для помещения всех переменных в структуру с целью ее дальнейшего вычисления в отладчике "Вычислить(Пер())".
// В портативном варианте не работает в управляемом приложении и на сервере.
//
// Параметры:
// ТекстПрограммы - Строка, *"" - на клиенте можно не указывать и тогда текст будет браться из буфера обмена, можно вставить имена локальных переменных выведенных в табличный документ
//
// Возвращаемое значение:
// Строка для вычисления в отладчике.
//
Функция ПерЛкс(Знач ТекстПрограммы = "") Экспорт
#Если Не ТолстыйКлиентОбычноеПриложение Тогда
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ВызватьИсключение "Такой вызов недоступен в варианте Портативный";
КонецЕсли;
#КонецЕсли
Параметры = ПолучитьПеременныеТекстаВстроенногоЯзыкаЛкс(ТекстПрограммы);
СтрокаИменПараметров = "";
Для Каждого КлючИЗначение Из Параметры Цикл
Если СтрокаИменПараметров <> "" Тогда
СтрокаИменПараметров = СтрокаИменПараметров + ", ";
КонецЕсли;
СтрокаИменПараметров = СтрокаИменПараметров + КлючИЗначение.Ключ;
КонецЦикла;
СтрокаРезультата = "Новый Структура(""" + СтрокаИменПараметров + """, " + СтрокаИменПараметров + ")";
Возврат СтрокаРезультата;
КонецФункции
// Функция получает таблицу значений из указанной временной таблицы из менеджера временных таблиц,
// либо структуру из всех входящих в запрос временных таблиц.
// Используется для просмотра временных таблиц серверного менеджера временных таблиц в отладчике.
// Параметры:
// ЗапросИлиМенеджерВременныхТаблиц - Запрос, МенеджерВременныхТаблиц
// ИменаВременныхТаблиц - Строка, *"" - имена существующих, но возможно не используемых в тексте запроса временных таблиц через запятую
// ДопустимоеЧислоСтрок - Число, *500000 - выбирать из временной таблицы не более этого числа строк
//
// Результат - ТаблицаЗначений, Структура
//
Функция ПолВТЛкс(Знач ЗапросИлиМенеджерВременныхТаблиц, Знач ИменаВременныхТаблиц = "", ДопустимоеЧислоСтрок = 500000) Экспорт
МассивИмен = ИменаИспользуемыхВЗапросеВременныхТаблицЛкс(ЗапросИлиМенеджерВременныхТаблиц, ИменаВременныхТаблиц);
Результат = Новый Структура();
Запрос = Новый Запрос;
Если ТипЗнч(ЗапросИлиМенеджерВременныхТаблиц) = Тип("Запрос") Тогда
Запрос.МенеджерВременныхТаблиц = ЗапросИлиМенеджерВременныхТаблиц.МенеджерВременныхТаблиц;
Иначе
Запрос.МенеджерВременныхТаблиц = ЗапросИлиМенеджерВременныхТаблиц;
КонецЕсли;
ТекстЗапроса = "
|ВЫБРАТЬ ПЕРВЫЕ " + XMLСтрока(ДопустимоеЧислоСтрок) + "
| *
|ИЗ
| ИмяВременнойТаблицы
|";
Для Каждого ИмяВременнойТаблицы Из МассивИмен Цикл
Если Не ЛиИмяПеременнойЛкс(ИмяВременнойТаблицы) Тогда
Продолжить;
КонецЕсли;
Если Результат.Свойство(ИмяВременнойТаблицы) Тогда
Продолжить;
КонецЕсли;
Запрос.Текст = СтрЗаменить(ТекстЗапроса, "ИмяВременнойТаблицы", ИмяВременнойТаблицы);
Попытка
РезультатЗапроса = Запрос.Выполнить();
Исключение
Продолжить;
КонецПопытки;
Результат.Вставить(ИмяВременнойТаблицы, РезультатЗапроса.Выгрузить());
КонецЦикла;
Возврат Результат;
КонецФункции
// Начать трассу в технологическом журнале. Сам технологический журнал надо заранее включить.
Функция ТехНЛкс() Экспорт
АнализТехножурнала = ирКэш.ПолучитьАнализТехножурналаЛкс();
Если АнализТехножурнала.НачатьТрассу("Отладчик") Тогда
Возврат "Трасса техножурнала начата";
Иначе
Возврат "Техножурнал не включен. Невозможно начать трассу.";
КонецЕсли;
КонецФункции
// Кончить трассу в технологическом журнале и показать ее анализ
Функция ТехКЛкс() Экспорт
АнализТехножурнала = ирКэш.ПолучитьАнализТехножурналаЛкс();
Если АнализТехножурнала.КончитьТрассу() Тогда
//АнализТехножурнала.ПоказатьТрассу();
Возврат "Трасса техножурнала кончена. Для ее анализа откройте в режиме предприятия ""Анализ техножурнала""";
Иначе
Возврат "Трасса техножурнала не была начата ранее.";
КонецЕсли;
КонецФункции
#Если Клиент Тогда
// Подготавливает строку для вызова Оперировать() в отладчике. Вызывается путем вычисления "Вычислить(Поп())".
// Изменения параметров возвращаются в вызывающий контекст.
// В портативном варианте не работает в управляемом приложении и на сервере.
//
// Параметры:
// ТекстПрограммы - Строка, *"" - программный код для передачи в консоль кода или выполнения, берется из буфера обмена если пустой;
// РежимОперации - Число - 0 - немодально, 1 - модально, 2 - неинтерактивно (на сервере всегда);
//
// Возвращаемое значение:
// Строка для вычисления в отладчике.
//
Функция ПопЛкс(Знач ТекстПрограммы = "", РежимОперации = 1) Экспорт
#Если Не ТолстыйКлиентОбычноеПриложение Тогда
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ВызватьИсключение "Такой вызов недоступен в варианте Портативный";
КонецЕсли;
#КонецЕсли
Если ПустаяСтрока(ТекстПрограммы) Тогда
ТекстПрограммы = ТекстИзБуфераОбменаОСЛкс();
КонецЕсли;
Параметры = Новый Структура();
ПолеВстроенногоЯзыка = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКлсПолеТекстаПрограммы");
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
ПолеВстроенногоЯзыка = Обработки.ирКлсПолеТекстаПрограммы.Создать();
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ПолеВстроенногоЯзыка.ИнициализироватьНеинтерактивно();
Пока Истина Цикл
ИнформацияОбОшибке = ПолеВстроенногоЯзыка.ПолучитьИнформациюОбОшибке(ТекстПрограммы);
Если ИнформацияОбОшибке = Неопределено Тогда
Прервать;
КонецЕсли;
НеопределеннаяПеременная = мПлатформа.ИмяНеопределеннойПеременнойИзИнформацииОбОшибке(ИнформацияОбОшибке);
Если Не ЗначениеЗаполнено(НеопределеннаяПеременная) Тогда
Возврат ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке);
КонецЕсли;
Если Не Параметры.Свойство(НеопределеннаяПеременная) Тогда
Параметры.Вставить(НеопределеннаяПеременная);
ПолеВстроенногоЯзыка.ДобавитьСловоЛокальногоКонтекста(НеопределеннаяПеременная);
КонецЕсли;
КонецЦикла;
СтрокаИменПараметров = "";
Для Каждого КлючИЗначение Из Параметры Цикл
Если СтрокаИменПараметров <> "" Тогда
СтрокаИменПараметров = СтрокаИменПараметров + ", ";
КонецЕсли;
СтрокаИменПараметров = СтрокаИменПараметров + КлючИЗначение.Ключ;
КонецЦикла;
НовыйТекст = ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(ТекстПрограммы);
СтрокаРезультата = "Оперировать(" + НовыйТекст + ", " + РежимОперации + ", " + """" + СтрокаИменПараметров + """, " + СтрокаИменПараметров + ")";
Возврат СтрокаРезультата;
КонецФункции
// Обертка Оперировать. Модально открывает консоль кода с передачей туда всех своих параметров.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
// Изменения параметров возвращаются в вызывающий контекст.
//
// Параметры:
// П* - Произвольный;
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОпЛкс(П1 = Null, П2 = Null, П3 = Null, П4 = Null, П5 = Null) Экспорт
Возврат ОперироватьЛкс(, Истина, , П1, П2, П3, П4, П5);
КонецФункции
// Открывает консоль кода с передачей туда структуры параметров.
// Изменения параметров возвращаются в структуру, но не в вызывающий контекст.
//
// Параметры:
// ТекстПрограммы - Строка;
// Модально - Булево - открывать окно модально;
// СтруктураПараметров - Структура - ключи соответствуют именам параметров, а значения их значениям.
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОперироватьСтруктуройЛкс(Знач ТекстПрограммы = "", Модально = Ложь, Знач СтруктураПараметров = Неопределено) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольКода) Тогда
Возврат СообщениеПользователюНетПраваИРЛкс();
КонецЕсли;
КонецЕсли;
Если Истина
И ПустаяСтрока(ТекстПрограммы)
И СтруктураПараметров <> Неопределено
И СтруктураПараметров.Количество() = 1
Тогда
Для Каждого КлючИЗначение Из СтруктураПараметров Цикл
ТекстПрограммы = КлючИЗначение.Ключ;
КонецЦикла;
КонецЕсли;
ФормаОтладки = ПолучитьФормуЛкс("Обработка.ирКонсольКода.Форма",,, Новый УникальныйИдентификатор);
//ФормаОтладки.мСписокВнешнихПараметров = СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураПараметров);
ПередаваемыеПараметры = Новый СписокЗначений;
Если СтруктураПараметров <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураПараметров Цикл
ПередаваемыеПараметры.Добавить(КлючИЗначение.Значение, КлючИЗначение.Ключ);
КонецЦикла;
ФормаОтладки.мСписокВнешнихПараметров = ПередаваемыеПараметры;
КонецЕсли;
ФормаОтладки.мРежимРедактора = Истина;
ФормаОтладки.ПараметрТекст = ТекстПрограммы;
Если Не Модально Тогда
ФормаОтладки.Открыть();
Возврат ФормаОтладки;
КонецЕсли;
ПолученныеПараметры = ФормаОтладки.ОткрытьМодально();
Если ПолученныеПараметры = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если СтруктураПараметров <> Неопределено Тогда
//ЗаполнитьЗначенияСвойств(СтруктураПараметров, ПолученныеПараметры);
Для Каждого ПолученныйПараметр Из ПолученныеПараметры Цикл
СтруктураПараметров.Вставить(ПолученныйПараметр.Представление, ПолученныйПараметр.Значение);
КонецЦикла;
КонецЕсли;
Возврат Неопределено;
КонецФункции
// Обертка ОперироватьСтруктурой. Модально открывает консоль кода с передачей туда всех своих параметров.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
// Изменения параметров возвращаются в структуру, но не в вызывающий контекст.
//
// Параметры:
// СтруктураПараметров - Структура - ключи соответствуют именам параметров, а значения их значениям.
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОпсЛкс(Знач СтруктураПараметров) Экспорт
Возврат ОперироватьСтруктуройЛкс(, Истина, СтруктураПараметров);
КонецФункции // Опс()
// Выводит в окно сообщений переданное значение вместе с типом и заданным представлением.
//
// Параметры:
// Значение - Произвольный;
// *Представление - Строка, *"" - представление наблюдаемого значения.
//
Процедура НаблюдатьЛкс(Знач Значение, Представление = "") Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирИсследовательОбъектов) Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Строка = Представление + " = " + "<" + ТипЗнч(Значение) + ">" + "[" + Значение + "]";
СообщитьЛкс(Строка);
КонецПроцедуры
#КонецЕсли
// Открывает или формирует снимок объекта для открытия в соответствующем инструменте.
// Варианты использования в зависимости от типа параметра Объект:
// Запрос, COMОбъект, HttpСоединение - открывает Запрос или ADODB.Command или ADODB.Connection в консоли запросов
// ПостроительЗапроса - открывает результирующий запрос построителя запросов в консоли запросов
// ПостроительОтчета - открывает построитель отчета в консоли построителей отчетов, откуда можно открыть результирующий запрос построителя отчета в консоли запросов
// СхемаКомпоновки - открывает схему компоновки в консоли компоновки данных, откуда можно открыть результирующие (из макета компоновки) запросы в консоли запросов
// МакетКомпоновкиДанных - открывает запросы макета компоновки в консоли запросов
// ОтчетОбъект - открывает схему и настройки компоновки отчета в консоли компоновки данных, откуда можно открыть результирующие (из макета компоновки) запросы в консоли запросов
// РегистрСведенийНаборЗаписей - открывает группировку таблицы набора записей по измерениям
//
// Параметры:
// Объект - Запрос, ПостроительЗапроса, ПостроительОтчета, СхемаКомпоновкиДанных, МакетКомпоновкиДанных, ОтчетОбъект, ADODB.Command, ADODB.Connection, HttpСоединение,
// РегистрСведенийНаборЗаписей, ДинамическийСписок, ТаблицаФормы - исследуемый объект;
// Модально - Булево - открывать окно модально, должно быть Истина для использования функции в отладчике;
// Объект2 - НастройкиКомпоновкиДанных, Строка, *Неопределено -
// если первый параметр СхемаКомпоновкиДанных, то настройки компоновки,
// если первый параметр WMI или ADODB.Connection, то текст запроса,
// если первый параметр HttpСоединение, то HttpЗапрос,
// если первый параметр Запрос, имена временных таблиц разделенных запятыми;
// ВнешниеНаборыДанных - Структура, *Неопределено - внешние наборы данных для схемы компоновки;
// ОтложеннаяОтладка - Булево - на сервере игнорируется (равно Истина), вместо открытия инструмента отладки сразу выполняется помещение
// объектов отладки во временное хранилище;
// ПорогОбрезкиВременнойТаблицы - Число, *500000 - допустимое количество строк для каждой временной таблицы запроса
// для отложенной отладки, больше этого количества строки не сохраняются, о чем сообщается в результате;
// Наименование - Строка - наименование сохраняемого объекта отложенной отладки;
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОтладитьЛкс(Знач Объект, Модально = Ложь, Знач Объект2 = Неопределено, Знач ВнешниеНаборыДанных = Неопределено,
ОтложенноеВыполнение = Ложь, ПорогОбрезкиВременнойТаблицы = 500000, выхОбъектДляОтладки = Неопределено, Наименование = "") Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольЗапросов) Тогда
Возврат СообщениеПользователюНетПраваИРЛкс();
КонецЕсли;
КонецЕсли;
#Если Не Клиент Тогда
ОтложенноеВыполнение = Истина;
#КонецЕсли
Если ирКэш.ЛиСеансТолстогоКлиентаУПЛкс() И ирКэш.ЛиПортативныйРежимЛкс() Тогда
ОтложенноеВыполнение = Истина;
КонецЕсли;
ТребоватьТипЛкс(Модально, "Модально", Тип("Булево"));
ТребоватьТипЛкс(ОтложенноеВыполнение, "ОтложенноеВыполнение", Тип("Булево"));
ТребоватьТипЛкс(ВнешниеНаборыДанных, "ВнешниеНаборыДанных", Тип("Неопределено"), Тип("Структура"));
ТребоватьТипЛкс(Объект2, "Объект2", Тип("Неопределено"), Тип("Строка"),
Тип("НастройкиКомпоновкиДанных"), Тип("HTTPЗапрос"));
Если Не ОтложенноеВыполнение Тогда
#Если Клиент Тогда
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(Объект));
Если Ложь
Или ТипЗнч(Объект) = Тип("Запрос")
Или ТипЗнч(Объект) = Тип("COMОбъект")
Тогда
КонсольЗапросов = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
Результат = КонсольЗапросов.ОткрытьДляОтладки(Объект, , , Модально, Объект2);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительЗапроса") Тогда
КонсольЗапросов = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
Результат = КонсольЗапросов.ОткрытьДляОтладки(Объект.ПолучитьЗапрос(), , , Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительОтчета") Тогда
КонсольПостроителейОтчетов = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольПостроителейОтчетов");
#Если Сервер И Не Сервер Тогда
КонсольПостроителейОтчетов = Обработки.ирКонсольПостроителейОтчетов.Создать();
#КонецЕсли
Результат = КонсольПостроителейОтчетов.ОткрытьДляОтладки(Объект, Модально);
ИначеЕсли Ложь
Или ТипЗнч(Объект) = Тип("СхемаКомпоновкиДанных")
Или ТипЗнч(Объект) = Тип("МакетКомпоновкиДанных")
Тогда
КонсольКомпоновкиДанных = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольКомпоновокДанных");
#Если Сервер И Не Сервер Тогда
КонсольКомпоновкиДанных = Обработки.ирКонсольКомпоновокДанных.Создать();
#КонецЕсли
Результат = КонсольКомпоновкиДанных.ОткрытьДляОтладки(Объект, Объект2, ВнешниеНаборыДанных, Модально);
ИначеЕсли Истина
И ОбъектМД <> Неопределено
И Метаданные.Отчеты.Индекс(ОбъектМД) <> -1
Тогда
КонсольКомпоновкиДанных = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольКомпоновокДанных");
#Если Сервер И Не Сервер Тогда
КонсольКомпоновкиДанных = Обработки.ирКонсольКомпоновокДанных.Создать();
Объект = КонсольКомпоновкиДанных;
#КонецЕсли
Если Объект.СхемаКомпоновкиДанных = Неопределено Тогда
Возврат "У отчета не установлена схема компоновки данных";
КонецЕсли;
Результат = КонсольКомпоновкиДанных.ОткрытьДляОтладки(Объект.СхемаКомпоновкиДанных, Объект.КомпоновщикНастроек.ПолучитьНастройки(), ВнешниеНаборыДанных, Модально);
ИначеЕсли Истина
И ОбъектМД <> Неопределено
И Метаданные.РегистрыСведений.Индекс(ОбъектМД) <> -1
Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
Объект = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаРедактирования = мПлатформа.ПолучитьФорму("ТаблицаЗначений");
ФормаРедактирования.НачальноеЗначениеВыбора = Объект.Выгрузить();
ФормаРедактирования.Открыть();
ОткрытьГруппировкуТабличногоПоляЛкс(ФормаРедактирования.ЭлементыФормы.ПолеТаблицы,, СтрСоединитьЛкс(ЗначенияСвойстваКоллекцииЛкс(Объект.Метаданные().Измерения)));
ИначеЕсли ТипЗнч(Объект) = Тип("HTTPСоединение") Тогда
КонсольHttpЗапросов = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольHttpЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольHttpЗапросов = Обработки.ирКонсольHttpЗапросов.Создать();
#КонецЕсли
Результат = КонсольHttpЗапросов.ОткрытьДляОтладки(Объект, Объект2, Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("ДинамическийСписок") Тогда
Возврат "Отладка динамического списка доступна только на сервере";
Иначе
//Возврат "Не поддерживаемый тип """ + ТипЗнч(Объект) + """ первого параметра";
ИсЛкс(Объект,, ОтложенноеВыполнение);
КонецЕсли;
#КонецЕсли
Иначе
СтруктураПараметров = СтруктураОбъектаДляОтладкиЛкс(Объект, Объект2, ВнешниеНаборыДанных, ПорогОбрезкиВременнойТаблицы);
Если СтруктураПараметров.Объект <> Неопределено Тогда
Результат = ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки, Наименование);
Иначе
Результат = ИсЛкс(Объект,, ОтложенноеВыполнение);
Если Результат = Неопределено Тогда
Результат = "Отложенная отладка объекта типа """ + ТипЗнч(Объект) + """ не поддерживается";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СтруктураОбъектаДляОтладкиЛкс(Знач Объект, Знач Объект2, Знач ВнешниеНаборыДанных, Знач ПорогОбрезкиВременнойТаблицы = 500000) Экспорт
ТребоватьТипЛкс(ВнешниеНаборыДанных, "ВнешниеНаборыДанных", Тип("Неопределено"), Тип("Структура"));
ТребоватьТипЛкс(Объект2, "НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц", Тип("Неопределено"), Тип("Строка"), Тип("НастройкиКомпоновкиДанных"), Тип("HTTPЗапрос"));
СтруктураПараметров = Новый Структура("Объект, НастройкаКомпоновки, ВнешниеНаборыДанных, ТипОбъекта");
Результат = Неопределено;
Если ТипЗнч(Объект) = Тип("Запрос") Тогда
#Если Сервер И Не Сервер Тогда
Объект = Новый Запрос;
#КонецЕсли
СтруктураЗапроса = Новый Структура("Текст, Параметры, ВременныеТаблицы, ТипЗапроса");
ВременныеТаблицы = Неопределено;
Если Объект.МенеджерВременныхТаблиц <> Неопределено Тогда
ВременныеТаблицы = ПолВТЛкс(Объект, Объект2, ПорогОбрезкиВременнойТаблицы);
Результат = "";
Для Каждого КлючИЗначение Из ВременныеТаблицы Цикл
Если Результат <> "" Тогда
Результат = Результат + ", ";
КонецЕсли;
Если КлючИЗначение.Значение.Количество() = ПорогОбрезкиВременнойТаблицы Тогда
Результат = Результат + КлючИЗначение.Ключ;
КонецЕсли;
КонецЦикла;
Если Результат <> "" Тогда
Результат = "Временные таблицы " + Результат + " были сохранены частично!";
КонецЕсли;
СтруктураЗапроса.ВременныеТаблицы = ВременныеТаблицы;
КонецЕсли;
СтруктураЗапроса.Текст = Объект.Текст;
СтруктураЗапроса.ТипЗапроса = "Обычный";
СтруктураЗапроса.Параметры = ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(Объект.Параметры);
СтруктураПараметров.Объект = СтруктураЗапроса;
СтруктураПараметров.ТипОбъекта = "Запрос";
ИначеЕсли ТипЗнч(Объект) = Тип("COMОбъект") Тогда
Попытка
Пустышка = Объект.CommandText;
ЭтоКомандаADO = Истина;
Исключение
ЭтоКомандаADO = Ложь;
Попытка
Пустышка = Объект.ConnectionString;
ЭтоСоединениеADO = Истина;
Исключение
ЭтоСоединениеADO = Ложь;
КонецПопытки;
КонецПопытки;
СтруктураЗапроса = Новый Структура("Текст, Параметры, ВременныеТаблицы, ТипЗапроса");
Если Ложь
Или ЭтоКомандаADO
Или ЭтоСоединениеADO
Тогда
Если ЭтоСоединениеADO Тогда
СтруктураЗапроса.Текст = Объект2;
Иначе
СтруктураЗапроса.Текст = Объект.CommandText;
// Антибаг платформы 8.2.18. Некорректная сериализация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СтруктураЗапроса.Параметры = КопияОбъектаЛкс(Объект.Параметры);
СтруктураЗапроса.Параметры = Новый Структура();
Для Каждого Parameter Из Объект.Parameters Цикл
КлючПараметра = Parameter.Name;
Если Не ЛиИмяПеременнойЛкс(КлючПараметра) Тогда
КлючПараметра = "_" + КлючПараметра;
КонецЕсли;
Если Не ЛиИмяПеременнойЛкс(КлючПараметра) Тогда
КлючПараметра = КлючПараметра + XMLСтрока(СтруктураЗапроса.Параметры.Количество());
КонецЕсли;
Если СтруктураЗапроса.Параметры.Свойство(КлючПараметра) Тогда
ВызватьИсключение "Не удалось назначить параметру уникальное имя";
КонецЕсли;
СтруктураЗапроса.Параметры.Вставить(КлючПараметра, ЗначениеВСтрокуВнутр(Parameter.Value));
КонецЦикла;
КонецЕсли;
СтруктураЗапроса.ТипЗапроса = "ADO";
//ВременныеТаблицы = Неопределено;
//ВременныеТаблицы = ПолВТ(Объект, ПорогОбрезкиВременнойТаблицы);
//Результат = "";
//Для Каждого КлючИЗначение Из ВременныеТаблицы Цикл
// Если Результат <> "" Тогда
// Результат = Результат + ", ";
// КонецЕсли;
// Если КлючИЗначение.Значение.Количество() = ПорогОбрезкиВременнойТаблицы Тогда
// Результат = Результат + КлючИЗначение.Ключ;
// КонецЕсли;
//КонецЦикла;
//Если Результат <> "" Тогда
// Результат = Результат + Символы.ПС + "Временные таблицы " + Результат + " были сохранены частично!";
//КонецЕсли;
//СтруктураЗапроса.ВременныеТаблицы = ВременныеТаблицы;
СтруктураПараметров.Объект = СтруктураЗапроса;
Иначе
СтруктураЗапроса.ТипЗапроса = "WQL";
СтруктураЗапроса.Текст = Объект2;
КонецЕсли;
СтруктураПараметров.ТипОбъекта = "COMОбъект";
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительЗапроса") Тогда
СтруктураЗапроса = Новый Структура("Текст, Параметры");
ЗаполнитьЗначенияСвойств(СтруктураЗапроса, Объект.ПолучитьЗапрос());
СтруктураЗапроса.Параметры = ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(СтруктураЗапроса.Параметры);
СтруктураПараметров.Объект = СтруктураЗапроса;
СтруктураПараметров.ТипОбъекта = "Запрос";
ИначеЕсли ТипЗнч(Объект) = Тип("МакетКомпоновкиДанных") Тогда
СтруктураПараметров.Вставить("Объект", Объект);
СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных);
СтруктураПараметров.ТипОбъекта = "МакетКомпоновкиДанных";
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительОтчета") Тогда
Результат = "Отложенная отладка построителя отчета не поддерживается";
ИначеЕсли ТипЗнч(Объект) = Тип("СхемаКомпоновкиДанных") Тогда
СтруктураПараметров.Вставить("Объект", Объект);
СтруктураПараметров.Вставить("НастройкаКомпоновки", Объект2);
СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных);
СтруктураПараметров.ТипОбъекта = "СхемаКомпоновкиДанных";
ИначеЕсли ТипЗнч(Объект) = Тип("HTTPСоединение") Тогда
#Если Сервер И Не Сервер Тогда
Объект = Новый HttpСоединение;
#КонецЕсли
ИменаСвойств = "Сервер, Порт, Пользователь, Пароль, Таймаут, Защищенное, ИспользоватьАутентификациюОС";
СтруктураСоединения = Новый Структура(ИменаСвойств);
ЗаполнитьЗначенияСвойств(СтруктураСоединения, Объект, ИменаСвойств);
Если ТипЗнч(Объект2) = Тип("HTTPЗапрос") Тогда
#Если Сервер И Не Сервер Тогда
Объект2 = Новый HTTPЗапрос;
#КонецЕсли
ИменаСвойств = "АдресРесурса, Заголовки";
СтруктураЗапроса = Новый Структура(ИменаСвойств);
ЗаполнитьЗначенияСвойств(СтруктураЗапроса, Объект2, ИменаСвойств);
СтруктураЗапроса.Вставить("ТелоДвоичныеДанные", Объект2.ПолучитьТелоКакДвоичныеДанные());
КонецЕсли;
СтруктураПараметров.Вставить("Объект", СтруктураСоединения);
СтруктураПараметров.Вставить("НастройкаКомпоновки", СтруктураЗапроса);
СтруктураПараметров.ТипОбъекта = "HttpСоединение";
ИначеЕсли ТипЗнч(Объект) = Тип("ДинамическийСписок") Тогда
Если НаКлиентеИДоступенСерверныйВызовЛкс() Тогда
Возврат "Отладка динамического списка доступна только на сервере";
КонецЕсли;
НастройкаКомпоновки = Неопределено;
Схема = Неопределено;
ПолучитьСхемуИНастройкиКомпоновкиДинамическогоСпискаЛкс(Объект, НастройкаКомпоновки, Схема);
СтруктураПараметров.Вставить("Объект", Схема);
СтруктураПараметров.Вставить("НастройкаКомпоновки", НастройкаКомпоновки);
СтруктураПараметров.ТипОбъекта = "СхемаКомпоновкиДанных";
ИначеЕсли ТипЗнч(Объект) = Тип("ТаблицаФормы") Тогда
Если НаКлиентеИДоступенСерверныйВызовЛкс() Тогда
Возврат "Отладка динамического списка доступна только на сервере";
КонецЕсли;
Схема = Объект.ПолучитьИсполняемуюСхемуКомпоновкиДанных();
НастройкаКомпоновки = Объект.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();
СтруктураПараметров.Вставить("Объект", Схема);
СтруктураПараметров.Вставить("НастройкаКомпоновки", НастройкаКомпоновки);
СтруктураПараметров.ТипОбъекта = "СхемаКомпоновкиДанных";
Иначе
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(Объект));
Если ОбъектМД <> Неопределено Тогда
Если Метаданные.Отчеты.Индекс(ОбъектМД) <> -1 Тогда
Если Объект.СхемаКомпоновкиДанных = Неопределено Тогда
Возврат "У отчета не установлена схема компоновки данных";
Иначе
СтруктураПараметров.Вставить("Объект", Объект.СхемаКомпоновкиДанных);
СтруктураПараметров.Вставить("НастройкаКомпоновки", Объект.КомпоновщикНастроек.ПолучитьНастройки());
СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных);
СтруктураПараметров.ТипОбъекта = "СхемаКомпоновкиДанных";
КонецЕсли;
ИначеЕсли Метаданные.РегистрыСведений.Индекс(ОбъектМД) <> -1 Тогда
СтруктураПараметров.Вставить("Объект", Объект);
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтруктураПараметров.Вставить("ТипОперации", "Отладить");
СтруктураПараметров.Вставить("ИмяПользователя", ИмяПользователя());
Возврат СтруктураПараметров;
КонецФункции
Функция СнимокОбъектаДляОтладкиЛкс(Знач Объект, Знач Объект2 = Неопределено, Знач ВнешниеНаборыДанных = Неопределено,
Знач ПорогОбрезкиВременнойТаблицы = 500000) Экспорт
СтруктураПараметров = СтруктураОбъектаДляОтладкиЛкс(Объект, Объект2, ВнешниеНаборыДанных, ПорогОбрезкиВременнойТаблицы);
Результат = ОбъектВСтрокуXMLЛкс(СтруктураПараметров);
Возврат Результат;
КонецФункции
// Обертка ирОбщий.ОтладитьЛкс(). Открывает или формирует снимок объекта для открытия в соответствующем инструменте.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
Функция ОтЛкс(Знач Объект, Знач Объект2 = Неопределено, Знач ВнешниеНаборыДанных = Неопределено, ОтложеннаяОтладка = Ложь, ПорогОбрезкиВременнойТаблицы = 500000, Наименование = "") Экспорт
Результат = ОтладитьЛкс(Объект, Истина, Объект2, ВнешниеНаборыДанных, ОтложеннаяОтладка, ПорогОбрезкиВременнойТаблицы,, Наименование);
Возврат Результат;
КонецФункции
// Открывает или формирует снимок объекта для открытия в исследователе объектов.
//
// Параметры:
// Объект - Произвольный, *Неопределено - объект, который будет исследован;
// Модально - Булево - открывать окно модально;
// КакКоллекцию - Булево, *Ложь - исследовать как коллекцию вместо объекта;
// ОтложеннаяОтладка - Булево - на сервере игнорируется (равно Истина), вместо открытия инструмента отладки сразу выполняется помещение
// объектов отладки во временное хранилище;
// ТекущееВыражение - Строка - исходное выражение
//
// Возвращаемое значение:
// Сам объект.
//
Функция ИсследоватьЛкс(Знач Объект = Неопределено, Знач Модально = Ложь, Знач КакКоллекцию = Ложь, Знач ОтложенноеВыполнение = Ложь, Знач ТекущееВыражение = Неопределено, Знач ИмяТекущегоСвойства = "",
Знач ПрикрепитьОкно = Ложь) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирИсследовательОбъектов) Тогда
Возврат СообщениеПользователюНетПраваИРЛкс();
КонецЕсли;
КонецЕсли;
#Если Не Клиент Тогда
ОтложенноеВыполнение = Истина;
#КонецЕсли
Если ирКэш.ЛиСеансТолстогоКлиентаУПЛкс() И ирКэш.ЛиПортативныйРежимЛкс() Тогда
ОтложенноеВыполнение = Истина;
КонецЕсли;
ТребоватьТипЛкс(Модально, "Модально", Тип("Булево"));
ТребоватьТипЛкс(КакКоллекцию, "КакКоллекцию", Тип("Булево"));
ТребоватьТипЛкс(ОтложенноеВыполнение, "ОтложенноеВыполнение", Тип("Булево"));
Если Не ОтложенноеВыполнение Тогда
ИсследовательОбъектов = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИсследовательОбъектов");
#Если Сервер И Не Сервер Тогда
ИсследовательОбъектов = Обработки.ирИсследовательОбъектов.Создать();
#КонецЕсли
Если КакКоллекцию Тогда
Результат = ИсследовательОбъектов.ИсследоватьКоллекцию(Объект, Модально);
Иначе
Результат = ИсследовательОбъектов.ИсследоватьОбъект(Объект, Модально, ТекущееВыражение, ИмяТекущегоСвойства, ПрикрепитьОкно);
КонецЕсли;
Если Результат <> Неопределено Тогда
Объект = Результат;
КонецЕсли;
Иначе
Если ТипЗнч(Объект) = Тип("ДанныеФормыДерево") Тогда
Объект = ДанныеФормыВЗначение(Объект, Тип("ДеревоЗначений"));
ИначеЕсли ТипЗнч(Объект) = Тип("ДанныеФормыКоллекция") Тогда
Объект = ДанныеФормыВЗначение(Объект, Тип("ТаблицаЗначений"));
КонецЕсли;
СтруктураПараметров = Новый Структура("Объект, Модально, КакКоллекцию, СериализацияФабрикой", Объект, Модально, КакКоллекцию, Ложь);
Наименование = "" + Объект;
Если Истина
И ТипЗнч(Объект) <> Тип("ОбъектXDTO")
И ТипЗнч(Объект) <> Тип("ЗначениеXDTO")
Тогда
Попытка
ОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(СтруктураПараметров);
Исключение
ОбъектXDTO = Неопределено;
КонецПопытки;
Иначе
СтруктураПараметров.СериализацияФабрикой = Истина;
Попытка
Объект = ОбъектВСтрокуXMLЛкс(Объект);
ОбъектXDTO = Объект;
Исключение
ОбъектXDTO = Неопределено;
КонецПопытки;
КонецЕсли;
Если ОбъектXDTO = Неопределено Тогда
ОбъектXDTO = Истина;
Объект = ЗначениеВСтрокуВнутр(Объект);
СтруктураПараметров.СериализацияФабрикой = "Внутр";
КонецЕсли;
Если ОбъектXDTO <> Неопределено Тогда
СтруктураПараметров.Вставить("ТипОперации", "Исследовать");
СтруктураПараметров.Вставить("Объект", Объект);
выхОбъектДляОтладки = Неопределено;
Результат = ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки, Наименование);
Иначе
Результат = "Отложенная отладка объекта такого типа не поддерживается";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СнимокОбъектаЛкс(Объект) Экспорт
Если ЛиТипОбъектаБДЛкс(ТипЗнч(Объект)) Тогда
ПолноеИмяМД = Объект.Метаданные().ПолноеИмя();
СтруктураОбъекта = ОбъектБДПоКлючуЛкс(ПолноеИмяМД,,, Ложь, Истина);
ИмитаторОбъекта = СтруктураОбъекта.Методы;
Если ЛиТипИмитатораОбъектаЛкс(ТипЗнч(ИмитаторОбъекта)) Тогда
#Если Сервер И Не Сервер Тогда
ИмитаторОбъекта = Обработки.ирИмитаторСсылочныйОбъект.Создать();
#КонецЕсли
ИмитаторОбъекта.Конструктор(Объект);
Результат = Новый Структура;
Результат.Вставить("Снимок", ИмитаторОбъекта.Снимок());
Результат.Вставить("ПолноеИмяМД", ПолноеИмяМД);
КонецЕсли;
//Иначе
// Большого смысла пока не увидел, т.к. обратное преобразование не оформлено отдельной функцией
// Результат = СтруктураОбъектаДляОтладкиЛкс(Объект);
КонецЕсли;
Если Результат = Неопределено Тогда
Результат = ЗначениеВСтрокуВнутр(Объект);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОбъектИзСнимкаЛкс(Снимок) Экспорт
Если ТипЗнч(Снимок) = Тип("Структура") Тогда
СтруктураОбъекта = ОбъектБДПоКлючуЛкс(Снимок.ПолноеИмяМД,,, Ложь, Истина);
ИмитаторОбъекта = СтруктураОбъекта.Методы;
Если ЛиТипИмитатораОбъектаЛкс(ТипЗнч(ИмитаторОбъекта)) Тогда
Результат = ИмитаторОбъекта;
#Если Сервер И Не Сервер Тогда
Результат = Обработки.ирИмитаторСсылочныйОбъект.Создать();
#КонецЕсли
Результат.ЗагрузитьСнимок(Снимок.Снимок);
КонецЕсли;
КонецЕсли;
Если Результат = Неопределено Тогда
Результат = ЗначениеИзСтрокиВнутрЛкс(Снимок);
КонецЕсли;
Возврат Результат;
КонецФункции
// Обертка Исследовать. Модально открывает объект в исследователе объектов
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
Функция ИсЛкс(Знач Объект = Неопределено, КакКоллекцию = Ложь, ОтложенноеВыполнение = Ложь) Экспорт
Возврат ИсследоватьЛкс(Объект, Истина, КакКоллекцию, ОтложенноеВыполнение);
КонецФункции
// Возвращает текст из файла
Функция ФайлЛкс(Знач ИмяФайла, Знач Кодировка = "UTF-8") Экспорт
Текст = Новый ТекстовыйДокумент;
Попытка
Текст.Прочитать(ИмяФайла, Кодировка);
Результат = Текст.ПолучитьТекст();
Исключение
Результат = ОписаниеОшибки();
КонецПопытки;
Возврат Результат;
КонецФункции
// Удаляет все элементы коллекции с возможностью оставить один элемент.
// Параметры:
// Коллекция - - коллекция из которой надо удалить элементы;
// ОставитьЭлементИлиИндекс - Число, Строка, *Неопределено - при Число Или Строка оставляется элемент с таким ключом (0 - первый), иначе удаляется все
Функция СокрКолЛкс(Знач Коллекция, Знач ОставитьЭлементИлиКлюч = Неопределено, Знач ОчищатьЕслиКлючНеНайден = Ложь) Экспорт
Если Ложь
Или ТипЗнч(ОставитьЭлементИлиКлюч) = Тип("Число")
Или ТипЗнч(ОставитьЭлементИлиКлюч) = Тип("Строка")
Тогда
Если ОставитьЭлементИлиКлюч = 0 Тогда
ОставитьЭлемент = "<Первый>";
Иначе
Попытка
ОставитьЭлемент = Коллекция[ОставитьЭлементИлиКлюч];
Исключение
Если ОчищатьЕслиКлючНеНайден Тогда
ОставитьЭлемент = Неопределено;
КонецЕсли;
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если ОставитьЭлемент = Неопределено Тогда
Попытка
Коллекция.Очистить();
Возврат Истина;
Исключение
ОставитьЭлемент = Неопределено;
КонецПопытки;
КонецЕсли;
МассивКУдалению = Новый Массив;
Для Каждого Элемент Из Коллекция Цикл
Если Истина
И ОставитьЭлемент <> Неопределено
И (Ложь
Или ОставитьЭлемент = "<Первый>"
Или ОставитьЭлемент = Элемент)
Тогда
ОставитьЭлемент = Элемент;
Продолжить;
КонецЕсли;
Если Ложь
Или ТипЗнч(Коллекция) = Тип("Структура")
Или ТипЗнч(Коллекция) = Тип("Соответствие")
Тогда
МассивКУдалению.Добавить(Элемент.Ключ);
Иначе
МассивКУдалению.Добавить(Элемент);
КонецЕсли;
КонецЦикла;
Для Каждого УдаляемыйЭлемент Из МассивКУдалению Цикл
Коллекция.Удалить(УдаляемыйЭлемент);
КонецЦикла;
Возврат Коллекция;
КонецФункции
// Проверяет что переданное значение отличается от предыдущего переданного с тем же именем.
// Полезно использовать в условных точках останова например для остановки в том проходе цикла, в котором изменяется значение выражения.
// https://www.hostedredmine.com/issues/892539
// Параметры:
// Значение - Произвольный - проверяемое значение. Все типы, кроме ссылок БД, преобразуются к строке через функцию РасширенноеПредставлениеЗначенияЛкс(), которая также используется при отображении значений в консоли кода.
// ИмяЗначения - Строка, Число, *"" - имя/идентификатор значения
// НужноеСтароеЗначение - Произвольный, * - игнорировать все старые значения кроме этого
// НужноеНовоеЗначение - Произвольный, * - игнорировать все новые значения кроме этого
// Результат:
// Булево - Истина, если значение изменилось
Функция ИзмЛкс(Знач Значение, Знач ИмяЗначения = "", Знач НужноеСтароеЗначение = "фйъх13м9", Знач НужноеНовоеЗначение = "фйъх13м9") Экспорт
ИмяЗначения = "_" + XMLСтрока(ИмяЗначения);
СтруктураСтарыхЗначений = ирКэш.ЗначенияДляПроверкиИзмененияЛкс();
Если Не ЛиСсылкаНаОбъектБДЛкс(Значение, Ложь) Тогда
Значение = Лев(РасширенноеПредставлениеЗначенияЛкс(Значение), 1000); // Чтобы избежать залипания в кэше больших объектов
КонецЕсли;
Если СтруктураСтарыхЗначений.Свойство(ИмяЗначения) Тогда
СтароеЗначение = СтруктураСтарыхЗначений[ИмяЗначения];
Результат = СтароеЗначение <> Значение;
Иначе
Результат = Ложь;
КонецЕсли;
СтруктураСтарыхЗначений.Вставить(ИмяЗначения, Значение);
Если Результат Тогда
Если НужноеСтароеЗначение <> "фйъх13м9" Тогда
Если Не ЛиСсылкаНаОбъектБДЛкс(НужноеСтароеЗначение, Ложь) Тогда
НужноеСтароеЗначение = Лев(РасширенноеПредставлениеЗначенияЛкс(НужноеСтароеЗначение), 1000);
КонецЕсли;
Если НужноеСтароеЗначение <> СтароеЗначение Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
Если НужноеНовоеЗначение <> "фйъх13м9" Тогда
Если Не ЛиСсылкаНаОбъектБДЛкс(НужноеНовоеЗначение, Ложь) Тогда
НужноеНовоеЗначение = Лев(РасширенноеПредставлениеЗначенияЛкс(НужноеНовоеЗначение), 1000);
КонецЕсли;
Если НужноеНовоеЗначение <> Значение Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Функция создает структуру из переданного объекта, добавляя к свойствам, содержащим коллекции, свойство "<ИмяКолонки>_Инфо" с представлением вложенной коллекции, включающим количество ее элементов.
//
// Параметры:
// Объект - Произвольный -
//
// Возвращаемое значение:
// - Структура
//
Функция СткЛкс(Объект) Экспорт
Возврат СтруктураИзОбъектаЛкс(Объект,,, Истина);
КонецФункции
// Функция создает таблицу значений из переданной коллекции, добавляя
// 1. К колонкам, содержащим коллекции, колонку "<ИмяКолонки>_Инфо" с представлением вложенной коллекции, включающем количеством ее элементов.
// 2. К колонкам, содержащим структуры или ссылки на строки таблицы/дерева, колонки "<ИмяКолонки>_<ИмяВложенногоСвойства>" со значениями свойств вложенных объектов
//
// Параметры:
// Объект - Произвольный - произвольная коллекция
// АнализХранилищЗначений - Булево, *Ложь - нужно ли получать представления содержимого хранилищ значений, увеличивает длительность
// МаксЧислоЭлементов - Число, *0 - ограничить число строк в таблице значений, 0 - не ограничивать
// Сортировка - Строка, *"" - строка упорядочивания, выполняется после контроля МаксЧислоЭлементов
//
// Возвращаемое значение:
// - ТаблицаЗначений
//
Функция КолЛкс(Объект, АнализХранилищЗначений = Ложь, МаксЧислоЭлементов = 0, Сортировка = "") Экспорт
Возврат ирОбщий.ТаблицаЗначенийИзКоллекцииЛкс(Объект,,,,,,, Истина, АнализХранилищЗначений, МаксЧислоЭлементов, Сортировка);
КонецФункции
// Формирует строку условия точки останова по значениям примитивных свойств объекта.
// https://www.hostedredmine.com/issues/938460
// Параметры:
// Объект - Произвольный - объект, значения свойств которого нужно проверять, или проверяемое значение примитивного типа
// ИмяПеременной - Строка - имя переменной объекта в контексте проверки условия
// Результат:
// Строка - условие для точки останова, где свойства следуют в алфавитном порядке
Функция УслЛкс(Объект, ИмяПеременной, МаксДлинаСтроки = 20, МаксДробныхЗнаков = 6) Экспорт
Структура = СтруктураИзОбъектаЛкс(Объект);
#Если Сервер И Не Сервер Тогда
Структура = Новый Структура;
#КонецЕсли
Результат = КодПроверкиЗначенияВыраженияЛкс(Объект, ИмяПеременной, МаксДлинаСтроки, МаксДробныхЗнаков);
Если Не ЗначениеЗаполнено(Результат) Тогда
Результат = Новый СписокЗначений;
Для Каждого КлючИЗначение Из Структура Цикл
ПроверяемоеВыражение = ИмяПеременной + "." + КлючИЗначение.Ключ;
ПроверяемоеЗначение = КлючИЗначение.Значение;
УсловиеСвойства = КодПроверкиЗначенияВыраженияЛкс(ПроверяемоеЗначение, ПроверяемоеВыражение, МаксДлинаСтроки, МаксДробныхЗнаков);
Если Не ЗначениеЗаполнено(УсловиеСвойства) Тогда
Продолжить;
КонецЕсли;
Результат.Добавить(УсловиеСвойства, КлючИЗначение.Ключ);
КонецЦикла;
Результат.СортироватьПоПредставлению();
Результат = СтрСоединитьЛкс(Результат.ВыгрузитьЗначения(), " И ");
КонецЕсли;
Возврат Результат;
КонецФункции
#КонецЕсли
// ОТЛАДКА
////////////////////////////////////////////////////////////////////////////////
// Результат: Число
Функция НомерВерсииПлатформыЛкс(Знач СтрокаВерсии, Знач ВключаяНомерСборки = Ложь) Экспорт
Фрагменты = ирОбщий.СтрРазделитьЛкс(СтрокаВерсии);
#Если Сервер И Не Сервер Тогда
Фрагменты = Новый Массив;
#КонецЕсли
Для Счетчик = Фрагменты.Количество() По 4 Цикл
Фрагменты.Добавить("0");
КонецЦикла;
Результат = Число(Фрагменты[0]) * 100 * 1000 + Число(Фрагменты[1]) * 1000 + Число(Фрагменты[2]); // 6 цифр
Если ВключаяНомерСборки Тогда
Результат = Результат * 10000 + Число(Фрагменты[3]); // 10 цифр
КонецЕсли;
Возврат Результат;
КонецФункции
Функция АдресОсновногоСайтаЛкс() Экспорт
Возврат "devtool1c.ucoz.ru";
КонецФункции
Функция АдресСайтаЗадачЛкс() Экспорт
Возврат "https://www.hostedredmine.com/projects/devtool1c";
КонецФункции
Функция СообщениеПользователюНетПраваИРЛкс() Экспорт
Возврат "Нет права использования функции. Добавьте пользователю """ + ИмяПользователя() + """ роль из подсистемы ""Инструменты разработчика"".";
КонецФункции // РП()
// Выполняет текст алгоритма. Возращается результат через переменную "Результат".
//
// Параметры:
// ТекстДляВыполнения - Строка;
// _АлгоритмОбъект - СправочникОбъект
// *СтруктураПараметров - Структура, *Неопределено.
//
Функция ВыполнитьАлгоритм(_ТекстДляВыполнения, _АлгоритмОбъект = Null, _Режим = Null,
_П0 = Null, _П1 = Null, _П2 = Null, _П3 = Null, _П4 = Null, _П5 = Null, _П6 = Null, _П7 = Null, _П8 = Null, _П9 = Null) Экспорт
Перем Результат;
Выполнить(_ТекстДляВыполнения);
Возврат Результат;
КонецФункции
Процедура ВыполнитьАлгоритмБезРезультата(_ТекстДляВыполнения) Экспорт
Выполнить(_ТекстДляВыполнения);
КонецПроцедуры
Функция ВычислитьВыражение(Выражение9124327783, Параметры = Неопределено, НаСервере9124327783 = Ложь) Экспорт
// Здесь должен быть максимально чистый контекст выполнения
Если НаСервере9124327783 Тогда
Результат9124327783 = ирСервер.ВычислитьВыражение(Выражение9124327783, Параметры);
Иначе
Если Параметры = Неопределено Тогда
Результат9124327783 = ВычислитьВыражениеБезПараметровЛкс(Выражение9124327783);
Иначе
Результат9124327783 = Вычислить(Выражение9124327783);
КонецЕсли;
КонецЕсли;
Возврат Результат9124327783;
КонецФункции
Функция ВычислитьВыражениеБезПараметровЛкс(Выражение9124327783) Экспорт
Возврат Вычислить(Выражение9124327783);
КонецФункции
Функция ПолучитьПриглашениеОткрытьОтладчикЛкс() Экспорт
Возврат "Если нет кнопки ""Подробно"", разрешите отладку. Нажмите кнопку ""Подробно"", а затем ""Конфигуратор"", чтобы начать отладку!";
КонецФункции
Процедура ОткрытьОтладчикЛкс() Экспорт
#Если ВебКлиент Тогда
СообщитьЛкс("Команда недоступна в вебклиенте");
#Иначе
ВызватьИсключение ПолучитьПриглашениеОткрытьОтладчикЛкс();
#КонецЕсли
КонецПроцедуры
// Параметры:
// ПолноеИмя - ? -
// ТекстМодуля - ? -
// ТипВыхода - Строка - Служебный параметр для перехода после вызова метода
Функция ПолноеИмяМДЕдинственноеВМножественноеЛкс(ПолноеИмя) Экспорт
Фрагменты = СтрРазделитьЛкс(ПолноеИмя);
#Если Сервер И Не Сервер Тогда
Фрагменты = Новый Массив;
#КонецЕсли
Для Счетчик = 1 По Фрагменты.Количество() / 2 Цикл
Индекс = (Счетчик - 1) * 2;
МножественноеИмяМД = ирОбщий.МножественноеИмяМДЛкс(Фрагменты[Индекс]);
Если МножественноеИмяМД = Неопределено Тогда
Для ИндексОстатка = Индекс По Фрагменты.ВГраница() Цикл
Фрагменты.Удалить(Индекс);
КонецЦикла;
Прервать;
КонецЕсли;
Фрагменты[Индекс] = МножественноеИмяМД;
КонецЦикла;
ТекстМодуля = СтрСоединитьЛкс(Фрагменты, ".");
Возврат ТекстМодуля;
КонецФункции
Функция ОписаниеТиповОдногоТипаИзОписанияТиповЛкс(Тип, ОписаниеТипов) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов = Новый ОписаниеТипов;
#КонецЕсли
Массив = Новый Массив;
Массив.Добавить(Тип);
Результат = Новый ОписаниеТипов(Массив, ОписаниеТипов.КвалификаторыЧисла, ОписаниеТипов.КвалификаторыСтроки, ОписаниеТипов.КвалификаторыДаты, ОписаниеТипов.КвалификаторыДвоичныхДанных);
Возврат Результат;
КонецФункции
Функция ЭтоИмяЛокальногоКомпьютераЛкс(ИмяКомпьютера) Экспорт
Результат = Ложь
Или Не ЗначениеЗаполнено(ИмяКомпьютера)
Или ИмяКомпьютера = "."
Или СтрокиРавныЛкс(ИмяКомпьютера, "localhost")
Или ИмяКомпьютера = "127.0.0.1"
#Если Не ВебКлиент Тогда
Или СтрокиРавныЛкс(ИмяКомпьютера, ИмяКомпьютера())
#КонецЕсли
;
Возврат Результат;
КонецФункции
Функция ИмяКомпьютераКластераЛкс() Экспорт
Результат = ирОбщий.ПервыйФрагментЛкс(НСтр(СтрокаСоединенияИнформационнойБазы(), "Srvr"), ":");
Возврат Результат;
КонецФункции
Процедура ТребоватьТипЛкс(Значение, ИмяПараметра = "", Тип1, Тип2 = Неопределено, Тип3 = Неопределено, Тип4 = Неопределено, Тип5 = Неопределено, Тип6 = Неопределено) Экспорт
ТипЗначения = ТипЗнч(Значение);
Если Ложь
Или ТипЗначения = Тип1
Или ТипЗначения = Тип2
Или ТипЗначения = Тип3
Или ТипЗначения = Тип4
Или ТипЗначения = Тип5
Или ТипЗначения = Тип6
Тогда
Возврат;
КонецЕсли;
Массив = Новый Массив;
Массив.Добавить(Тип1);
Массив.Добавить(Тип2);
Массив.Добавить(Тип3);
Массив.Добавить(Тип4);
Массив.Добавить(Тип5);
Массив.Добавить(Тип6);
СтрокаТипов = "";
Для Каждого Тип Из Массив Цикл
Если ТипЗначения = Тип Тогда
Возврат;
КонецЕсли;
Если Тип = Неопределено Тогда
Прервать;
КонецЕсли;
Если СтрокаТипов <> "" Тогда
СтрокаТипов = СтрокаТипов + ", ";
КонецЕсли;
СтрокаТипов = СтрокаТипов + Тип;
КонецЦикла;
Текст = "";
Если ЗначениеЗаполнено(ИмяПараметра) Тогда
Текст = Текст + "Для параметра """ + ИмяПараметра + """ ";
КонецЕсли;
Текст = Текст + "Получено значение типа """ + ТипЗначения + """ вместо ожидаемых типов: " + СтрокаТипов + ".";
ВызватьИсключение Текст;
КонецПроцедуры
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
Процедура ПерейтиКОбъектуМетаданныхВКонфигуратореЛкс(Знач ПолноеИмя) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ТекстМодуля = ПолноеИмяМДЕдинственноеВМножественноеЛкс(ПолноеИмя);
Если Не ЗначениеЗаполнено(ТекстМодуля) Тогда
Возврат;
КонецЕсли;
ИмяВнешнейОбработки = ИдентификаторИзПредставленияЛкс("ПереходВКонфигураторе." + ПолноеИмя);
ИмяФайла = КаталогВременныхФайлов() + ИмяВнешнейОбработки + ".epf";
ФайлВнешнейОбработки = Новый Файл(ИмяФайла);
мПлатформа.СформироватьВнешнююОбработку(ФайлВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля,,, Истина);
мПлатформа.ОткрытьМодульВнешнейОбработкиВКонфигураторе(ИмяФайла, 1,, Истина, ИмяВнешнейОбработки);
КонецПроцедуры
Процедура ПерейтиКОпределениюМетодаВКонфигуратореЛкс(Знач СтрокаВызоваМетодаБезСкобок) Экспорт
ТекстМодуля = СтрокаВызоваМетодаБезСкобок + "();";
ИмяВнешнейОбработки = ИдентификаторИзПредставленияЛкс("ПереходВКонфигураторе." + СтрокаВызоваМетодаБезСкобок);
ИмяФайла = КаталогВременныхФайлов() + ИмяВнешнейОбработки + ".epf";
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФайлВнешнейОбработки = Новый Файл(ИмяФайла);
мПлатформа.СформироватьВнешнююОбработку(ФайлВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля,,, Истина);
мПлатформа.ОткрытьМодульВнешнейОбработкиВКонфигураторе(ИмяФайла, 1,, Истина, ИмяВнешнейОбработки);
КонецПроцедуры
// Возвращает стек встроенного языка строкой через выброс и обработку исключения. В точке останова возвращает пустую строку, т.к. там не передается стек предмета отладки.
// Полезна для временного включения записи диагностической информации в журнал регистрации путем временной вставки в код.
//
// Параметры:
// ЗаписатьВЖурналРегистрации - Булево, *Истина - записать стек в журнал регистрации, используется УровеньЖурналаРегистрации.Предупреждение
//
// Возвращаемое значение:
// - Строка
//
Функция СтекЛкс(ЗаписатьВЖурналРегистрации = Истина) Экспорт
Результат = Неопределено;
#Если ТолстыйКлиентОбычноеПриложение Тогда
Если ирКэш.НомерВерсииПлатформыЛкс() < 803019 Тогда
Результат = "Для обычного приложения функция доступна начиная с 8.3.19";
КонецЕсли;
#КонецЕсли
Если Результат = Неопределено Тогда
в8вт9я24хъЭЖ93 = 1;
Попытка
ВызватьИсключение в8вт9я24хъЭЖ93;
Исключение
Результат = ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке());
Результат = ирОбщий.ПоследнийФрагментЛкс(Результат, "в8вт9я24хъЭЖ93;" + Символы.ПС);
Маркеры = Новый Массив;
Маркеры.Добавить("СтекЛкс");
Для Каждого Маркер Из Маркеры Цикл
Результат = ирОбщий.ПоследнийФрагментЛкс(Результат, Маркер + "();" + Символы.ПС);
Результат = ирОбщий.ПоследнийФрагментЛкс(Результат, НРег(Маркер) + "();" + Символы.ПС);
Результат = ирОбщий.ПоследнийФрагментЛкс(Результат, Маркер + "()" + Символы.ПС);
Результат = ирОбщий.ПоследнийФрагментЛкс(Результат, НРег(Маркер) + "()" + Символы.ПС);
КонецЦикла;
КонецПопытки
КонецЕсли;
Если ЗаписатьВЖурналРегистрации Тогда
ЗаписьЖурналаРегистрации("Стек", УровеньЖурналаРегистрации.Предупреждение,,, Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПодробноеПредставлениеОшибкиЛкс(Знач ИнформацияОбОшибке) Экспорт
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
Если ИнформацияОбОшибке = Неопределено Тогда
// Из аварийного фонового задания нередко возвращается пустое свойство ИнформацияОбОшибке
Результат = "<>";
Иначе
Результат = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
// Антибаг платформы 8.3.19-21+ https://www.hostedredmine.com/issues/941533
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(Результат);
НомерПоследнейСтроки = ТекстовыйДокумент.КоличествоСтрок();
Если Найти(ТекстовыйДокумент.ПолучитьСтроку(НомерПоследнейСтроки), "{") = 0 Тогда
Пока Истина
И ИнформацияОбОшибке.Причина <> Неопределено
И (Ложь
Или ЗначениеЗаполнено(ИнформацияОбОшибке.Причина.ИмяМодуля)
Или ИнформацияОбОшибке.Причина.Причина <> Неопределено)
Цикл
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
ТекстовыйДокумент.УдалитьСтроку(НомерПоследнейСтроки);
Результат = ТекстовыйДокумент.ПолучитьТекст() + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЗагрузитьЗначениеИзФайлаЛкс(Знач ПолноеИмяФайла, Знач Сжатие = Ложь) Экспорт
Если Сжатие Тогда
ВременныйКаталог = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ВременныйКаталог);
ЗипЧтение = Новый ЧтениеZipФайла(ПолноеИмяФайла);
ЗипЧтение.ИзвлечьВсе(ВременныйКаталог);
ПолноеИмяФайла = ВременныйКаталог + РазделительПутиКФайлуЛкс() + ЗипЧтение.Элементы[0].Имя;
КонецЕсли;
ЧтениеХМЛ = Новый ЧтениеXML;
ЧтениеХМЛ.ОткрытьФайл(ПолноеИмяФайла);
Попытка
//Результат = ЗначениеИзФайла(ВыборФайла.ПолноеИмяФайла);
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеХМЛ);
Исключение
СообщитьЛкс(ОписаниеОшибки());
Результат = Неопределено;
КонецПопытки;
ЧтениеХМЛ.Закрыть();
Если Сжатие Тогда
УдалитьФайлы(ВременныйКаталог, "*");
КонецЕсли;
Если ТипЗнч(Результат) = Тип("Структура") И Результат.Свойство("ВложенноеНесериализуемоеЗначение") Тогда
Результат = Результат.ВложенноеНесериализуемоеЗначение.Получить();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СохранитьЗначениеВФайлЛкс(Знач Значение, Знач ПолноеИмяФайла, Сжатие = Ложь, УровеньСжатия = Неопределено) Экспорт
ЗаписьХМЛ = Новый ЗаписьXML;
ЗаписьХМЛ.ОткрытьФайл(ПолноеИмяФайла);
Результат = Истина;
Попытка
//ЗначениеВФайл(ПолноеИмяФайла, Значение);
СериализаторXDTO.ЗаписатьXML(ЗаписьХМЛ, Значение);
Исключение
ЗаписьХМЛ.Закрыть();
ЗаписьХМЛ = Новый ЗаписьXML;
ЗаписьХМЛ.ОткрытьФайл(ПолноеИмяФайла);
Значение = Новый Структура("ВложенноеНесериализуемоеЗначение", Новый ХранилищеЗначения(Значение));
Попытка
СериализаторXDTO.ЗаписатьXML(ЗаписьХМЛ, Значение);
СообщитьЛкс("При сохранении данных в файл использована сериализация через хранилище значения из-за наличия недопустимых символов XML");
Исключение
СообщитьЛкс(ОписаниеОшибки());
Результат = Ложь;
КонецПопытки;
КонецПопытки;
ЗаписьХМЛ.Закрыть();
Если Результат И Сжатие Тогда
ВременныйКаталог = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ВременныйКаталог);
Файл = Новый Файл(ПолноеИмяФайла);
ИмяВременногоФайла = ВременныйКаталог + РазделительПутиКФайлуЛкс() + Файл.ИмяБезРасширения + ".xml";
ПереместитьФайл(Файл.ПолноеИмя, ИмяВременногоФайла);
ЗаписьЗип = Новый ЗаписьZipФайла(ПолноеИмяФайла,,,, УровеньСжатия);
ЗаписьЗип.Добавить(ИмяВременногоФайла);
ЗаписьЗип.Записать();
УдалитьФайлы(ВременныйКаталог, "*");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция КомпоновщикТаблицыМетаданныхЛкс(Знач ПолноеИмяМД, ВызыватьИсключениеПриОтсутствииПрав = Истина, ИндексПараметраПериодичность = Неопределено,
ВыражениеПараметраПериодичность = "", ИменаВместоПредставлений = Ложь) Экспорт
СхемаКомпоновкиДанных = ирОбщий.СоздатьСхемуКомпоновкиПоОбъектуМДЛкс(ПолноеИмяМД,, Ложь,, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность, ИменаВместоПредставлений);
#Если Сервер И Не Сервер Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
Попытка
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных);
Исключение
// Антибаг платформы 8.2.18
// Ошибка при вызове конструктора (ИсточникДоступныхНастроекКомпоновкиДанных)
// ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных);
//по причине:
//Ошибка получения информации набора данных
//по причине:
//Ошибка в запросе набора данных
//по причине:
//{(1, 17)}: Неверное присоединение
//ВЫБРАТЬ Т.* ИЗ <>>КАК Т
ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяМД);
Если ОбъектМД = Неопределено Тогда
// Возможно эта логика уже есть в какой то функции
лПолноеИмяМД = ПолноеИмяМД;
Фрагменты = ирОбщий.СтрРазделитьЛкс(ПолноеИмяМД);
Если Фрагменты.Количество() > 1 Тогда
Фрагменты.Удалить(Фрагменты.Количество() - 1);
лПолноеИмяМД = ирОбщий.СтрСоединитьЛкс(Фрагменты, ".");
КонецЕсли;
ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(лПолноеИмяМД);
КонецЕсли;
Если Ложь
Или ОбъектМД = Неопределено
Или Не ПравоДоступа("Чтение", ОбъектМД)
Тогда
Если ВызыватьИсключениеПриОтсутствииПрав Тогда
ВызватьИсключение "Таблица отсутствует или нет прав на ее чтение """ + ПолноеИмяМД + """";
Иначе
Возврат Неопределено;
КонецЕсли;
Иначе
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроек.Инициализировать(ИсточникДоступныхНастроек);
// Для сравнения скорости в отладчике. Примерно та же скорость через построитель.
//ПсевдонимТаблицы = "Т";
//ПолноеИмяИлиОбъектМД = ПолноеИмяМД;
//Если ТипЗнч(ПолноеИмяИлиОбъектМД) = Тип("Строка") Тогда
// ПолноеИмяМД = ПолноеИмяИлиОбъектМД;
//Иначе
// ПолноеИмяМД = ПолноеИмяИлиОбъектМД.ПолноеИмя();
//КонецЕсли;
//ПолноеИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
//Если ИндексПараметраПериодичность <> Неопределено Тогда
// ПолноеИмяТаблицыБД = ПолноеИмяТаблицыБД + "(";
// Для Индекс = 1 По ИндексПараметраПериодичность Цикл
// ПолноеИмяТаблицыБД = ПолноеИмяТаблицыБД + ",";
// КонецЦикла;
// ПолноеИмяТаблицыБД = ПолноеИмяТаблицыБД + ВыражениеПараметраПериодичность + ")";
//КонецЕсли;
//ТекстЗапроса = "ВЫБРАТЬ " + ПсевдонимТаблицы + ".* ИЗ " + ПолноеИмяТаблицыБД + " КАК " + ПсевдонимТаблицы;
//Построитель = Новый ПостроительЗапроса(ТекстЗапроса);
//Построитель.ЗаполнитьНастройки();
Возврат КомпоновщикНастроек;
КонецФункции
Функция ЕстьНекорректныеЭлементыВКомпоновщикеНастроекЛкс(Знач ПроверочныйКомпоновщик, выхСтрокаТекущихНастроек = "", выхСтрокаИсправленныхНастроек = "") Экспорт
выхСтрокаТекущихНастроек = ОбъектВСтрокуXMLЛкс(ПроверочныйКомпоновщик.Настройки);
ирОбщий.КомпоновщикНастроекВосстановитьЛкс(ПроверочныйКомпоновщик);
выхСтрокаИсправленныхНастроек = ОбъектВСтрокуXMLЛкс(ПроверочныйКомпоновщик.Настройки);
ЕстьНекорректныеЭлементы = выхСтрокаИсправленныхНастроек <> выхСтрокаТекущихНастроек;
Возврат ЕстьНекорректныеЭлементы;
КонецФункции
Процедура ОбработкаПолученияФормыЛкс(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка, ЕстьУправляемаяФорма = Ложь) Экспорт
Если ЕстьУправляемаяФорма Тогда
Возврат;
КонецЕсли;
#Если Сервер Тогда
ПроверитьФлажокИспользоватьОбычныеФормыВУправляемомПриложенииЛкс();
#КонецЕсли
СтандартнаяОбработка = Ложь;
Если Не ирКэш.ЛиСеансТолстогоКлиентаЛкс() Тогда
ВыбраннаяФорма = "Обработка.ирПортативный.Форма.ЗапускСеансаУправляемая";
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьФлажокИспользоватьОбычныеФормыВУправляемомПриложенииЛкс() Экспорт
Если Не Метаданные.ИспользоватьОбычныеФормыВУправляемомПриложении Тогда
СообщитьЛкс("Для использования отчетов подсистемы запустите обычное приложение либо в свойствах конфигурации установите флажок ""Использовать обычные формы в управляемом приложении""
| доступный в режиме ""Сервис""/""Параметры""/""Редактирование конфигурации для режимов запуска""=""Управляемое приложение и обычное приложение"".");
КонецЕсли;
КонецПроцедуры
Функция ВыполнитьАлгоритмЧерезВнешнююОбработкуЛкс(ИмяФайлаВнешнейОбработки, СтруктураПараметров, выхВремяНачала = Неопределено, ВерсияАлгоритма = Неопределено) Экспорт
#Если Сервер И Не Клиент Тогда
Файл = Новый Файл(ИмяФайлаВнешнейОбработки);
Если Не Файл.Существует() Тогда
КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс();
Если Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
ВызватьИсключение "файл внешней обработки алгоритма не доступен на сервере. Рекомендуется в общих настройках инструментов задать сетевой каталог объектов для отладки.";
КонецЕсли;
КонецЕсли;
#КонецЕсли
ВнешняяОбработка = ВнешниеОбработки.Создать(ИмяФайлаВнешнейОбработки, Ложь);
Если ВерсияАлгоритма <> Неопределено И ВнешняяОбработка.ВерсияАлгоритма() <> ВерсияАлгоритма Тогда
// Антибаг 8.3.11.2700-?. Testplatform@1c.ru - Support #17972. В обычном приложении на клиенте при повторном создании с одним именем файла и внутренней версией используются метаданные первой обработки в сеансе.
СообщитьЛкс("Внешняя обработка не обновилась в кэше процесса 1С. Для ее обновления рекомендуется выполнить перезапуск процесса.", СтатусСообщения.Внимание);
КонецЕсли;
ОбщиеМодули = ПолучитьСтруктуруОсновныхОбщихМодулейЛкс();
выхВремяНачала = ирОбщий.ТекущееВремяВМиллисекундахЛкс();
ВнешняяОбработка.мМетод(СтруктураПараметров, ОбщиеМодули);
//Возврат Результат;
КонецФункции
Функция ТекстМодуляСгенерированнойВнешнейОбработки(ПолноеИмяФайла) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Файл = Новый Файл(ПолноеИмяФайла);
Текст = мПлатформа.ТекстМодуляСгенерированнойВнешнейОбработки(Файл);
Возврат Текст;
КонецФункции
Функция ПолучитьСтруктуруОсновныхОбщихМодулейЛкс() Экспорт
ОбщиеМодули = Новый Структура;
ОбщиеМодули.Вставить("ирОбщий", ирОбщий);
ОбщиеМодули.Вставить("ирКэш", ирКэш);
ОбщиеМодули.Вставить("ирСервер", ирСервер);
Возврат ОбщиеМодули;
КонецФункции // ВыполнитьЛокально()
Процедура ОбновитьТипЗначенияВСтрокеТаблицыЛкс(ТекущаяСтрока, Знач ИмяКолонкиЗначения = "Значение", Знач ИмяКолонкиИлиОписаниеТипов = "ОписаниеТипов",
Знач ИмяКолонкиТипаЗначения = "ТипЗначения", Знач ИмяКолонкиИмяТипаЗначения = "ИмяТипаЗначения", Знач Колонки = Неопределено, Знач РасширенноеЗначение = Неопределено) Экспорт
Если Колонки = Неопределено Тогда
Колонки = ТекущаяСтрока.Владелец().Колонки;
Иначе
ТребоватьТипЛкс(Колонки, Тип("ТаблицаЗначений"), Тип("КоллекцияКолонокТаблицыЗначений"), Тип("КоллекцияКолонокДереваЗначений"), Тип("КоллекцияКолонокРезультатаЗапроса"), , Тип("КоллекцияОбъектовМетаданных"));
#Если Сервер И Не Сервер Тогда
Колонки = Новый ТаблицаЗначений;
Колонки = Колонки.Колонки;
#КонецЕсли
КонецЕсли;
Если ЗначениеЗаполнено(ИмяКолонкиЗначения) Тогда
РасширенноеЗначение = ТекущаяСтрока[ИмяКолонкиЗначения];
КонецЕсли;
ТипЗначения = ТипЗнч(РасширенноеЗначение);
Если ТипЗнч(ИмяКолонкиИлиОписаниеТипов) <> Тип("ОписаниеТипов") Тогда
КолонкаОписанияТипов = Колонки.Найти(ИмяКолонкиИлиОписаниеТипов);
Если КолонкаОписанияТипов <> Неопределено Тогда
ИмяКолонкиИлиОписаниеТипов = ТекущаяСтрока[ИмяКолонкиИлиОписаниеТипов];
Иначе
ИмяКолонкиИлиОписаниеТипов = Неопределено;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(Колонки) = Тип("ТаблицаЗначений") Тогда
ЕстьКолонкаТипЗначения = Колонки.Найти(ИмяКолонкиТипаЗначения, "Имя") <> Неопределено;
Иначе
ЕстьКолонкаТипЗначения = Колонки.Найти(ИмяКолонкиТипаЗначения) <> Неопределено;
КонецЕсли;
Если ЕстьКолонкаТипЗначения Тогда
ТекущаяСтрока[ИмяКолонкиТипаЗначения] = ПредставлениеТипаЛкс(ТипЗначения, ИмяКолонкиИлиОписаниеТипов, Ложь);
КонецЕсли;
Если ТипЗнч(Колонки) = Тип("ТаблицаЗначений") Тогда
ЕстьКолонкаИмяТипаЗначения = Колонки.Найти(ИмяКолонкиИмяТипаЗначения, "Имя") <> Неопределено;
Иначе
ЕстьКолонкаИмяТипаЗначения = Колонки.Найти(ИмяКолонкиИмяТипаЗначения) <> Неопределено;
КонецЕсли;
Если ЕстьКолонкаИмяТипаЗначения Тогда
ТекущаяСтрока[ИмяКолонкиИмяТипаЗначения] = ПредставлениеТипаЛкс(ТипЗначения, ИмяКолонкиИлиОписаниеТипов, Истина);
КонецЕсли;
КонецПроцедуры
// Функция - Параметры запуска приложения1 с лкс
//
// Параметры:
// ИмяПользователяИнфобазы - -
// ПарольПользователяИнфобазы - -
// КодРазрешения - -
// РежимКонфигуратора - -
// РежимЗапуска - Строка - ОбычноеПриложение, УправляемоеПриложениеТолстый, УправляемоеПриложениеТонкий
// ПрименитьТекущиеПараметрыЗапуска - -
// ОчисткаКэшаКлиентСерверныхВызовов - -
// ДополнительныеПараметры - -
// СообщитьСтрокуПараметров - -
// СтрокаСоединения - -
// ОткрытьПортативныеИнструменты - -
// РежимИнтерфейсаТакси - -
// РазделениеДанных - -
// ОтключитьАутентификациюОС - -
// КодЯзыка - -
// ПараметрЗапуска - -
// ИмяВСпискеБазПользователя - -
//
// Возвращаемое значение:
// -
//
Функция ПараметрыЗапускаПриложения1СЛкс(Знач ИмяПользователяИнфобазы = "", Знач ПарольПользователяИнфобазы = "", КодРазрешения = "", РежимКонфигуратора = Ложь,
РежимЗапуска = "ОбычноеПриложение", ПрименитьТекущиеПараметрыЗапуска = Истина, ОчисткаКэшаКлиентСерверныхВызовов = Ложь, ДополнительныеПараметры = "", СообщитьСтрокуПараметров = Истина,
СтрокаСоединения = "", ОткрытьПортативныеИнструменты = Ложь, РежимИнтерфейсаТакси = Ложь, РазделениеДанных = "", ОтключитьАутентификациюОС = Ложь, КодЯзыка = "", ПараметрЗапуска = "",
ИмяВСпискеБазПользователя = "") Экспорт
Если Не ЗначениеЗаполнено(СтрокаСоединения) Тогда
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
КонецЕсли;
ПараметрыЗапуска = "";
Если РежимКонфигуратора Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " CONFIG";
Иначе
ПараметрыЗапуска = ПараметрыЗапуска + " ENTERPRISE";
КонецЕсли;
ПараметрыЗапуска = ПараметрыЗапуска + " /IBConnectionString" + СтрокаВВыражениеВстроенногоЯзыкаЛкс(СтрокаСоединения);
Если ЗначениеЗаполнено(ИмяВСпискеБазПользователя) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /IBName" + СтрокаВВыражениеВстроенногоЯзыкаЛкс(ИмяВСпискеБазПользователя);
КонецЕсли;
Если ЗначениеЗаполнено(ИмяПользователяИнфобазы) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /N""" + ИмяПользователяИнфобазы + """";
КонецЕсли;
Если ОтключитьАутентификациюОС Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /WA-";
КонецЕсли;
Если ЗначениеЗаполнено(ПарольПользователяИнфобазы) Тогда
СтрокаПараметраПароля = "/P""" + ПарольПользователяИнфобазы + """";
СтрокаЗаменыПароля = "/P""" + "***" + """";
ПараметрыЗапуска = ПараметрыЗапуска + " " + СтрокаПараметраПароля;
КонецЕсли;
Если ЗначениеЗаполнено(ПараметрЗапуска) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /C""" + ПараметрЗапуска + """";
КонецЕсли;
ПараметрыЗапуска = ПараметрыЗапуска + " /UC""" + КодРазрешения + """";
Если Не РежимКонфигуратора Тогда
Если ПрименитьТекущиеПараметрыЗапуска Тогда
ПараметрыЗапускаДляОтладки = ПараметрыЗапускаСеансаТекущиеЛкс();
ПараметрыЗапуска = ПараметрыЗапуска + " " + ПараметрыЗапускаДляОтладки;
КонецЕсли;
Если ОчисткаКэшаКлиентСерверныхВызовов Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /ClearCache";
КонецЕсли;
Если РежимИнтерфейсаТакси Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /iTaxi";
КонецЕсли;
Если ОткрытьПортативныеИнструменты И ирКэш.ЛиПортативныйРежимЛкс() Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /Execute""" + ирПортативный.ИспользуемоеИмяФайла + """";
КонецЕсли;
Если СтрокиРавныЛкс(РежимЗапуска, "Авто") Тогда
// Из-за этого иногда долго стартует почему то
ПараметрыЗапуска = ПараметрыЗапуска + " /AppAutoCheckMode"; // Автоматический выбор типа приложения для запуска
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "ОбычноеПриложение") Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /RunModeOrdinaryApplication";
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "УправляемоеПриложениеТолстый") Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /RunModeManagedApplication";
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "УправляемоеПриложениеТонкий") Тогда
//ПараметрыЗапуска = ПараметрыЗапуска + "/IBConnectionString" + СтрокаВВыражениеВстроенногоЯзыкаЛкс(СтрокаСоединения);
КонецЕсли;
Если ЗначениеЗаполнено(РазделениеДанных) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /Z""" + РазделениеДанных + """";
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(КодЯзыка) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /L""" + КодЯзыка + """";
КонецЕсли;
Если ЗначениеЗаполнено(ДополнительныеПараметры) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " " + ДополнительныеПараметры;
КонецЕсли;
Если СообщитьСтрокуПараметров Тогда
СообщитьЛкс(СтрЗаменить(ПараметрыЗапуска, СтрокаПараметраПароля, СтрокаЗаменыПароля));
КонецЕсли;
Возврат ПараметрыЗапуска;
КонецФункции
Функция СоздатьСсылочныйОбъектПоМетаданнымЛкс(ОбъектИлиИмяМД, ЭтоГруппаДляНового = Ложь, ИдентификаторСсылки = Неопределено, ЗаполнитьНовый = Истина) Экспорт
УстановитьПривилегированныйРежим(Истина);
Менеджер = ПолучитьМенеджерЛкс(ОбъектИлиИмяМД);
Если ТипЗнч(ОбъектИлиИмяМД) = Тип("ОбъектМетаданных") Тогда
ОбъектМД = ОбъектИлиИмяМД;
Иначе
ОбъектМД = ПолучитьМетаданныеЛкс(ОбъектИлиИмяМД);
КонецЕсли;
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ИмяТипаМетаданного = ПеревестиВРусский(ПервыйФрагментЛкс(ПолноеИмяМД));
Попытка
Если ИмяТипаМетаданного = "Справочник" Или ИмяТипаМетаданного = "ПланВидовХарактеристик" Тогда
Если ЭтоГруппаДляНового Тогда
Объект = Менеджер.СоздатьГруппу();
Иначе
Объект = Менеджер.СоздатьЭлемент();
КонецЕсли;
ИначеЕсли ИмяТипаМетаданного = "Документ" Тогда
Объект = Менеджер.СоздатьДокумент();
ИначеЕсли ИмяТипаМетаданного = "Задача" Тогда
Объект = Менеджер.СоздатьЗадачу();
ИначеЕсли ИмяТипаМетаданного = "БизнесПроцесс" Тогда
Объект = Менеджер.СоздатьБизнесПроцесс();
ИначеЕсли ИмяТипаМетаданного = "ПланОбмена" Тогда
Объект = Менеджер.СоздатьУзел();
ИначеЕсли ИмяТипаМетаданного = "ПланВидовРасчета" Тогда
Объект = Менеджер.СоздатьВидРасчета();
ИначеЕсли ИмяТипаМетаданного = "ПланСчетов" Тогда
Объект = Менеджер.СоздатьСчет();
ИначеЕсли ИмяТипаМетаданного = "ВнешнийИсточникДанных" Тогда
Объект = Менеджер.СоздатьОбъект();
Иначе
ВызватьИсключение "Неизвестный тип метаданных """ + ИмяТипаМетаданного + """";
КонецЕсли;
Исключение
ПроверитьОшибкуПодписокНаКлиентеЛкс(ОписаниеОшибки());
ВызватьИсключение;
КонецПопытки;
Если ИдентификаторСсылки = Неопределено Тогда
ИдентификаторСсылки = Новый УникальныйИдентификатор();
КонецЕсли;
Объект.УстановитьСсылкуНового(Менеджер.ПолучитьСсылку(ИдентификаторСсылки));
Если ЗаполнитьНовый Тогда
Объект.Заполнить(Неопределено);
КонецЕсли;
Возврат Объект;
КонецФункции
Процедура ПроверитьОшибкуПодписокНаКлиентеЛкс(ОписаниеОшибки)
#Если Клиент Тогда
Если Найти(ОписаниеОшибки, "Обработчик события не найден") > 0 Тогда
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
СообщитьЛкс("Для предотвращения ошибок инициализации объектов рекомендуется в общих параметрах записи установить флажок ""Объекты на сервере""=Да или перейти на непортативный вариант инструментов");
Иначе
СообщитьЛкс("Для предотвращения ошибок инициализации объектов рекомендуется в общих параметрах записи установить флажки ""Объекты на сервере""=Да и ""Не использовать имитаторы""=Нет");
КонецЕсли;
КонецЕсли;
#КонецЕсли
КонецПроцедуры
Функция СтрокаПустогоИдентификатораЛкс() Экспорт
Возврат "00000000-0000-0000-0000-000000000000";
КонецФункции
Функция ИмяТипаИзПолногоИмениМДЛкс(Знач ПолноеИмяИлиОбъектМД, Знач ПодтипРус = "Ссылка", Знач ФрагментыИмени = Неопределено) Экспорт
Если ТипЗнч(ПолноеИмяИлиОбъектМД) <> Тип("Строка") Тогда
ПолноеИмяИлиОбъектМД = ПолноеИмяИлиОбъектМД.ПолноеИмя();
КонецЕсли;
Если ФрагментыИмени = Неопределено Тогда
ФрагментыИмени = СтрРазделитьЛкс(ПолноеИмяИлиОбъектМД);
КонецЕсли;
Если ФрагментыИмени.Количество() = 3 Тогда
ИмяТипа = ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяИлиОбъектМД, ПодтипРус);
Иначе
ПервоеСлово = "";
ИменаМД = "";
Для Счетчик = 1 По ФрагментыИмени.Количество() / 2 Цикл
ПервоеСлово = ПервоеСлово + ФрагментыИмени[(Счетчик - 1) * 2];
ИменаМД = ИменаМД + "." + ФрагментыИмени[(Счетчик - 1) * 2 + 1];
КонецЦикла;
Если ЛиРусскаяБукваЛкс(Лев(ПервоеСлово, 1)) Тогда
Подтип = ПодтипРус;
Иначе
Подтип = ПеревестиСтроку(ПодтипРус);
КонецЕсли;
ИмяТипа = ПервоеСлово + Подтип + ИменаМД;
КонецЕсли;
Возврат ИмяТипа;
КонецФункции
Функция ИмяТипаИзПолногоИмениТаблицыБДЛкс(ИмяТаблицыБД, Знач ПодтипРус = "Ссылка") Экспорт
Если Найти(ИмяТаблицыБД, "." + ПеревестиСтроку("Точки")) > 0 Тогда
ОписаниеТаблицыБД = ОписаниеТаблицыБДЛкс(ИмяТаблицыБД);
КонецЕсли;
Если Истина
И ОписаниеТаблицыБД <> Неопределено
И ОписаниеТаблицыБД.Тип = "Точки"
Тогда
Если ПодтипРус = "Ссылка" Тогда
Фрагменты = СтрРазделитьЛкс(ИмяТаблицыБД);
Результат = ПеревестиСтроку("ТочкаМаршрутаБизнесПроцессаСсылка") + "." + Фрагменты[1];
КонецЕсли;
Иначе
ПолноеИмяМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ИмяТаблицыБД);
Если ПолноеИмяМД <> Неопределено Тогда
Результат = ИмяТипаИзПолногоИмениМДЛкс(ПолноеИмяМД, ПодтипРус);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ИмяТипаЛкс(Знач Тип) Экспорт
Если ТипЗнч(Тип) <> Тип("Тип") Тогда
Тип = ТипЗнч(Тип);
КонецЕсли;
Результат = ПредставлениеТипаЛкс(Тип,, Истина);
Возврат Результат;
КонецФункции
// Возвращает имя типа, который будет использован в xml файле для указанного объекта метаданных
// Используется при поиске и замене ссылок при загрузке, при модификации схемы current-config при записи
//
// Параметры:
// Значение - Объект метаданных или Ссылка
//
// Возвращаемое значение:
// Строка - Строка вида CatalogRef.Валюты, описывающая объект метаданных
//
Функция XMLТипСсылкиЛкс(Знач ОбъектМДИлиСсылка) Экспорт
Если ТипЗнч(ОбъектМДИлиСсылка) = Тип("ОбъектМетаданных") Тогда
Ссылка = Новый (ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(ОбъектМДИлиСсылка));
Иначе
Ссылка = ОбъектМДИлиСсылка;
КонецЕсли;
Результат = СериализаторXDTO.XMLТипЗнч(Ссылка).ИмяТипа;
Возврат Результат;
КонецФункции
Функция ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, Знач ПодтипРус = "НаборЗаписей") Экспорт
Подтип = ПеревестиСтроку(ПодтипРус);
Фрагменты = СтрРазделитьЛкс(ПолноеИмяТаблицыБД);
Если Фрагменты.Количество() > 2 Тогда
Если Фрагменты[0] = ПеревестиСтроку("РегистрРасчета") Тогда
ИмяТипа = ПеревестиСтроку("Перерасчет") + Подтип + "." + Фрагменты[1] + "." + Фрагменты[2];
ИначеЕсли Фрагменты[0] = ПеревестиСтроку("РегистрБухгалтерии") Тогда
ИмяТипа = ПеревестиСтроку("РегистрБухгалтерии") + Подтип + "." + Фрагменты[1];
ИначеЕсли ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(Фрагменты[0]) Тогда
ИмяТипа = ПеревестиСтроку("ВнешнийИсточникДанныхТаблица") + Подтип + "." + Фрагменты[1] + "." + Фрагменты[3];
КонецЕсли;
Иначе
ИмяТипа = СтрЗаменить(ПеревестиСтроку(Фрагменты[0]) + "." + Фрагменты[1], ".", Подтип + ".");
КонецЕсли;
Возврат ИмяТипа;
КонецФункции
Функция ЗаменитьИдентификаторОбъектаЛкс(Объект, ИдентификаторСсылки = Неопределено) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() И ТипЗнч(Объект) = Тип("ОбработкаОбъект.ирИмитаторСсылочныйОбъект") Тогда
Возврат Объект.ЗаменитьИдентификаторОбъекта();
КонецЕсли;
Если ИдентификаторСсылки = Неопределено Тогда
ИдентификаторСсылки = Новый УникальныйИдентификатор;
КонецЕсли;
// Антибаг платформы 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=967697#967697
//Объект = СериализаторXDTO.ЗаписатьXDTO(Объект);
//Объект.Ref = ИдентификаторСсылки;
//Объект.IsFolder = ЭтоГруппаДляНового;
//Объект = СериализаторXDTO.ПрочитатьXDTO(Объект);
//
// Этот метод опасный, т.к. может привести к нежелательным изменениям в объекте!
ЗаписьХмл = Новый ЗаписьXML;
ЗаписьХмл.УстановитьСтроку();
ЗаписатьXML(ЗаписьХмл, Объект);
СтрокаХмл = ЗаписьХмл.Закрыть();
Попытка
ТекущийИДСсылки = XMLСтрока(Объект.Ссылка);
Исключение
// Внешний источник данных
ТекущийИДСсылки = "";
КонецПопытки;
Если ЗначениеЗаполнено(ТекущийИДСсылки) Тогда
ИмяЭлементаСсылки = "Ref";
СтрокаХмл = СтрЗаменить(СтрокаХмл, "<" + ИмяЭлементаСсылки + ">" + ТекущийИДСсылки + "" + ИмяЭлементаСсылки + ">",
"<" + ИмяЭлементаСсылки + ">" + XMLСтрока(ИдентификаторСсылки) + "" + ИмяЭлементаСсылки + ">");
//ИмяЭлементаЭтоГруппа = "IsFolder";
//Если Найти(СтрокаХмл, "<" + ИмяЭлементаЭтоГруппа + ">") > 0 Тогда
// СтрокаХмл = СтрЗаменить(СтрокаХмл, "<" + ИмяЭлементаЭтоГруппа + ">" + XMLСтрока(Объект.IsFolder) + "" + ИмяЭлементаЭтоГруппа + ">",
// "<" + ИмяЭлементаЭтоГруппа + ">" + XMLСтрока(ЭтоГруппаДляНового) + "" + ИмяЭлементаЭтоГруппа + ">");
//КонецЕсли;
КонецЕсли;
ЧтениеХмл = Новый ЧтениеXML;
ЧтениеХмл.УстановитьСтроку(СтрокаХмл);
Объект = ПрочитатьXML(ЧтениеХмл);
Возврат Объект;
КонецФункции
Функция НедоступноИзменениеПоляСсылочногоОбъектаЛкс(Знач ИмяПоля) Экспорт
НедоступноИзменениеПоля = Ложь
Или Нрег(ИмяПоля) = Нрег("Ссылка")
Или Нрег(ИмяПоля) = Нрег("ВерсияДанных")
Или Нрег(ИмяПоля) = Нрег("ЭтоГруппа")
//Или Нрег(ИмяПоля) = Нрег("ЭтотУзел") // ошибочно помечен как нередактируемый в синтакс-помощнике
Или Нрег(ИмяПоля) = Нрег("Предопределенный");
Возврат НедоступноИзменениеПоля;
КонецФункции
// Функция - Параметры доступа к объекту МДЛкс
//
// Параметры:
// Право - -
// МетаОбъект - -
// РольИлиПользователь - -
// выхПраваНеПрименимы - -
// выхИмяПоля - Строка - Неопределено - сначала подбор полей Ссылка, Период; "" - сразу получаем все поля и берем первое
//
// Возвращаемое значение:
// -
//
Функция ПараметрыДоступаКОбъектуМДЛкс(Знач Право, Знач МетаОбъект, Знач РольИлиПользователь = Неопределено, выхПраваНеПрименимы = Ложь, выхИмяПоля = Неопределено) Экспорт
Если выхИмяПоля = Неопределено Тогда
ИменаПолей = Новый Массив;
ИменаПолей.Добавить("Ссылка");
ИменаПолей.Добавить("Период");
Для Каждого ИмяПоля Из ИменаПолей Цикл
Попытка
ПараметрыДоступа = ПараметрыДоступа(Право, МетаОбъект, ИмяПоля, РольИлиПользователь);
Прервать;
Исключение
КонецПопытки;
КонецЦикла;
ИначеЕсли выхИмяПоля <> "" Тогда
Попытка
ПараметрыДоступа = ПараметрыДоступа(Право, МетаОбъект, выхИмяПоля, РольИлиПользователь);
Исключение
КонецПопытки;
КонецЕсли;
Если ПараметрыДоступа = Неопределено Тогда
Попытка
ПоляТаблицы = ПоляТаблицыМДЛкс(МетаОбъект, Ложь,,, Ложь);
ИмяПоля = ПоляТаблицы[0].Имя;
ПараметрыДоступа = ПараметрыДоступа(Право, МетаОбъект, ИмяПоля, РольИлиПользователь);
выхИмяПоля = ИмяПоля;
Исключение
// Например это Обработка, Перечисление
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
ПараметрыДоступа = Неопределено;
// Баг 8.3.13 Эта функция возвращает Истина даже для некорректных комбинаций параметров
//Попытка
// ПараметрыДоступа = ПравоДоступа(КлючИЗначение.Ключ, МетаОбъект, Роль);
//Исключение
выхПраваНеПрименимы = Истина;
//КонецПопытки;
КонецПопытки;
КонецЕсли;
Возврат ПараметрыДоступа;
КонецФункции
Функция ЕстьОграниченияДоступаКСтрокамТаблицыНаЧтениеЛкс(Знач ОбъектМД) Экспорт
ЕстьПраваДоступаКСтрокам = Ложь;
ПараметрыДоступа = ПараметрыДоступаКОбъектуМДЛкс("Чтение", ОбъектМД);
Если ПараметрыДоступа = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ПараметрыДоступа = ПараметрыДоступа();
#КонецЕсли
Если ПараметрыДоступа.Доступность Тогда
ЕстьПраваДоступаКСтрокам = ПараметрыДоступа.ОграничениеУсловием;
КонецЕсли;
Возврат ЕстьПраваДоступаКСтрокам;
КонецФункции
Функция РежимОбъектыНаСервереПоУмолчаниюЛкс(РазрешитьВПортативномВарианте = Истина) Экспорт
Результат = Истина
И (Ложь
Или Не ирКэш.ЛиПортативныйРежимЛкс()
Или РазрешитьВПортативномВарианте И ирПортативный.ЛиСерверныйМодульДоступенЛкс())
И Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение;
Возврат Результат;
КонецФункции
// Функция - Скопировать колонки коллекции
//
// Параметры:
// КоллекцияИсточник - -
// КоллекцияПриемник - -
// БезТипов - -
// *ИменаКолонок - Строка, "" - белый список имен колонок через запятую
//
// Возвращаемое значение:
// -
//
Функция СкопироватьКолонкиКоллекцииЛкс(КоллекцияИсточник, КоллекцияПриемник = Неопределено, БезТипов = Ложь, Знач ИменаКолонок = "") Экспорт
#Если Сервер И Не Сервер Тогда
КоллекцияИсточник = Новый ТаблицаЗначений;
#КонецЕсли
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый (ТипЗнч(КоллекцияИсточник));
КонецЕсли;
#Если Сервер И Не Сервер Тогда
КоллекцияПриемник = Новый ТаблицаЗначений;
#КонецЕсли
Если ЗначениеЗаполнено(ИменаКолонок) Тогда
СтруктураКолонок = Новый Структура(ИменаКолонок);
КонецЕсли;
Для Каждого Колонка Из КоллекцияИсточник.Колонки Цикл
Если Ложь
Или (Истина
И СтруктураКолонок <> Неопределено
И Не СтруктураКолонок.Свойство(Колонка.Имя))
Или КоллекцияПриемник.Колонки.Найти(Колонка.Имя) <> Неопределено
Тогда
Продолжить;
КонецЕсли;
Если БезТипов Тогда
НовыйТип = Новый ОписаниеТипов;
Иначе
НовыйТип = Колонка.ТипЗначения;
КонецЕсли;
КоллекцияПриемник.Колонки.Добавить(Колонка.Имя, НовыйТип, Колонка.Заголовок, Колонка.Ширина);
КонецЦикла;
Возврат КоллекцияПриемник;
КонецФункции
// ПропускатьДвиженияВнеПланаОбмена - Булево - при РегистрироватьДвиженияВместеСДокументом = Истина позволяет управлять поведением для тех движений, которые не входят в план обмена,
// Если Истина, то такие движения пропускаются, иначе вызывается исключение
Функция ПланыОбменаИзменитьРегистрациюЛкс(УзелИлиМассив, КлючОбъекта, НовоеЗначение = Истина, РегистрироватьДвиженияВместеСДокументом = Ложь, ДвиженияВместеСПоследовательностями = Ложь,
ПропускатьДвиженияВнеПланаОбмена = Истина, ПроверятьНаличиеТаблицыИзмененийДляКаждогоУзла = Ложь) Экспорт
Если КлючОбъекта = Неопределено Тогда
ВызватьИсключение "Изменение регистрации всех данных недопустимо";
КонецЕсли;
Если ТипЗнч(КлючОбъекта) = Тип("ОбъектМетаданных") Тогда
ОбъектМД = КлючОбъекта;
Иначе
ОбъектМД = Метаданные.НайтиПоТипу(ТипОбъектаБДЛкс(КлючОбъекта));
КонецЕсли;
Если РегистрироватьДвиженияВместеСДокументом Тогда
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ЭтоДокумент = ЛиКорневойТипДокументаЛкс(ПервыйФрагментЛкс(ПолноеИмяМД));
КонецЕсли;
Если РегистрироватьДвиженияВместеСДокументом И ЭтоДокумент И ТипЗнч(КлючОбъекта) = Тип("ОбъектМетаданных") Тогда
Запрос = Новый Запрос("ВЫБРАТЬ Т.Ссылка ИЗ " + ПолноеИмяМД + " КАК Т");
МассивОбъектов = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(0);
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(МассивОбъектов.Количество(), "Изменение регистрации");
Иначе
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(КлючОбъекта);
КонецЕсли;
Если ТипЗнч(УзелИлиМассив) = Тип("Массив") Тогда
Если УзелИлиМассив.Количество() > 0 Тогда
ОдинУзелОбмена = УзелИлиМассив[0];
Иначе
ОдинУзелОбмена = Неопределено;
КонецЕсли;
МассивУзлов = УзелИлиМассив;
Иначе
ОдинУзелОбмена = УзелИлиМассив;
МассивУзлов = Новый Массив;
МассивУзлов.Добавить(УзелИлиМассив);
КонецЕсли;
Если Не ЗначениеЗаполнено(ОдинУзелОбмена) Тогда
СообщитьЛкс("Не указан узел для регистрации изменений");
Возврат Ложь;
КонецЕсли;
Если ПроверятьНаличиеТаблицыИзмененийДляКаждогоУзла Тогда
УзлыДляРегистрации = ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(ОбъектМД, МассивУзлов);
Если УзлыДляРегистрации.Количество() = 0 Тогда
Возврат Истина;
КонецЕсли;
Иначе
УзлыДляРегистрации = МассивУзлов;
КонецЕсли;
Успех = Истина;
НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
Для Каждого Объект Из МассивОбъектов Цикл
Если Индикатор <> Неопределено Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
Если ТипЗнч(Объект) = Тип("Структура") Тогда
Объект = Объект.Методы;
КонецЕсли;
Если Истина
И ТипЗнч(Объект) = Тип("ОбъектМетаданных")
И Не ПравоДоступа("Изменение", Объект)
Тогда
ирОбщий.СообщитьЛкс(ирОбщий.СтрШаблонИменЛкс("Нет доступа к таблице %1",, Объект.ПолноеИмя()), СтатусСообщения.Внимание);
Продолжить;
КонецЕсли;
ИзменитьРегистрациюОбъектаДляУзлаЛкс(УзлыДляРегистрации, Объект, НовоеЗначение, ОдинУзелОбмена, НомерВерсииПлатформы);
Если РегистрироватьДвиженияВместеСДокументом И ЭтоДокумент Тогда
ОбъектыМД = ирОбщий.МетаданныеНаборовЗаписейПоРегистраторуЛкс(ОбъектМД, ДвиженияВместеСПоследовательностями, Истина);
Для Каждого МетаРегистр из ОбъектыМД Цикл
Если Не ОдинУзелОбмена.Метаданные().Состав.Содержит(МетаРегистр) Тогда
Если ПропускатьДвиженияВнеПланаОбмена Тогда
Продолжить;
Иначе
ВызватьИсключение "Движение документа по регистру " + МетаРегистр.ПолноеИмя() + " не может быть зарегистрировано в плане обмена " + ОдинУзелОбмена.Метаданные().Имя;
КонецЕсли;
КонецЕсли;
ИмяТаблицыБДРегистра = ирКэш.ИмяТаблицыИзМетаданныхЛкс(МетаРегистр.ПолноеИмя());
ИмяПоляОтбора = ирОбщий.ИмяПоляОтбораПодчиненногоНабораЗаписейЛкс(ИмяТаблицыБДРегистра);
СтруктураНабораЗаписей = ОбъектБДПоКлючуЛкс(ИмяТаблицыБДРегистра, Новый Структура(ИмяПоляОтбора, Объект.Ссылка),, Ложь);
ИзменитьРегистрациюОбъектаДляУзлаЛкс(УзлыДляРегистрации, СтруктураНабораЗаписей.Методы, НовоеЗначение, ОдинУзелОбмена, НомерВерсииПлатформы);
КонецЦикла;
КонецЕсли;
КонецЦикла;
Если Индикатор <> Неопределено Тогда
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
Возврат Успех;
КонецФункции
Процедура ИзменитьРегистрациюОбъектаДляУзлаЛкс(Знач УзлыДляРегистрации, Знач Объект, Знач НовоеЗначение, Знач ОдинУзелОбменаДляПроверки, Знач НомерВерсииПлатформы = "") Экспорт
НесобственныеУзлы = Новый Массив;
Для Каждого Узел Из УзлыДляРегистрации Цикл
Если ПланыОбмена[Метаданные.НайтиПоТипу(ТипЗнч(Узел)).Имя].ЭтотУзел() = Узел Тогда
// Изменение регистрации для собственных узлов выбросит исключение
Продолжить;
КонецЕсли;
НесобственныеУзлы.Добавить(Узел);
КонецЦикла;
ТипОбъекта = ТипЗнч(Объект);
ЭтоИмитатор = ЛиТипИмитатораОбъектаЛкс(ТипОбъекта);
Если ЭтоИмитатор Тогда
ОбъектXML = Объект.Снимок();
ирСервер.ИзменитьРегистрациюОбъектаДляУзлаЛкс(ОбъектXML, ТипОбъекта, НесобственныеУзлы, НовоеЗначение, ОдинУзелОбменаДляПроверки, НомерВерсииПлатформы);
Иначе
Если НовоеЗначение Тогда
ПланыОбмена.ЗарегистрироватьИзменения(НесобственныеУзлы, Объект);
Если НомерВерсииПлатформы = Неопределено Тогда
НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
КонецЕсли;
// Антибаг платформы 8.2.17-8.3.4
Если Истина
И НомерВерсииПлатформы < 803005
И ТипЗнч(Объект) <> Тип("ОбъектМетаданных")
И Не ПланыОбмена.ИзменениеЗарегистрировано(ОдинУзелОбменаДляПроверки, Объект)
Тогда
Успех = Ложь;
СообщитьЛкс(СтрШаблонИменЛкс("Не удалось зарегистрировать изменение %1 из-за ошибки платформы, исправленной в 8.3.5",, Объект));
КонецЕсли;
Иначе
ПланыОбмена.УдалитьРегистрациюИзменений(НесобственныеУзлы, Объект);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(ОбъектМД, МассивУзлов, ТолькоУзлыСАвторегистрацией = Ложь) Экспорт
УзлыДляРегистрации = Новый Массив;
Для Каждого ПроверяемыйУзел Из МассивУзлов Цикл
ЭлементСостава = ПроверяемыйУзел.Метаданные().Состав.Найти(ОбъектМД);
Если Истина
И ЭлементСостава <> Неопределено
И (Ложь
Или Не ТолькоУзлыСАвторегистрацией
Или ЭлементСостава.АвтоРегистрация = АвтоРегистрацияИзменений.Разрешить)
Тогда
УзлыДляРегистрации.Добавить(ПроверяемыйУзел);
КонецЕсли;
КонецЦикла;
Возврат УзлыДляРегистрации;
КонецФункции
// Копирует регистрацию изменений с узла источника на узлы приемники. Опционально каждый тип данных отдельно равномерно распределяется по узлам приемникам.
// Параметры:
// НомерСообщения - Неопределено - брать номер отправленного с узла, Null - не фильтровать но номеру сообщения, иначе выбираются все изменения с номером равным или меньшим заданного
// Возвращаемое значение: Массив - количество изменений зарегистрированных по каждому узлу
Функция СкопироватьРаспределитьРегистрациюИзмененийПоУзламЛкс(УзелИсточник, УзлыПриемники, Распределять = Ложь, НомерСообщения = Null, МассивМетаданных = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
УзелИсточник = ПланыОбмена.Полный.ПустаяСсылка();
УзлыПриемники = Новый Массив;
#КонецЕсли
#Если Клиент Тогда
СостояниеЛкс("Выбираем все изменения для узла…");
#КонецЕсли
Если НомерСообщения = Неопределено Тогда
НомерСообщения = УзелИсточник.НомерОтправленного;
КонецЕсли;
Результат = Новый Массив;
Для Счетчик = 1 По УзлыПриемники.Количество() Цикл
Если Распределять И ТипЗнч(УзлыПриемники[Счетчик - 1]) <> ТипЗнч(УзелИсточник) Тогда
ВызватьИсключение "Нельзя распределять на узлы другого плана обмена";
КонецЕсли;
Результат.Добавить(0);
КонецЦикла;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Узел", УзелИсточник);
Запрос.УстановитьПараметр("НомерСообщения", НомерСообщения);
МетаПланОбмена = УзелИсточник.Метаданные();
ТекстЗапроса = "";
ТипыДанныхЗапросов = Новый Массив;
Для Каждого ЭлементСостава Из МетаПланОбмена.Состав Цикл
МетаОбъект = ЭлементСостава.Метаданные;
Если Ложь
Или МетаОбъект = Неопределено
Или (Истина
И МассивМетаданных <> Неопределено
И МассивМетаданных.Найти(МетаОбъект) = Неопределено)
Тогда
Продолжить;
КонецЕсли;
Если ТекстЗапроса <> "" Тогда
ТекстЗапроса = ТекстЗапроса + ";" + Символы.ПС;
КонецЕсли;
ПолноеИмяМД = МетаОбъект.ПолноеИмя();
ТипыДанныхЗапросов.Добавить(ПолноеИмяМД);
ИмяТаблицыДляПоискаЗарегистрированных = СтрЗаменить(ПолноеИмяМД, ".Перерасчет.", ".") + ".Изменения";
ТекстЗапроса = ТекстЗапроса + "ВЫБРАТЬ *
|ИЗ
| " + ИмяТаблицыДляПоискаЗарегистрированных + " КАК РегистрацияИзменений
|ГДЕ
| РегистрацияИзменений.Узел = &Узел";
Если НомерСообщения <> Null Тогда
ТекстЗапроса = ТекстЗапроса = " И НомерСообщения <= &НомерСообщения";
КонецЕсли;
КонецЦикла;
Если ТекстЗапроса <> "" Тогда
Запрос.Текст = ТекстЗапроса;
РезультатПакета = Запрос.ВыполнитьПакет();
ИндикаторСостава = ПолучитьИндикаторПроцессаЛкс(РезультатПакета.Количество(), "Распределение изменений");
Для ИндексЗапроса = 0 По РезультатПакета.ВГраница() Цикл
ОбработатьИндикаторЛкс(ИндикаторСостава);
РезультатЗапроса = РезультатПакета[ИндексЗапроса];
#Если Сервер И Не Сервер Тогда
РезультатЗапроса1 = Новый Запрос;
РезультатЗапроса = РезультатЗапроса1.Выполнить();
#КонецЕсли
ПолноеИмяМД = ТипыДанныхЗапросов[ИндексЗапроса];
//Если Ложь
// Или РезультатЗапроса.Колонки.Найти("НомерСообщения1") <> Неопределено
// Или РезультатЗапроса.Колонки.Найти("Узел1") <> Неопределено
//Тогда
// ВызватьИсключение "В таблице " + ПолноеИмяМД + " в основной отбор включены измерения с запрещенными именами (НомерСообщения, Узел)";
//КонецЕсли;
ТаблицаКорректна = Истина;
Для Каждого КолонкаРезультата Из РезультатЗапроса.Колонки Цикл
Если Не ЭтоКорректноеПолеТаблицыИзмененийЛкс(ПолноеИмяМД, КолонкаРезультата.Имя) Тогда
СообщитьЛкс(СтрШаблонИменЛкс("Изменения таблицы %1 не были скопированы, т.к. она имеет некорректное поле %2, порожденное конфликтом имен полей", 1, ПолноеИмяМД, 2, КолонкаРезультата.Имя));
ТаблицаКорректна = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ТаблицаКорректна Тогда
Продолжить;
КонецЕсли;
МакетныйОбъект = "";
ТекущаяГруппаТипаМетаданных = "";
Выборка = РезультатЗапроса.Выбрать();
ИндексУзла = 0;
КоличествоЭлементов = Выборка.Количество();
Если КоличествоЭлементов > 0 Тогда
Если Распределять Тогда
УзлыРегистрации = УзлыПриемники;
Иначе
УзлыРегистрации = ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяМД), УзлыПриемники);
Если УзлыРегистрации.Количество() < УзлыПриемники.Количество() Тогда
СообщитьЛкс(СтрШаблонИменЛкс("Изменения таблицы %1 были скопированы не на все узлы, т.к. некоторые планы обмена приемников не содержат ее.",, ПолноеИмяМД));
КонецЕсли;
КонецЕсли;
Если УзлыРегистрации.Количество() > 0 Тогда
ИндикаторТаблицы = ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, ПолноеИмяМД);
ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяМД, МакетныйОбъект, ТекущаяГруппаТипаМетаданных); //, КлючевыеПоля
Пока Выборка.Следующий() Цикл
ОбработатьИндикаторЛкс(ИндикаторТаблицы);
Объект = ОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(Выборка, МакетныйОбъект, ТекущаяГруппаТипаМетаданных, Ложь, "НомерСообщения, Узел");
// Регистрация
Если Распределять Тогда
УзелПриемник = УзлыРегистрации[ИндексУзла];
ПланыОбменаИзменитьРегистрациюЛкс(УзелПриемник, Объект);
Результат[ИндексУзла] = Результат[ИндексУзла] + 1;
ИндексУзла = ИндексУзла + 1;
Если ИндексУзла = УзлыРегистрации.Количество() Тогда
ИндексУзла = 0;
КонецЕсли;
Иначе
ПланыОбменаИзменитьРегистрациюЛкс(УзлыРегистрации, Объект);
Результат[0] = Результат[0] + 1;
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЭтоКорректноеПолеТаблицыИзмененийЛкс(ПолноеИмяМД, ИмяПоля) Экспорт
Если Ложь
Или ирОбщий.СтрокиРавныЛкс(ИмяПоля, "Узел1")
Или ирОбщий.СтрокиРавныЛкс(ИмяПоля, "НомерСообщения1")
Тогда
//ПолноеИмяРегистра = ирОбщий.СтрокаМеждуМаркерамиЛкс(ПолноеИмяТаблицыБД,, ".Изменения");
КорневойТип = ПервыйФрагментЛкс(ПолноеИмяМД);
Если ЛиКорневойТипРегистраБДЛкс(КорневойТип) Тогда
ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяМД);
Если ОбъектМД <> Неопределено Тогда
Если ОбъектМД.Измерения.Найти("" + ИмяПоля) = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Истина;
КонецФункции
// ИгнорироватьКолонки - Строка - имена колонок через запятую, которые не будут учитываться
Функция ОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(Знач ДанныеСтроки, Знач МакетныйОбъект, Знач ТекущаяГруппаТипаМетаданных, СчитатьДанныеОбъекта = Истина,
Знач ИгнорироватьКолонки = "", Заблокировать = Ложь, ОбъектыНаСервере = Неопределено) Экспорт
Если ТекущаяГруппаТипаМетаданных = "Ссылочный" Тогда
ИмяСсылка = ирОбщий.ПеревестиСтроку("Ссылка");
СтруктураОбъекта = ДанныеСтроки[ИмяСсылка];
Если Заблокировать Тогда
ЗаблокироватьСсылкуВТранзакцииЛкс(СтруктураОбъекта);
КонецЕсли;
Если СчитатьДанныеОбъекта Тогда
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(СтруктураОбъекта.Метаданные().ПолноеИмя(), СтруктураОбъекта,,, ОбъектыНаСервере);
КонецЕсли;
ИначеЕсли ТекущаяГруппаТипаМетаданных = "Регистр" Тогда
Если ЛиКлючЗаписиРегистраЛкс(ДанныеСтроки) Тогда
ДанныеСтроки = ирОбщий.ДанныеСтрокиРегистраИзКлючаЗаписиЛкс(ДанныеСтроки);
КонецЕсли;
СтруктураОбъекта = МакетныйОбъект;
Если ЗначениеЗаполнено(ИгнорироватьКолонки) Тогда
ИгнорироватьКолонки = Нрег(ИгнорироватьКолонки) + ",";
КонецЕсли;
Для Каждого ЭлементОтбора Из СтруктураОбъекта.Методы.Отбор Цикл
Если Найти(ИгнорироватьКолонки, НРег(ЭлементОтбора.Имя) + ",") > 0 Тогда
Продолжить;
КонецЕсли;
Попытка
ЗначениеПоля = ДанныеСтроки[ЭлементОтбора.Имя];
Исключение
// Независимый регистр сведений, у измерения не включен ОсновнойОтбор
Продолжить;
КонецПопытки;
ЭлементОтбора.Значение = ЗначениеПоля;
ЭлементОтбора.Использование = Истина;
КонецЦикла;
Если Заблокировать Тогда
ЗаблокироватьНаборЗаписейПоОтборуЛкс(СтруктураОбъекта);
КонецЕсли;
Если СчитатьДанныеОбъекта Тогда
СтруктураОбъекта.Методы.Прочитать();
КонецЕсли;
ИначеЕсли ТекущаяГруппаТипаМетаданных = "Константа" Тогда
СтруктураОбъекта = МакетныйОбъект;
Если Заблокировать Тогда
ЗаблокироватьКонстантуЛкс(СтруктураОбъекта);
КонецЕсли;
Если СчитатьДанныеОбъекта Тогда
СтруктураОбъекта.Методы.Прочитать();
КонецЕсли;
КонецЕсли;
Возврат СтруктураОбъекта;
КонецФункции
// Добавляет глобальные переменные и методы в контекст поля текстового документа с контекстной подсказкой.
//
// Параметры
// ПолеТекстаПрограммы - ОбработкаОбъект.ПолеТекстаПрограммы.
//
Процедура ИнициироватьГлобальныйКонтекстПодсказкиЛкс(ПолеТекстаПрограммы) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекстаПрограммы = Обработки.ирКлсПолеТекстаПрограммы.Создать();
#КонецЕсли
Если ПолеТекстаПрограммы.ЯзыкПрограммы = 1 Тогда
Возврат;
КонецЕсли;
ПолеТекстаПрограммы.ОчиститьТаблицуСловЛокальногоКонтекста();
ПолеТекстаПрограммы.ДобавитьПравилоВычисленияФункции("ирКПА", "ПравилоВычисленияТипаЗначенияКПА");
МассивГлобальныхПеременных = Новый Массив;
МассивГлобальныхПеременных.Добавить("ирПлатформа");
Для Каждого ИмяГлобальнойПеременной Из МассивГлобальныхПеременных Цикл
Попытка
ГлобальнаяПеременная = ВычислитьВыражение(ИмяГлобальнойПеременной);
Исключение
// ирПлатформа может отсутствовать
Продолжить;
КонецПопытки;
МассивТипов = Новый Массив;
МассивТипов.Добавить(ТипЗнч(ГлобальнаяПеременная));
ПолеТекстаПрограммы.ДобавитьСловоЛокальногоКонтекста(
ИмяГлобальнойПеременной, "Свойство", Новый ОписаниеТипов(МассивТипов), ГлобальнаяПеременная, Истина);
КонецЦикла;
СтруктураГлобальныхФункций = Новый Структура;
СтруктураГлобальныхФункций.Вставить("Исследовать", Тип("Число"));
СтруктураГлобальныхФункций.Вставить("Отладить", Тип("Число"));
СтруктураГлобальныхФункций.Вставить("Оперировать", Тип("Число"));
СтруктураГлобальныхФункций.Вставить("Наблюдать");
Для Каждого ЭлементГлобальнойФункции Из СтруктураГлобальныхФункций Цикл
Если ТипЗнч(ЭлементГлобальнойФункции.Значение) = Тип("Тип") Тогда
МассивТипов = Новый Массив;
МассивТипов.Добавить(ЭлементГлобальнойФункции.Значение);
ОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
ИначеЕсли ТипЗнч(ЭлементГлобальнойФункции.Значение) = Тип("ОписаниеТипов") Тогда
ОписаниеТипов = ЭлементГлобальнойФункции.Значение;
КонецЕсли;
ПолеТекстаПрограммы.ДобавитьСловоЛокальногоКонтекста(
ЭлементГлобальнойФункции.Ключ, "Метод", ОписаниеТипов);
КонецЦикла;
КонецПроцедуры
// Параметры - ТаблицаЗначений с колонкой Имя
Функция ПроверитьТаблицуПараметровЛкс(Параметры, Заголовок = "") Экспорт
Результат = Истина;
Если Параметры.Количество() = 0 Тогда
Возврат Результат;
КонецЕсли;
Для Каждого СтрокаПараметра Из Параметры Цикл
Если Не ЛиИмяПеременнойЛкс(СтрокаПараметра.Имя) Тогда
Результат = Ложь;
СообщитьЛкс(Заголовок + СтрШаблонИменЛкс("Имя параметра %1 некорректно",, """" + СтрокаПараметра.Имя + """"), СтатусСообщения.Внимание);
КонецЕсли;
КонецЦикла;
НеуникальныеИмена = НеуникальныеЗначенияКолонкиТаблицыЛкс(Параметры, "Имя");
Для Каждого НеуникальноеИмя Из НеуникальныеИмена Цикл
СообщитьЛкс(Заголовок + СтрШаблонИменЛкс("Имя параметра %1 встречается более одного раза",, """" + НеуникальноеИмя + """"), СтатусСообщения.Внимание);
Результат = Ложь;
КонецЦикла;
Возврат Результат;
КонецФункции
// Возможно нужно объединить с ПолучитьМетаданныеЛкс
Функция ПолучитьМетаданныеПоПолномуИмениЛкс(ПолноеИмяМД) Экспорт
Объект = СоздатьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД);
Результат = Объект.Метаданные();
Возврат Результат;
КонецФункции
// Функция - Таблицы внешнего источника данных лкс
//
// Параметры:
// ОбъектМД - -
// ЛиОбъектные - Булево, *Ложь - Если Ложь то вернет только объектные таблицы, иначе - только необъектные
//
// Возвращаемое значение:
// -
//
Функция ТаблицыВнешнегоИсточникаДанныхЛкс(РодительскийОбъектМД, ЛиОбъектные = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
РодительскийОбъектМД = Метаданные.ВнешниеИсточникиДанных.ВнешнийИсточникДанных1;
#КонецЕсли
Результат = Новый Массив;
Для Каждого ОбъектМД Из РодительскийОбъектМД.Таблицы Цикл
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.ВнешниеИсточникиДанных.ВнешнийИсточникДанных1.Таблицы.Таблица1;
#КонецЕсли
Если Ложь
Или (ЛиОбъектные И ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.НеобъектныеДанные)
Или (Не ЛиОбъектные И ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные)
Тогда
Продолжить;
КонецЕсли;
Результат.Добавить(ОбъектМД);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция МножественноеИмяМДЛкс(Единственное) Экспорт
ТаблицаТиповМетаОбъектов = ирКэш.ТипыМетаОбъектов();
СтрокаТаблицы = ТаблицаТиповМетаОбъектов.Найти(НРег(Единственное), "НЕдинственное");
Если СтрокаТаблицы <> Неопределено Тогда
Результат = СтрокаТаблицы.Множественное;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЕдинственноеИмяМДЛкс(Множественное) Экспорт
ТаблицаТиповМетаОбъектов = ирКэш.ТипыМетаОбъектов();
СтрокаТаблицы = ТаблицаТиповМетаОбъектов.Найти(НРег(Множественное), "НМножественное");
Если СтрокаТаблицы <> Неопределено Тогда
Результат = СтрокаТаблицы.Единственное;
КонецЕсли;
Возврат Результат;
КонецФункции
// Получает тип из описания типов, типа или значения.
//
// Параметры:
// пОбъект - Тип, ОписаниеТипов, Произвольный - проверяемое значение.
//
// Возвращаемое значение:
// Тип - найденный тип.
//
Функция ПолучитьТипОбъектаЛкс(пОбъект)
ТипОбъекта = Тип("Неопределено");
ТипПараметра = ТипЗнч(пОбъект);
Если ТипПараметра = Тип("ОписаниеТипов") Тогда
Если пОбъект.Типы().Количество() > 0 Тогда
ТипОбъекта = пОбъект.Типы()[0];
КонецЕсли;
ИначеЕсли ТипПараметра <> Тип("Тип") Тогда
ТипОбъекта = ТипПараметра;
Иначе
ТипОбъекта = пОбъект;
КонецЕсли;
Возврат ТипОбъекта;
КонецФункции // ПолучитьТипОбъектаЛкс()
// Проверяет, является ли строка именем корневого типа объекта БД.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина - тип является корневым типом объекта БД;
// Ложь - иначе.
//
Функция ЛиКорневойТипСсылочногоОбъектаБДЛкс(Знач КорневойТип) Экспорт
Если Найти(КорневойТип, ".") > 0 Тогда
КорневойТип = ПервыйФрагментЛкс(КорневойТип);
КонецЕсли;
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "БизнесПроцесс"
ИЛИ КорневойТип = "Задача"
ИЛИ КорневойТип = "Документ"
ИЛИ КорневойТип = "ПланВидовРасчета"
ИЛИ КорневойТип = "ПланВидовХарактеристик"
ИЛИ КорневойТип = "ПланОбмена"
ИЛИ КорневойТип = "ПланСчетов"
ИЛИ КорневойТип = "Справочник"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипКонстантыЛкс(Знач КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "Константа"
ИЛИ КорневойТип = "Константы"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипПланаОбменаЛкс(Знач КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "ПланОбмена"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипДокументаЛкс(Знач КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "Документ"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипБизнесПроцессаЛкс(Знач КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "БизнесПроцесс"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Проверяет, является ли строка именем корневого типа ссылки.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина - тип является корневым типом ссылки;
// Ложь - иначе.
//
Функция ЛиКорневойТипСсылкиЛкс(Знач КорневойТип, ИсключаяСсылкиМетаданных = Ложь) Экспорт
Если Найти(КорневойТип, ".") > 0 Тогда
КорневойТип = ПервыйФрагментЛкс(КорневойТип);
КонецЕсли;
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ Не ИсключаяСсылкиМетаданных И КорневойТип = "Перечисление"
ИЛИ Не ИсключаяСсылкиМетаданных И КорневойТип = "Точки" // Грязно
ИЛИ ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Проверяет, является ли строка именем корневого типа регистра БД.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина - тип является корневым типом регистра БД;
// Ложь - иначе.
//
Функция ЛиКорневойТипРегистраБДЛкс(Знач КорневойТип, СчитатьПоследовательностьРегистром = Истина) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "РегистрСведений"
ИЛИ КорневойТип = "РегистрНакопления"
ИЛИ КорневойТип = "РегистрБухгалтерии"
ИЛИ КорневойТип = "ДвиженияССубконто"
ИЛИ КорневойТип = "РегистрРасчета"
ИЛИ КорневойТип = "Перерасчет"
ИЛИ (Истина
И СчитатьПоследовательностьРегистром
И КорневойТип = "Последовательность")
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипРегистраРасчетаЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если КорневойТип = "РегистрРасчета" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипРегистраСведенийЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если КорневойТип = "РегистрСведений" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипРегистраБухгалтерииЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если КорневойТип = "РегистрБухгалтерии" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипРегистраНакопленияЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если КорневойТип = "РегистрНакопления" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипПоследовательностиЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если КорневойТип = "Последовательность" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если КорневойТип = "ВнешнийИсточникДанных" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипПеречисленияЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если КорневойТип = "Перечисление" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиТипТаблицыМетассылкиЛкс(ТипТаблицы) Экспорт
Если КодСимвола(ТипТаблицы, 1) < 128 Тогда
ТипТаблицы = ПеревестиВРусский(ТипТаблицы);
КонецЕсли;
Если Ложь
ИЛИ ТипТаблицы = "Перечисление"
ИЛИ ТипТаблицы = "Точки"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "ЖурналДокументов"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипКритерияОтбораЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "КритерийОтбора"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипТаблицыБДЛкс(КорневойТип, ВключаяВнешниеИсточникиДанных = Истина) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
Или ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип)
Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип)
Или ЛиКорневойТипРегистраБДЛкс(КорневойТип)
Или (ВключаяВнешниеИсточникиДанных И ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип))
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Проверяет, является ли строка именем типа вложенной таблицы БД.
//
// Параметры:
// ТипТаблицы - Строка, Неопределено - имя типа таблицы.
//
// Возвращаемое значение:
// Булево.
//
Функция ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Экспорт
Если КодСимвола(ТипТаблицы, 1) < 128 Тогда
ТипТаблицы = ПеревестиВРусский(ТипТаблицы);
КонецЕсли;
Если Ложь
ИЛИ ТипТаблицы = "ТабличнаяЧасть"
ИЛИ ЛиИмяПредопределеннойТабличнойЧастиЛкс(ТипТаблицы)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиИмяПредопределеннойТабличнойЧастиЛкс(ТипТаблицы) Экспорт
Если КодСимвола(ТипТаблицы, 1) < 128 Тогда
ТипТаблицы = ПеревестиВРусский(ТипТаблицы);
КонецЕсли;
Если Ложь
ИЛИ ТипТаблицы = "ВидыСубконто"
ИЛИ ТипТаблицы = "БазовыеВидыРасчета"
ИЛИ ТипТаблицы = "ВедущиеВидыРасчета"
ИЛИ ТипТаблицы = "ВытесняющиеВидыРасчета"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Проверяет, корневой тип на наличие реквизита "Код".
//
// Параметры:
// КорневойТип - Строка, Произвольный.
//
// Возвращаемое значение:
// Истина - реквизит "Код" имеется;
// Ложь - иначе.
//
Функция ЛиКорневойТипОбъектаСКодомЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
Или КорневойТип = "ПланВидовХарактеристик"
Или КорневойТип = "ПланОбмена"
Или КорневойТип = "ПланСчетов"
Или КорневойТип = "ПланРасчета"
Или КорневойТип = "Справочник"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипОбъектаСКодомЛкс()
// Проверяет, корневой тип на наличие реквизита "Предопределенный".
//
// Параметры:
// КорневойТип - Строка, Произвольный.
//
// Возвращаемое значение:
// Истина - реквизит "Предопределенный" имеется;
// Ложь - иначе.
//
Функция ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
Или КорневойТип = "Справочник"
Или КорневойТип = "ПланСчетов"
Или КорневойТип = "ПланВидовХарактеристик"
Или КорневойТип = "ПланВидовРасчета"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипОбъектаСПредопределеннымЛкс()
Функция ЛиМетаданныеВнешнегоИсточникаДанныхЛкс(ОбъектМД) Экспорт
Если ОбъектМД = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КорневойТип = КорневойТипКонфигурацииЛкс(ОбъектМД);
Возврат ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип);
КонецФункции
// Проверяет, метаданные на иерархию.
// Иначе говоря проверяется наличие реквизита "Родитель".
//
// Параметры:
// пМетаданныеТипа - ОбъектМетаданных, Неопределено.
//
// Возвращаемое значение:
// Истина - метаданные с иерархией;
// Ложь - иначе.
//
Функция ЛиМетаданныеИерархическогоОбъектаЛкс(ОбъектМД) Экспорт
Если ОбъектМД = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КорневойТип = КорневойТипКонфигурацииЛкс(ОбъектМД);
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
Или КорневойТип = "ПланСчетов"
Или (Истина
И (Ложь
Или КорневойТип = "Справочник"
Или КорневойТип = "ПланВидовХарактеристик")
И ОбъектМД.Иерархический)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМетаданныеИерархическогоОбъектаЛкс()
// Проверяет, метаданные на иерархию.
// Иначе говоря проверяется начилие реквизита "Родитель".
//
// Параметры:
// пМетаданныеТипа - ОбъектМетаданных, Неопределено.
//
// Возвращаемое значение:
// Истина - метаданные с иерархией;
// Ложь - иначе.
//
Функция ЛиМетаданныеПодчиненногоОбъектаЛкс(ОбъектМД) Экспорт
Если ОбъектМД = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КорневойТип = КорневойТипКонфигурацииЛкс(ОбъектМД);
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Истина
И (Ложь
Или КорневойТип = "Справочник"
Или КорневойТип = "ПланВидовХарактеристик")
И ОбъектМД.Владельцы.Количество() > 0
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМетаданныеИерархическогоОбъектаЛкс()
// Проверяет, метаданные на иерархию с группами.
// Иначе говоря проверяется начилие реквизита "ЭтоГруппа".
//
// Параметры:
// пМетаданныеТипа - ОбъектМетаданных, Неопределено.
//
// Возвращаемое значение:
// Истина - метаданные с иерархией групп;
// Ложь - иначе.
//
Функция ЛиМетаданныеОбъектаСГруппамиЛкс(ОбъектМД) Экспорт
Если ОбъектМД = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КорневойТип = КорневойТипКонфигурацииЛкс(ОбъектМД, Истина);
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
Или (Истина
И КорневойТип = "Справочник"
И ОбъектМД.Иерархический
И ОбъектМД.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов)
Или (Истина
И КорневойТип = "ПланВидовХарактеристик"
И ОбъектМД.Иерархический)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Функция - Ли метаданные ссылочного объекта лкс
//
// Параметры:
// ОбъектМД - -
// ДляТабличнойЧастиПроверятьРодителя - -
// ИсключаяСсылкиМетаданных - -
// ИсключаяВнешниеИсточникиДанных - -
// ФрагментыИмени - Массив - можно передавать для ускорения
//
// Возвращаемое значение:
// -
//
Функция ЛиМетаданныеСсылочногоОбъектаЛкс(ОбъектМД, ДляТабличнойЧастиПроверятьРодителя = Ложь, ИсключаяСсылкиМетаданных = Ложь, ИсключаяВнешниеИсточникиДанных = Ложь,
Знач ФрагментыИмени = Неопределено) Экспорт
Если ОбъектМД = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Если ФрагментыИмени = Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.РегистрыСведений.КурсыВалют;
#КонецЕсли
Фрагменты = СтрРазделитьЛкс(ОбъектМД.ПолноеИмя());
Иначе
Фрагменты = ФрагментыИмени;
КонецЕсли;
КорневойТип = Фрагменты[0];
Если Истина
И Не ИсключаяВнешниеИсточникиДанных
И Фрагменты.Количество() = 4
И ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип)
Тогда
Возврат (ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные);
Иначе
Если Истина
И Не ДляТабличнойЧастиПроверятьРодителя
И Фрагменты.Количество() > 2
Тогда
Возврат Ложь;
КонецЕсли;
Если ЛиКорневойТипСсылкиЛкс(КорневойТип, ИсключаяСсылкиМетаданных) Тогда
Возврат Истина;
Иначе
Возврат Ложь;
КонецЕсли;
КонецЕсли;
КонецФункции
Функция ЛиМетаданныеРегистраЛкс(ОбъектМД, СчитатьПоследовательностьРегистром = Истина) Экспорт
Если ОбъектМД = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.РегистрыСведений.КурсыВалют;
#КонецЕсли
Фрагменты = СтрРазделитьЛкс(ОбъектМД.ПолноеИмя());
КорневойТип = Фрагменты[0];
Если ЛиКорневойТипРегистраБДЛкс(КорневойТип, СчитатьПоследовательностьРегистром) Тогда
Возврат Истина;
ИначеЕсли Истина
И Фрагменты.Количество() = 4
И ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип)
Тогда
Возврат (ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.НеобъектныеДанные);
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
Функция ЛиМетаданныеНезависимогоРегистраЛкс(ОбъектМД) Экспорт
Если ОбъектМД = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.РегистрыСведений.КурсыВалют;
#КонецЕсли
Фрагменты = СтрРазделитьЛкс(ОбъектМД.ПолноеИмя());
КорневойТип = Фрагменты[0];
ЭтоНезависимыйРегистр = Ложь
Или (Истина
И ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип)
И ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.НеобъектныеДанные)
Или (Истина
И ирОбщий.ЛиКорневойТипРегистраСведенийЛкс(КорневойТип)
И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.Независимый);
Возврат ЭтоНезависимыйРегистр;
КонецФункции
// https://www.hostedredmine.com/issues/895490
Функция ЛиДоступноРедактированиеВФормеОбъектаЛкс(ОбъектМД) Экспорт
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Справочники.Валюты;
#КонецЕсли
Результат = Истина;
//Если Ложь
// #Если ТолстыйКлиентУправляемоеПриложение Тогда
// Или Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.ОбычноеПриложение
// #ИначеЕсли ТолстыйКлиентОбычноеПриложение Тогда
// Или Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение
// Или ирОбщий.ТипТаблицыБДЛкс(ОбъектМД.ПолноеИмя()) = "Внешняя" // Обычные формы для таблиц внешних источников не обеспечивает платформа
// #КонецЕсли
//Тогда
Если ирОбщий.ЛиМетаданныеРегистраЛкс(ОбъектМД) Тогда
ИмяФормы = "ФормаЗаписи";
Иначе
ИмяФормы = "ФормаОбъекта";
КонецЕсли;
Попытка
ОсновнаяФорма = ОбъектМД["Основная" + ИмяФормы];
Исключение
ОсновнаяФорма = Неопределено;
КонецПопытки;
Если ОсновнаяФорма = Неопределено Тогда
Результат = Ложь;
КонецЕсли;
//КонецЕсли;
Возврат Результат;
КонецФункции
// Проверяет, является ли значение ссылкой на объект БД.
//
// Параметры:
// пЗначение - ОбъектМетаданных, Произвольный - проверяемое значение.
//
// Возвращаемое значение:
// Истина - значение является ссылкой на объект БД;
// Ложь - значение не является ссылкой на объект БД.
//
Функция ЛиСсылкаНаОбъектБДЛкс(Знач пЗначение, ИсключаяСсылкиМетаданных = Истина) Экспорт
//Результат = ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТипКонфигурацииЛкс(пЗначение, Истина));
Результат = ЛиТипСсылкиБДЛкс(ТипЗнч(пЗначение), ИсключаяСсылкиМетаданных);
Возврат Результат;
КонецФункции // ЛиСсылкаНаОбъектБДЛкс
Функция ЛиТипСсылкиБДЛкс(Знач Тип, Знач ИсключаяСсылкиМетаданных = Истина) Экспорт
Результат = Ложь;
ХмлТип = XMLТип(Тип);
Если ХмлТип <> Неопределено Тогда
Если Найти(ХмлТип.ИмяТипа, "Ref.") > 0 Тогда
Если Ложь
Или Не ИсключаяСсылкиМетаданных
Или (Истина
И Найти(ХмлТип.ИмяТипа, "BusinessProcessRoutePointRef.") = 0
И Найти(ХмлТип.ИмяТипа, "EnumRef.") = 0)
Тогда
Результат = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Не поддерживает имитаторы
Функция ЛиТипОбъектаБДЛкс(Тип) Экспорт
Результат = Ложь;
ХмлТип = XMLТип(Тип);
Если ХмлТип <> Неопределено Тогда
Если Ложь
Или Найти(ХмлТип.ИмяТипа, "Object.") > 0
Или Найти(ХмлТип.ИмяТипа, "RecordSet.") > 0
Или Найти(ХмлТип.ИмяТипа, "ValueManager.") > 0
Тогда
Результат = Истина;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиТипСсылкиТочкиМаршрутаЛкс(Тип) Экспорт
XMLТип = XMLТип(Тип);
Если XMLТип <> Неопределено Тогда
Если Найти(XMLТип.ИмяТипа, "BusinessProcessRoutePointRef.") > 0 Тогда
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиТипСсылкиВнешнейТаблицыЛкс(Тип) Экспорт
XMLТип = XMLТип(Тип);
Если XMLТип <> Неопределено Тогда
Если Найти(XMLТип.ИмяТипа, "ExternalDataSourceTableRef.") > 0 Тогда
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Получить структуру отбора по связям И параметрам выбора
//
// Параметры:
// ЭтотОбъект - - <тип> -
// ПолеФормыИлиРеквизитМетаданных - - <тип> -
// СтруктураТЧ - Структура - один элемент, ключ не играет роли (оставлено для совместимости)
// ДляОчистки - - <тип>, Ложь -
//
// Возвращаемое значение:
// -
//
Функция СтруктураОтбораПоСвязямИПараметрамВыбораЛкс(ПолеФормыИлиРеквизитМетаданных, ЭтотОбъект = Неопределено, СтруктураТЧ = Неопределено, ДляОчистки = Ложь) Экспорт
Попытка
СвязиПараметровВыбора = ПолеФормыИлиРеквизитМетаданных.СвязиПараметровВыбора;
Исключение
Возврат Новый Структура();
КонецПопытки;
ПараметрыВыбора = ПолеФормыИлиРеквизитМетаданных.ПараметрыВыбора;
Результат = Новый Структура("Отбор", Новый Структура);
Для Каждого СвязьПараметраВыбора Из СвязиПараметровВыбора Цикл
#Если Сервер И Не Сервер Тогда
СвязьПараметраВыбора = Новый СвязьПараметраВыбора;
#КонецЕсли
Если Истина
И ДляОчистки
И СвязьПараметраВыбора.ИзменениеЗначения = РежимИзмененияСвязанногоЗначения.НеИзменять
Тогда
Продолжить;
КонецЕсли;
ПолныйПутьКДанным = "ЭтотОбъект." + СвязьПараметраВыбора.ПутьКДанным;
Если СтруктураТЧ <> Неопределено Тогда
КлючИЗначениеТЧ = Неопределено;
Для Каждого КлючИЗначение Из СтруктураТЧ Цикл
КлючИЗначениеТЧ = КлючИЗначение;
Прервать;
КонецЦикла;
//Если ирОбщий.СтрокиРавныЛкс(ирОбщий.ПервыйФрагментЛкс(СвязьПараметраВыбора.ПутьКДанным), КлючИЗначениеТЧ.Ключ) Тогда
// ПолныйПутьКДанным = "СтруктураТЧ." + СвязьПараметраВыбора.ПутьКДанным;
//КонецЕсли;
Если СтрЧислоВхождений(СвязьПараметраВыбора.ПутьКДанным, ".") = 1 Тогда
ПолныйПутьКДанным = "СтруктураТЧ." + КлючИЗначениеТЧ.Ключ + "." + ПоследнийФрагментЛкс(СвязьПараметраВыбора.ПутьКДанным);
КонецЕсли;
КонецЕсли;
Попытка
ЗначениеДанных = Вычислить(ПолныйПутьКДанным);
Исключение
// Например поле таблицы или на сервере текущая строка таблицы
Продолжить;
КонецПопытки;
УстановитьВложенноеСвойствоСтруктурыЛкс(Результат, СвязьПараметраВыбора.Имя, ЗначениеДанных);
КонецЦикла;
Для Каждого ПараметрВыбора Из ПараметрыВыбора Цикл
#Если Сервер И Не Сервер Тогда
ПараметрВыбора = Новый ПараметрВыбора;
#КонецЕсли
УстановитьВложенноеСвойствоСтруктурыЛкс(Результат, ПараметрВыбора.Имя, ПараметрВыбора.Значение);
КонецЦикла;
Результат = Результат.Отбор; // Возможно потом перейдем везде на передачу полной структуры
Возврат Результат;
КонецФункции
Процедура УстановитьВложенноеСвойствоСтруктурыЛкс(Знач НачальнаяСтруктура, Знач ПолноеИмяСвойства, Знач ЗначениеДанных)
Фрагменты = СтрРазделитьЛкс("_." + ПолноеИмяСвойства);
ТекущаяСтруктура = Новый Структура("_", НачальнаяСтруктура);
Для Индекс = 0 По Фрагменты.Вграница() - 1 Цикл
ТекущаяСтруктура = ТекущаяСтруктура[Фрагменты[Индекс]];
Если Не ТекущаяСтруктура.Свойство(Фрагменты[Индекс + 1]) Тогда
ТекущаяСтруктура.Вставить(Фрагменты[Индекс + 1], Новый Структура);
КонецЕсли;
КонецЦикла;
ТекущаяСтруктура[Фрагменты[Фрагменты.Вграница()]] = ЗначениеДанных;
КонецПроцедуры
// Проверяет, является ли значение ссылкой на значение перечисления.
//
// Параметры:
// пЗначение - Произвольный - проверяемое значение.
//
// Возвращаемое значение:
// Истина - значение является ссылкой на объект БД;
// Ложь - значение не является ссылкой на объект БД.
//
Функция ЛиСсылкаНаПеречислениеЛкс(пЗначение) Экспорт
Возврат (КорневойТипКонфигурацииЛкс(пЗначение) = "Перечисление");
КонецФункции
// Проверка с учетом мультиязычности встроенного языка
Функция ЛиТипыРегистровРодственныЛкс(Знач Объект, Знач Подтип, Знач КоличествоСлов) Экспорт
ТипОбразец = ирКэш.ЛюбойТипРегистраЛкс(Подтип);
Если ТипОбразец = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Результат = ЛиПодтипыТиповРавныЛкс(ТипОбразец, Объект, КоличествоСлов);
Возврат Результат;
КонецФункции
// Проверка родственности типов, производных от метаданных
//
// Параметры:
// ТипОбразец - Тип -
// ОбъектИлиТип - -
// КоличествоСлов - Число - количество слов представления типа перед двоеточием, обозначающих подтип
//
// Возвращаемое значение:
// - Булево
//
Функция ЛиПодтипыТиповРавныЛкс(Знач ТипОбразец, Знач ОбъектИлиТип, Знач КоличествоСлов)
МаркерТипа = ирКэш.МаркерПодтипаИзТипаЛкс("" + ТипОбразец, КоличествоСлов);
ПредставлениеОбъекта = ПервыйФрагментЛкс(ПолучитьТипОбъектаЛкс(ОбъектИлиТип), ":");
Результат = СтрКончаетсяНаЛкс(ПредставлениеОбъекта, МаркерТипа);
Возврат Результат;
КонецФункции
// Проверяет, является ли ключом записи регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект - Тип, ОписаниеТипов, Произвольный - проверяемое значение.
//
// Возвращаемое значение:
// Истина - тип ключа записи регистра подтвержден;
// Ложь - тип ключа записи регистра не подтвержден.
//
Функция ЛиКлючЗаписиРегистраЛкс(Объект, _ИсключаяВнешниеИсточникиДанных = Ложь) Экспорт
Результат = ЛиТипыРегистровРодственныЛкс(Объект, "КлючЗаписи", 2);
Возврат Результат;
КонецФункции
&НаКлиенте
Функция ЛиКлючСсылкиИлиРегистраЛкс(Знач Объект) Экспорт
Возврат Ложь
Или ЛиСсылкаНаОбъектБДЛкс(Объект)
Или ЛиКлючЗаписиРегистраЛкс(Объект);
КонецФункции
// Проверяет, является ли записью регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект - Тип, ОписаниеТипов, Произвольный - проверяемое значение.
//
// Возвращаемое значение:
// Истина - тип записи регистра подтвержден;
// Ложь - тип записи регистра не подтвержден.
//
Функция ЛиЗаписьРегистраЛкс(Объект) Экспорт
Результат = ЛиТипыРегистровРодственныЛкс(Объект, "Запись", 1);
Возврат Результат;
КонецФункции
// Проверяет, является ли набором записей регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект - Тип, ОписаниеТипов, Произвольный - проверяемое значение.
//
// Возвращаемое значение:
// Истина - тип набора записей регистра подтвержден;
// Ложь - тип набора записей регистра не подтвержден.
//
Функция ЛиНаборЗаписейРегистраЛкс(Объект) Экспорт
Результат = ЛиТипыРегистровРодственныЛкс(Объект, "НаборЗаписей", 2);
Возврат Результат;
КонецФункции
// Проверяет, является ли менеджером записи регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект - Тип, ОписаниеТипов, Произвольный - проверяемое значение.
//
// Возвращаемое значение:
// Истина - тип менеджер записи регистра подтвержден;
// Ложь - тип менеджер записи регистра не подтвержден.
//
Функция ЛиМенеджерЗаписиРегистраЛкс(Объект) Экспорт
Результат = ЛиТипыРегистровРодственныЛкс(Объект, "МенеджерЗаписи", 2);
Возврат Результат;
КонецФункции
Функция ЛиТабличнаяЧастьЛкс(Знач ТипЗначенияИлиОбъект) Экспорт
Результат = ЛиПодтипыТиповРавныЛкс(ирКэш.ЛюбойТипТабличнойЧастиЛкс(), ТипЗначенияИлиОбъект, 2);
Возврат Результат;
КонецФункции
Функция ЛиСтрокаТабличнойЧастиЛкс(Знач ТипЗначенияИлиОбъект) Экспорт
Результат = ЛиПодтипыТиповРавныЛкс(ирКэш.ЛюбойТипСтрокиТабличнойЧастиЛкс(), ТипЗначенияИлиОбъект, 3);
Возврат Результат;
КонецФункции
// Проверяет, является ли субконтом описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект - Тип, ОписаниеТипов, Произвольный - проверяемое значение.
//
// Возвращаемое значение:
// Истина - тип субконто подтвержден;
// Ложь - тип субконто не подтвержден.
//
Функция ЛиСубконтоЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "субконто:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиСубконтоЛкс()
// Проверяет, является ли значение табличной частью внешней обработки.
//
// Параметры:
// пЗначение - Произвольный - проверяемое значение.
//
// Возвращаемое значение:
// Истина - значение является табличной частью внешней обработки;
// Ложь - значение не является табличной частью внешней обработки.
//
Функция ЛиТабличнаяЧастьВнешнейОбработкиЛкс(Объект) Экспорт
Результат = "ВнешняяОбработкаТабличнаяЧасть" = ПервыйФрагментЛкс(Строка(Объект));
Возврат Результат;
КонецФункции
Функция ЛиВнешняяОбработкаЛкс(Объект) Экспорт
Результат = "ВнешняяОбработкаОбъект" = ПервыйФрагментЛкс(Строка(Объект));
Возврат Результат;
КонецФункции
// Получает ссылочный тип по метаданным.
//
// Параметры:
// пМетаданные - ОбъектМетаданных.
//
// Возвращаемое значение:
// - Тип - ссылочный;
// Неопределено - тип нельзя получить.
//
Функция ПолучитьСсылочныйТипПоМетаданнымЛкс(пМетаданные) Экспорт
Результат = Неопределено;
КорневойТип = КорневойТипКонфигурацииЛкс(пМетаданные, Истина);
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
Результат = Тип(КорневойТип + "Ссылка." + пМетаданные.Имя);
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьСсылочныйТипПоМетаданнымЛкс()
// Получает метаданные по полному имени, описанию типов, типу, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект - Произвольный - для чего получаем метаданные.
//
// Возвращаемое значение:
// - Метаданные - полученные;
// Неопределено - не удалось получить метаданные.
//
Функция ПолучитьМетаданныеЛкс(пОбъект) Экспорт
Если ТипЗнч(пОбъект) = Тип("Строка") Тогда
Если ПустаяСтрока(пОбъект) Тогда
Результат = Неопределено;
Иначе
Фрагменты = СтрРазделитьЛкс(пОбъект);
#Если Сервер И Не Сервер Тогда
Фрагменты = Новый Массив;
#КонецЕсли
Если Фрагменты.Количество() % 2 = 1 Тогда
// ВидыСубконто, Изменения
Фрагменты.Удалить(Фрагменты.ВГраница());
ПолноеИмяМД = СтрСоединитьЛкс(Фрагменты, ".");
Иначе
ПолноеИмяМД = пОбъект;
КонецЕсли;
Результат = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяМД);
КонецЕсли;
Возврат Результат;
КонецЕсли;
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Результат = Метаданные.НайтиПоТипу(ТипОбъекта);
Возврат Результат;
КонецФункции
// Получает метаданные списка по описанию типов, типу или значению.
// Для описания типов берется первый тип массива типов.
//
//
// Параметры:
// пОбъект - Произвольное - проверяемое значение.
//
// Возвращаемое значение:
// - Метаданные - списка;
// Неопределено - значение не является списком.
//
Функция ПолучитьМетаданныеСпискаЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
МаркерСписка = "список:";
Если Найти(Строка(ТипОбъекта), МаркерСписка) > 0 Тогда
Возврат ПолучитьМетаданныеЛкс(ТипОбъекта);
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции // ПолучитьМетаданныеСпискаЛкс()
// Определяет корневой тип конфигурации по описанию типов, типу, метаданным, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект - Произвольный - для чего получаем метаданные;
// *пЛиТолькоДляКорневого - Булево, *Ложь - возвращать только для объекта корневого типа.
//
// Возвращаемое значение:
// - Строка - имя типа корневого объекта метаданных;
// Неопределено - не удалось получить имя типа.
//
Функция КорневойТипКонфигурацииЛкс(пОбъект, пЛиТолькоДляКорневого = Ложь) Экспорт
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
МетаданныеТипа = пОбъект;
Иначе
МетаданныеТипа = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
Результат = Неопределено;
Если МетаданныеТипа <> Неопределено Тогда
ПолноеИмя = МетаданныеТипа.ПолноеИмя();
Если пЛиТолькоДляКорневого Тогда
МассивФрагментов = СтрРазделитьЛкс(ПолноеИмя);
Если МассивФрагментов.Количество() = 2 Тогда
Результат = МассивФрагментов[0];
КонецЕсли;
Иначе
Результат = ПервыйФрагментЛкс(ПолноеИмя);
КонецЕсли;
//Если Результат = "ВнешнийИсточникДанных" Тогда
// Результат = Результат + "Таблица";
//КонецЕсли;
Результат = ПеревестиВРусский(Результат);
КонецЕсли;
Если Результат = "ТабличнаяЧасть" Тогда
// Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции // КорневойТипКонфигурацииЛкс()
// Определяет имя корневого типа строки табличной части по описанию типов, типу или значению.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект - Произвольный - для чего получаем корневой тип строки табличной части.
//
// Возвращаемое значение:
// - Строка - имя типа корневого объекта метаданных;
// Неопределено - значение не является строкой табличной части.
//
Функция КорневойТипСтрокиТабличнойЧастиЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "табличная часть строка:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат ПервыйФрагментЛкс(Метаданные.НайтиПоТипу(ТипОбъекта).ПолноеИмя());
КонецЕсли;
Возврат Неопределено;
КонецФункции // КорневойТипСтрокиТабличнойЧастиЛкс()
// Определяет имя корневого типа табличной части по описанию типов, типу, метаданным, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект - Произвольный - для чего определяем корневой тип.
//
// Возвращаемое значение:
// - Строка - имя типа корневого объекта метаданных;
// Неопределено - значение не является строкой табличной части.
//
Функция ПолучитьКорневойТипТабличнойЧастиЛкс(пОбъект) Экспорт
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
МетаданныеТипа = пОбъект;
Иначе
МетаданныеТипа = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
Если МетаданныеТипа <> Неопределено Тогда
ПолноеИмя = МетаданныеТипа.ПолноеИмя();
МассивФрагментов = СтрРазделитьЛкс(ПолноеИмя);
Если Истина
И МассивФрагментов.Количество() >= 4
И МассивФрагментов[2] = "ТабличнаяЧасть"
Тогда
Возврат МассивФрагментов[2];
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьКорневойТипТабличнойЧастиЛкс()
// Определяет имя корневого типа списка по описанию типов, типу или значению.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект - Произвольный - для чего получаем корневой тип строки табличной части.
//
// Возвращаемое значение:
// - Строка - имя типа корневого объекта метаданных;
// Неопределено - значение не является списком.
//
Функция ПолучитьКорневойТипСпискаЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "список:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат ПервыйФрагментЛкс(Метаданные.НайтиПоТипу(ТипОбъекта).ПолноеИмя());
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьКорневойТипСпискаЛкс()
// Определяет имя табличной части по ее метаданным.
//
// Параметры:
// пМетаданные - ОбъектМетаданных - который проверяем.
//
// Возвращаемое значение:
// - Строка - имя табличной части;
// Неопределено - это метаданные не табличной части.
//
Функция ПолучитьИмяТабличнойЧастиЛкс(пМетаданные) Экспорт
Если пМетаданные <> Неопределено Тогда
МассивФрагментов = СтрРазделитьЛкс(пМетаданные.ПолноеИмя());
Если МассивФрагментов.ВГраница() >= 2 Тогда
Если МассивФрагментов[2] = "ТабличнаяЧасть" Тогда
Возврат МассивФрагментов[3];
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьИмяТабличнойЧастиЛкс()
// Получает менеджер по описанию типов, типу, метаданным, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект - Произвольный - для чего получаем менеджер.
//
// Возвращаемое значение:
// - МенеджерОбъекта - для ссылки или ссылочного типа;
// Неопределено - не удалось получить.
//
Функция ПолучитьМенеджерЛкс(пОбъект) Экспорт
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
МетаданныеОбъекта = пОбъект;
Иначе
МетаданныеОбъекта = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
Если МетаданныеОбъекта = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
МассивФрагментов = СтрРазделитьЛкс(МетаданныеОбъекта.ПолноеИмя());
КорневойТип = МассивФрагментов[0];
Менеджер = Неопределено;
Если Истина
И МассивФрагментов.Количество() = 4
И ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип)
Тогда
ИмяТипаМенеджера = МассивФрагментов[0] + ПеревестиСтроку("ТаблицаМенеджер") + "." + МассивФрагментов[1] + "." + МассивФрагментов[3];
Иначе
//КорневойТип = КорневойТипКонфигурацииЛкс(МетаданныеОбъекта, Истина); // Изменил 02.03.2012
Если КорневойТип <> Неопределено Тогда
ИмяТипаМенеджера = КорневойТип + ПеревестиСтроку("Менеджер") + "." + МетаданныеОбъекта.Имя;
Иначе
ИмяТипаМенеджера = "Неопределено";
КонецЕсли;
КонецЕсли;
Попытка
Менеджер = Новый (ИмяТипаМенеджера);
Исключение
КонецПопытки;
Возврат Менеджер;
КонецФункции // ПолучитьМенеджерЛкс()
// Получает запись регистра по ключу записи.
//
// Параметры:
// пКлючЗаписи - КлючЗаписиРегистра - идентифицирующий запись.
//
// Возвращаемое значение:
// - ЗаписьРегистра - найденная запись.
//
Функция ПолучитьЗаписьРегистраПоКлючуЛкс(пКлючЗаписи) Экспорт
МенеджерЗначения = ПолучитьМенеджерЛкс(пКлючЗаписи);
МенеджерЗаписи = МенеджерЗначения.СоздатьМенеджерЗаписи();
ЗаполнитьЗначенияСвойств(МенеджерЗаписи, пКлючЗаписи);
МенеджерЗаписи.Прочитать();
Возврат МенеджерЗаписи;
КонецФункции // ПолучитьЗаписьРегистраПоКлючуЛкс()
// Больше не используется. Кандидат на удаление.
// Получает список реквизитов объекта БД.
//
// Параметры:
// пОбъект - определитель объекта метаданных;
// *ЛиВключатьТолькоЧитаемые - Булево, *Ложь - включать ли в список только читаемые реквизиты;
// *ЛиВключатьНедоступные - Булево, *Ложь - включать ли в список недоступные (группы/элементы) реквизиты;
// *ЛиСортировать - Булево, *Ложь - отсортировать ли по представлению;
// *ЛиСКартинками - Булево, *Ложь - добавлять ли картинки;
// *ЛиСТабличнымиЧастями - Булево, *Ложь - включать ли в список табличные части.
//
// Возвращаемое значение:
// СписокЗначений - содержащий в качестве значений имена реквизитов.
//
Функция РеквизитыОбъектаБДЛкс(пОбъект, ЛиВключатьТолькоЧитаемые = Ложь,
ЛиВключатьНедоступные = Ложь, ЛиСортировать = Ложь, ЛиСКартинками = Ложь, ЛиСТабличнымиЧастями = Ложь) Экспорт
СписокРеквизитов = Новый СписокЗначений;
Если пОбъект = Неопределено Тогда
Возврат СписокРеквизитов;
КонецЕсли;
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
ОбъектМетаданных = пОбъект;
Иначе
ОбъектМетаданных = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
КорневойТип = КорневойТипКонфигурацииЛкс(ОбъектМетаданных);
КорневойТип = ПеревестиВРусский(КорневойТип);
ИерархияГрупп = Ложь;
КартинкаРеквизита = Неопределено;
#Если Клиент Тогда
Если ЛиСКартинками Тогда
КартинкаРеквизита = БиблиотекаКартинок.СлужебныйРеквизит;
КонецЕсли;
#КонецЕсли
Если КорневойТип = "Задача" Тогда
СписокРеквизитов.Добавить("БизнесПроцесс", "Бизнес процесс", , КартинкаРеквизита);
СписокРеквизитов.Добавить("Дата", "Дата", , КартинкаРеквизита);
Если ОбъектМетаданных.ДлинаНаименования > 0 Тогда
СписокРеквизитов.Добавить("Наименование", "Наименование", , КартинкаРеквизита);
КонецЕсли;
Если ОбъектМетаданных.ДлинаНомера > 0 Тогда
СписокРеквизитов.Добавить("Номер", "Номер", , КартинкаРеквизита);
КонецЕсли;
СписокРеквизитов.Добавить("ТочкаМаршрута", "Точка маршрута", , КартинкаРеквизита);
СписокРеквизитов.Добавить("Выполнена", "Выполнена", , КартинкаРеквизита);
Для Каждого Рекв из ОбъектМетаданных.РеквизитыАдресации Цикл
СписокРеквизитов.Добавить(Рекв.Имя, Рекв.Представление(), , КартинкаРеквизита);
КонецЦикла;
КонецЕсли;
Если КорневойТип = "Документ" Тогда
СписокРеквизитов.Добавить("Дата", "Дата", , КартинкаРеквизита);
Если ОбъектМетаданных.ДлинаНомера > 0 Тогда
СписокРеквизитов.Добавить("Номер", "Номер", , КартинкаРеквизита);
КонецЕсли;
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("Проведен", "Проведен", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
Если КорневойТип = "Справочник" Тогда
Если ОбъектМетаданных.Владельцы.Количество() > 0 Тогда
СписокРеквизитов.Добавить("Владелец", "Владелец", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
ЭтоГруппа = Ложь;
Если ЛиКорневойТипОбъектаСКодомЛкс(КорневойТип) Тогда
Если ОбъектМетаданных.ДлинаКода > 0 Тогда
СписокРеквизитов.Добавить("Код", "Код", , КартинкаРеквизита);
КонецЕсли;
Если ОбъектМетаданных.ДлинаНаименования > 0 Тогда
СписокРеквизитов.Добавить("Наименование", "Наименование", , КартинкаРеквизита);
КонецЕсли;
Если ЛиМетаданныеИерархическогоОбъектаЛкс(ОбъектМетаданных) Тогда
СписокРеквизитов.Добавить("Родитель", "Родитель", , КартинкаРеквизита);
Если ЛиМетаданныеОбъектаСГруппамиЛкс(ОбъектМетаданных) Тогда
ИерархияГрупп = Истина;
Если Не ЛиВключатьНедоступные Тогда
ЭтоГруппа = пОбъект.ЭтоГруппа;
КонецЕсли;
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("ЭтоГруппа", "Это группа", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("Предопределенный", "Предопределенный", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
СписокРеквизитов.Добавить("ПометкаУдаления", "Пометка удаления", , КартинкаРеквизита);
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("Ссылка", "Ссылка", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
Для Каждого СтрокаРеквизита Из СписокРеквизитов Цикл
СтрокаРеквизита.Значение = ПеревестиСтроку(СтрокаРеквизита.Значение);
КонецЦикла;
#Если Клиент Тогда
Если ЛиСКартинками Тогда
КартинкаРеквизита = ирКэш.КартинкаПоИмениЛкс("ирРеквизит");
КонецЕсли;
#КонецЕсли
Для Каждого МетаРеквизит Из ОбъектМетаданных.Реквизиты Цикл
Если Ложь
Или ЛиВключатьНедоступные
Или Не ИерархияГрупп
Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента
Или (Истина
И ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы)
Или (Истина
И Не ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента)
Тогда
СписокРеквизитов.Добавить(МетаРеквизит.Имя, МетаРеквизит.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
Если ирКэш.ДоступныОбщиеРеквизитыЛкс() Тогда
Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл
Если ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Тогда
СписокРеквизитов.Добавить(ОбщийРеквизит.Имя, ОбщийРеквизит.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЛиСТабличнымиЧастями Тогда
#Если Клиент Тогда
Если ЛиСКартинками Тогда
КартинкаРеквизита = БиблиотекаКартинок.ТабличнаяЧасть;
КонецЕсли;
#КонецЕсли
Для Каждого МетаТабличнаяЧасть Из ОбъектМетаданных.ТабличныеЧасти Цикл
Если Ложь
Или ЛиВключатьНедоступные
Или Не ИерархияГрупп
Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента
Или (Истина
И ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы)
Или (Истина
И Не ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента)
Тогда
СписокРеквизитов.Добавить(МетаТабличнаяЧасть.Имя, МетаТабличнаяЧасть.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЛиСортировать Тогда
СписокРеквизитов.СортироватьПоПредставлению();
КонецЕсли;
Возврат СписокРеквизитов;
КонецФункции // РеквизитыОбъектаБДЛкс()
Функция ИмяФайлаСпискаИнфобазПользователяОСЛкс() Экспорт
ИмяФайлаСписка = ирКэш.КаталогПлатформыВПрофилеЛкс(Ложь) + СтрЗаменить("\1cestart\ibases.v8i", "\", РазделительПутиКФайлуЛкс());
Возврат ИмяФайлаСписка;
КонецФункции
// Описатель - ОбъектМетаданных - его реквизиты переносятся в коллекцию в качестве элементов для структуры и в качестве колонок для дерева или таблицы
// - Коллекция с элементами РеквизитФормы, ОбъектМетаданных:Реквизит
// ИсходнаяКоллекция - ТаблицаЗначений, ДеревоЗначений, Структура - по умолчанию создается ТаблицаЗначений
//
Функция УстановитьМетаданныеКоллекцииЛкс(Описатель, ИсходнаяКоллекция = Неопределено) Экспорт
Если ИсходнаяКоллекция = Неопределено Тогда
ИсходнаяКоллекция = Новый ТаблицаЗначений;
КонецЕсли;
ТипИсходнойКоллекции = ТипЗнч(ИсходнаяКоллекция);
Если Ложь
Или ТипИсходнойКоллекции = Тип("ДеревоЗначений")
Или ТипИсходнойКоллекции = Тип("ТаблицаЗначений")
Тогда
Коллекция = ИсходнаяКоллекция.Колонки;
Колонки = Коллекция;
Иначе//Если ТипИсходнойКоллекции = Тип("Структура") Тогда
Коллекция = ИсходнаяКоллекция;
Если ТипЗнч(ИсходнаяКоллекция) = Тип("Структура") Тогда
Пустышка = Новый ТаблицаЗначений;
Колонки = Пустышка.Колонки;
Иначе
Колонки = Коллекция;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(Описатель) = Тип("ОбъектМетаданных") Тогда
Реквизиты = Описатель.Реквизиты;
Иначе
Реквизиты = Описатель;
КонецЕсли;
Для Каждого Реквизит Из Реквизиты Цикл
Если Колонки.Найти(Реквизит.Имя) <> Неопределено Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(Реквизит) = Тип("РеквизитФормы") Тогда
Колонки.Добавить(Реквизит.Имя, Реквизит.ТипЗначения, Реквизит.Заголовок);
ИначеЕсли ТипЗнч(Реквизит) = Тип("КолонкаТаблицыЗначений") Тогда
Колонки.Добавить(Реквизит.Имя, Реквизит.ТипЗначения, Реквизит.Заголовок);
ИначеЕсли ТипЗнч(Реквизит) = Тип("ОбъектМетаданных") Тогда
Колонки.Добавить(Реквизит.Имя, Реквизит.Тип, Реквизит.Представление());
ИначеЕсли ТипЗнч(Реквизит) = Тип("ПолеНастройки") Тогда
Колонки.Добавить(Реквизит.Имя, Реквизит.ТипЗначения, Реквизит.Представление);
Иначе
ВызватьИсключение "Неизвестный тип описания реквизита """ + ТипЗнч(Реквизит) + """";
КонецЕсли;
КонецЦикла;
Если ТипЗнч(Коллекция) = Тип("Структура") Тогда
Для Каждого Колонка Из Колонки Цикл
Коллекция.Вставить(Колонка.Имя, Колонка.ТипЗначения.ПривестиЗначение(Неопределено));
КонецЦикла;
КонецЕсли;
Возврат ИсходнаяКоллекция;
КонецФункции
Функция ПолучитьСписокБазПользователяОСЛкс(Знач ПолноеИмяФайла = Неопределено, ВычислятьРазмерыКаталогов = Ложь, ВычислятьПоследнегоПользователя = Ложь,
ТаблицаПриемник = Неопределено) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если ТаблицаПриемник = Неопределено Тогда
Результат = мПлатформа.СписокБазПользователя.ВыгрузитьКолонки();
Иначе
Результат = ТаблицаПриемник;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
Результат = мПлатформа.СписокБазПользователя;
#КонецЕсли
Если ПолноеИмяФайла = Неопределено Тогда
лПолноеИмяФайла = ИмяФайлаОбщегоСпискаИнфобазВсехПользователейОСЛкс();
Если ЗначениеЗаполнено(лПолноеИмяФайла) Тогда
ПолучитьСписокБазПользователяОСЛкс(лПолноеИмяФайла,,, Результат);
КонецЕсли;
лПолноеИмяФайла = ИмяФайлаОбщегоСпискаИнфобазТекущегоПользователяОСЛкс();
Если ЗначениеЗаполнено(лПолноеИмяФайла) Тогда
ПолучитьСписокБазПользователяОСЛкс(лПолноеИмяФайла,,, Результат);
КонецЕсли;
ПолноеИмяФайла = ИмяФайлаСпискаИнфобазПользователяОСЛкс();
КонецЕсли;
Если ЛиИдентификацияБазыВСпискеПоНаименованиюЛкс() Тогда
КолонкаConnect = Неопределено;
Иначе
КолонкаConnect = Результат.Колонки.Connect;
КонецЕсли;
Файл = Новый Файл(ПолноеИмяФайла);
ДобавленныеСтроки = Новый Массив;
Если Файл.Существует() Тогда
ЧтениеФайла = Новый ЧтениеТекста;
Попытка
ЧтениеФайла.Открыть(ПолноеИмяФайла, КодировкаТекста.UTF8);
СтрокаИзФайла = ЧтениеФайла.ПрочитатьСтроку();
Исключение
// Файл существует, но недоступен http://www.hostedredmine.com/issues/882846
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
СтрокаИзФайла = Неопределено;
КонецПопытки;
Пока СтрокаИзФайла <> Неопределено Цикл
Если СтрДлина(СокрЛП(СтрокаИзФайла)) Тогда
ТекущаяСтрока = СокрЛП(СтрокаИзФайла);
Если Лев(ТекущаяСтрока, 1) = "[" Тогда
НовоеНаименование = Сред(ТекущаяСтрока, 2, СтрДлина(ТекущаяСтрока) - 2); // Убираем квадратные скобки вначале и вконце
Если КолонкаConnect = Неопределено Тогда
НоваяСтрока = Результат.Найти(НРег(НовоеНаименование), "КлючСтроки");
Если НоваяСтрока <> Неопределено Тогда
НоваяСтрока = Неопределено;
СтрокаИзФайла = ЧтениеФайла.ПрочитатьСтроку();
Продолжить;
КонецЕсли;
КонецЕсли;
НоваяСтрока = Результат.Добавить();
НоваяСтрока.ФайлСписка = ПолноеИмяФайла;
НоваяСтрока.Наименование = НовоеНаименование;
ДобавленныеСтроки.Добавить(НоваяСтрока);
КонецЕсли;
ИмяКолонки = ПервыйФрагментЛкс(ТекущаяСтрока, "=", Ложь);
Если НоваяСтрока <> Неопределено И ЗначениеЗаполнено(ИмяКолонки) Тогда
Колонка = Результат.Колонки.Найти(ИмяКолонки);
Если Колонка <> Неопределено Тогда
ПредставлениеЗначения = Сред(ТекущаяСтрока, СтрДлина(ИмяКолонки + "=") + 1);
ЗначениеПараметра = Колонка.ТипЗначения.ПривестиЗначение(ПредставлениеЗначения);
НоваяСтрока[Колонка.Имя] = ЗначениеПараметра;
Если Колонка = КолонкаConnect Тогда
СуществующаяСтрока = Результат.Найти(НРег(ЗначениеПараметра), "КлючСтроки");
Если СуществующаяСтрока <> Неопределено Тогда
Результат.Удалить(НоваяСтрока);
ДобавленныеСтроки.Удалить(ДобавленныеСтроки.ВГраница());
НоваяСтрока = Неопределено;
СтрокаИзФайла = ЧтениеФайла.ПрочитатьСтроку();
Продолжить;
КонецЕсли;
КонецЕсли;
Иначе
Пустышка = 0; // Для отладки
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтрокаИзФайла = ЧтениеФайла.ПрочитатьСтроку();
КонецЦикла;
КонецЕсли;
Разделитель = РазделительПутиКФайлуЛкс();
#Если Сервер И Не Сервер Тогда
ДобавленныеСтроки = Результат;
#КонецЕсли
Для Каждого СтрокаТЧ Из ДобавленныеСтроки Цикл
ИзданиеПлатформы = СтрЗаменить(Лев(СтрокаТЧ.Version, 3), ".", "");
СтрокаТЧ.КаталогКэша = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс(, ИзданиеПлатформы) + Разделитель + СтрокаТЧ.ID;
СтрокаТЧ.КаталогНастроек = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс(Ложь, ИзданиеПлатформы) + Разделитель + СтрокаТЧ.ID;
Если ЛиИдентификацияБазыВСпискеПоНаименованиюЛкс() Тогда
СтрокаТЧ.КлючСтроки = НРег(СтрокаТЧ.Наименование);
Иначе
СтрокаТЧ.КлючСтроки = НРег(СтрокаТЧ.Connect);
КонецЕсли;
СтрокаТЧ.НСтрокаСоединения = НРег(СтрокаТЧ.Connect);
СтрокаСоединенияКластера = НСтр(СтрокаТЧ.Connect, "Srvr");
//СтруктураURI = СтруктураURIЛкс(СтрокаСоединенияКластера); // Здесь может быть строка одновременно нескольких кластеров - tcp://rocket:1541,tcp://rocket1:1741
//СтрокаТЧ.ИмяКомпьютера = ПервыйФрагментЛкс(СтруктураURI.ИмяСервера, ":");
Если ВычислятьПоследнегоПользователя Тогда
ИмяФайлаПоследнегоПользователя = СтрокаТЧ.КаталогНастроек + Разделитель + "def.usr";
ФайлПоследнегоПользователя = Новый Файл(ИмяФайлаПоследнегоПользователя);
Если ФайлПоследнегоПользователя.Существует() Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ФайлПоследнегоПользователя.ПолноеИмя);
СтрокаТЧ.ПоследнийПользователь = СтрокаМеждуМаркерамиЛкс(ТекстовыйДокумент.ПолучитьТекст(), "{""", """}");
КонецЕсли;
КонецЕсли;
Если ВычислятьРазмерыКаталогов Тогда
СтрокаТЧ.РазмерКэшаКБ = ВычислитьРазмерКаталогаЛкс(СтрокаТЧ.КаталогКэша) / 1024;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ЛиИдентификацияБазыВСпискеПоНаименованиюЛкс() Экспорт
Результат = ирКэш.НомерВерсииПлатформыЛкс() > 803000;
Возврат Результат;
КонецФункции
Функция КлючБазыВСпискеПользователяЛкс(выхКлючомЯвляетсяСтрокаСоединения = Ложь) Экспорт
выхКлючомЯвляетсяСтрокаСоединения = Не ЛиИдентификацияБазыВСпискеПоНаименованиюЛкс();
КлючБазыВСпискеПользователя = ирКэш.КлючБазыВСпискеПользователяИзКоманднойСтрокиЛкс();
Если Не ЗначениеЗаполнено(КлючБазыВСпискеПользователя) Тогда
КлючБазыВСпискеПользователя = СтрокаСоединенияИнформационнойБазы();
выхКлючомЯвляетсяСтрокаСоединения = Истина;
КонецЕсли;
Возврат КлючБазыВСпискеПользователя;
КонецФункции
Функция ИмяФайлаОбщегоСпискаИнфобазТекущегоПользователяОСЛкс(ИмяКонфигФайла = "") Экспорт
ИмяКонфигФайла = ирКэш.КаталогПлатформыВПрофилеЛкс(Ложь) + СтрЗаменить("\1cestart\1cestart.cfg", "\", РазделительПутиКФайлуЛкс());
Текст = Новый ТекстовыйДокумент;
Текст.Прочитать(ИмяКонфигФайла);
СписокИмен = "";
Для Счетчик = 1 По СтрЧислоСтрок(Текст.ПолучитьТекст()) Цикл
СтрокаТекста = СокрЛ(Текст.ПолучитьСтроку(Счетчик));
Если Найти(СтрокаТекста, "CommonInfoBases") = 1 Тогда
Результат = Сред(СтрокаТекста, Найти(СтрокаТекста, "=") + 1);
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ИмяФайлаОбщегоСпискаИнфобазВсехПользователейОСЛкс(ИмяКонфигФайла = "") Экспорт
Если Не ирКэш.ЛиПлатформаWindowsЛкс() Тогда
Возврат Неопределено;
Иначе
ПриложениеОболочкиОС = Новый COMobject("Shell.Application");
КаталогОбщихНастроек = ПриложениеОболочкиОС.NameSpace(35).Self.Path;
КонецЕсли;
ИмяКонфигФайла = КаталогОбщихНастроек + СтрЗаменить("\1C\1cestart\1cestart.cfg", "\", РазделительПутиКФайлуЛкс());
Текст = Новый ТекстовыйДокумент;
Текст.Прочитать(ИмяКонфигФайла);
СписокИмен = "";
Для Счетчик = 1 По СтрЧислоСтрок(Текст.ПолучитьТекст()) Цикл
СтрокаТекста = СокрЛ(Текст.ПолучитьСтроку(Счетчик));
Если Найти(СтрокаТекста, "CommonInfoBases") = 1 Тогда
Результат = Сред(СтрокаТекста, Найти(СтрокаТекста, "=") + 1);
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
// Получает строку для установки порядка. Пример "Контрагент убыв, Номенклатура.Код возр".
//
// Параметры:
// Порядок - Порядок.
//
// Возвращаемое значение:
// Строка - для установки порядка.
//
Функция ПорядокВСтрокуЛкс(Порядок) Экспорт
Строка = "";
Для Каждого ЭлементПорядка Из Порядок Цикл
Строка = Строка + ", " + ЭлементПорядка.ПутьКДанным + " ";
Если ЭлементПорядка.Направление = НаправлениеСортировки.Возр Тогда
Строка = Строка + "возр";
Иначе
Строка = Строка + "убыв";
КонецЕсли;
КонецЦикла;
Возврат Сред(Строка, 2);
КонецФункции
// Выполняет текст на внутреннем языке. Применяется для безопасного выполнения произвольного кода.
// Безопасность заключается в том, что нет свойств локального контекста
// и недоступны доопределенные Свойства глобального контекста.
//
// Параметры:
// ТекстДляВыполнения - Строка;
// *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля.
//
Процедура ВыполнитьВКонтекстеОбщегоМодуляЛкс(ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт
Выполнить(ТекстДляВыполнения);
КонецПроцедуры // ВыполнитьВКонтекстеОбщегоМодуляЛкс()
// Получает копию произвольного объекта. Копирование производится через сериализацию.
//
// Параметры:
// пОбъект - Произвольное - сохраняемое значение;
// ИспользоватьXDTO - Булево - выполнять через ОбъектXDTO, для типов компоновки данных работает быстрее в 2 раза, но не у всех типов есть XDTO отображение, позволяет обходить платформенные ошибки десериализации компоновки
// Истина - не делает глубокого копирования! Применять в основном имеет смысл только для объектов системы компоновки данных
//
// Возвращаемое значение:
// Произвольный - копия объекта.
//
Функция КопияОбъектаЛкс(пОбъект, ИспользоватьXDTO = Ложь) Экспорт
Если ИспользоватьXDTO Тогда
// Быстрее в 2 раза
Попытка
НовыйОбъект = СериализаторXDTO.ПрочитатьXDTO(СериализаторXDTO.ЗаписатьXDTO(пОбъект));
Исключение
// 7ы78аывраы0ав8
// https://partners.v8.1c.ru/forum/t/1918496/m/1918496
// Антибаг платформы 8.3.17-+ В настройках компоновки в элементах отбора с видом сравнения "ВСписке" в правых значениях поля компоновки при десериализации возникает ошибка.
// Чтобы ее обойти оборачиваем каждое такое поле в массив
СтрокаХмл = ирОбщий.ОбъектВСтрокуXMLЛкс(пОбъект);
ДокументДом = ирОбщий.ПрочитатьТекстВДокументDOMЛкс(СтрокаХмл);
#Если Сервер И Не Сервер Тогда
ДокументДом = Новый ДокументDOM;
#КонецЕсли
РазыменовательПИ = Новый РазыменовательПространствИменDOM("w", "http://v8.1c.ru/8.1/data-composition-system/settings");
РезультатХПути = ДокументДом.ВычислитьВыражениеXPath("//w:comparisonType[text()='InList' or text()='NotInList']/following-sibling::w:right[@xsi:type='dcscor:Field']", ДокументДом,
РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
Пока Истина Цикл
УзелПравогоЗначенияОтбора = РезультатХПути.ПолучитьСледующий();
Если УзелПравогоЗначенияОтбора = Неопределено Тогда
Прервать;
КонецЕсли;
ПрефиксЯдра = УзелПравогоЗначенияОтбора.НайтиПрефикс("http://v8.1c.ru/8.1/data/core");
ПрефиксТипов = УзелПравогоЗначенияОтбора.НайтиПрефикс("http://www.w3.org/2001/XMLSchema-instance");
ПрефиксКомпоновки = УзелПравогоЗначенияОтбора.НайтиПрефикс("http://v8.1c.ru/8.1/data-composition-system/core");
НовыйВложенныйУзел = ДокументДом.СоздатьЭлемент("http://v8.1c.ru/8.1/data/core", ПрефиксЯдра + ":Value");
НовыйВложенныйУзел.УстановитьАтрибут("http://www.w3.org/2001/XMLSchema-instance", ПрефиксТипов + ":type", ПрефиксКомпоновки + ":Field");
НовыйВложенныйУзел.ТекстовоеСодержимое = УзелПравогоЗначенияОтбора.ПервыйДочерний.ТекстовоеСодержимое;
УзелПравогоЗначенияОтбора.УдалитьДочерний(УзелПравогоЗначенияОтбора.ПервыйДочерний);
УзелПравогоЗначенияОтбора.УдалитьУзелАтрибута(УзелПравогоЗначенияОтбора.Атрибуты[0]);
УзелПравогоЗначенияОтбора.ДобавитьДочерний(НовыйВложенныйУзел);
УзелПравогоЗначенияОтбора.УстановитьАтрибут("http://www.w3.org/2001/XMLSchema-instance", ПрефиксТипов + ":type", ПрефиксЯдра + ":Array");
КонецЦикла;
СтрокаХМЛ = ирОбщий.ЗаписатьДокументDOMВСтрокуЛкс(ДокументДом);
НовыйОбъект = ирОбщий.ОбъектИзСтрокиXMLЛкс(СтрокаХМЛ);
КонецПопытки;
Иначе
НовыйОбъект = ЗначениеИзСтрокиВнутрЛкс(ЗначениеВСтрокуВнутр(пОбъект));
КонецЕсли;
Возврат НовыйОбъект;
КонецФункции
Процедура ВосстановитьОтборыКомпоновкиПослеДесериализацииЛкс(Знач НастройкаИлиГруппаОтбора) Экспорт
Если ТипЗнч(НастройкаИлиГруппаОтбора) = Тип("НастройкиКомпоновкиДанных") Тогда
#Если Сервер И Не Сервер Тогда
НастройкаИлиГруппаОтбора = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
ГруппаОтбора = НастройкаИлиГруппаОтбора.Отбор;
Иначе
ГруппаОтбора = НастройкаИлиГруппаОтбора;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ГруппаОтбора = Новый НастройкиКомпоновкиДанных;
ГруппаОтбора = НастройкаИлиГруппаОтбора.Отбор;
#КонецЕсли
// https://partners.v8.1c.ru/forum/t/1623191/m/1623191
Для Каждого ЭлементОтбора Из ГруппаОтбора.Элементы Цикл
Если ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
ВосстановитьОтборыКомпоновкиПослеДесериализацииЛкс(ЭлементОтбора);
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("Массив") Тогда
МассивЗначенияОтбора = ЭлементОтбора.ПравоеЗначение;
ИначеЕсли Истина
И ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("СписокЗначений")
И ЭлементОтбора.ПравоеЗначение.Количество() = 1
И ТипЗнч(ЭлементОтбора.ПравоеЗначение[0].Значение) = Тип("Массив")
Тогда
МассивЗначенияОтбора = ЭлементОтбора.ПравоеЗначение[0].Значение;
Иначе
МассивЗначенияОтбора = Неопределено;
КонецЕсли;
Если МассивЗначенияОтбора <> Неопределено Тогда
СписокЗначений = Новый СписокЗначений;
Для Каждого ЭлементМассива Из МассивЗначенияОтбора Цикл
Если ТипЗнч(ЭлементМассива) = Тип("ПолеКомпоновкиДанных") Тогда
// 7ы78аывраы0ав8
// https://partners.v8.1c.ru/forum/t/1918496/m/1918496
СписокЗначений = ЭлементМассива;
Прервать;
КонецЕсли;
СписокЗначений.Добавить(ЭлементМассива);
КонецЦикла;
ЭлементОтбора.ПравоеЗначение = СписокЗначений;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Находит элемент коллекции по свойству "ПутьКДанным".
//
// Параметры:
// пКоллекция - Коллекция - все элементы которой имеют свойство "ПутьКДанным";
// пПутьКДанным - Строка - искомое значение.
//
// Возвращаемое значение:
// - ЭлементКоллекции;
// Неопределено - не найден.
//
Функция НайтиЭлементКоллекцииПоПутиКДаннымЛкс(пКоллекция, пПутьКДанным) Экспорт
СуществующаяСтрока = Неопределено;
Для Каждого ЭлементКоллеции Из пКоллекция Цикл
Если ЭлементКоллеции.ПутьКДанным = пПутьКДанным Тогда
СуществующаяСтрока = ЭлементКоллеции;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат СуществующаяСтрока;
КонецФункции // НайтиЭлементКоллекцииПоПутиКДаннымЛкс()
// Находит поле настройки по пути к данным.
//
// Параметры:
// пПоляНастройки - ПоляНастройки;
// пПутьКДанным - Строка - путь к данным поля в виде разыменовывания;
// *пПутьКТекущемуПолю - Строка, "" - путь к текущему полю.
//
// Возвращаемое значение:
// ПолеНастройки - найденное поле;
// Неопределено - иначе.
//
Функция НайтиПолеНастройкиПоПутиКДаннымЛкс(пПоляНастройки, пПутьКДанным, пПутьКТекущемуПолю = "") Экспорт
ПоляНастройки = пПоляНастройки;
МассивФрагментов = СтрРазделитьЛкс(пПутьКДанным);
ТекущееПоле = Неопределено;
Для Каждого Фрагмент Из МассивФрагментов Цикл
пПутьКТекущемуПолю = пПутьКТекущемуПолю + ?(пПутьКТекущемуПолю = "", "", ".") + Фрагмент;
ТекущееПоле = НайтиЭлементКоллекцииПоПутиКДаннымЛкс(ПоляНастройки, пПутьКТекущемуПолю);
Если ТекущееПоле = Неопределено Тогда
Прервать;
КонецЕсли;
ПоляНастройки = ТекущееПоле.Поля;
КонецЦикла;
Возврат ТекущееПоле;
КонецФункции // НайтиПолеНастройкиПоПутиКДаннымЛкс()
// Копирует один элемент отбора в другой. Если Использование = Ложь, то копируется только оно.
//
// Параметры:
// пЭлементОтбораПриемник - ЭлементОтбора - куда копируем;
// пЭлементОтбораИсточник - ЭлементОтбора - откуда копируем.
//
Процедура СкопироватьЭлементОтбораЛкс(пЭлементОтбораПриемник, пЭлементОтбораИсточник) Экспорт
ЗаполнитьЗначенияСвойств(пЭлементОтбораПриемник, пЭлементОтбораИсточник, "Представление, Использование");
МассивСвойствЭлементаОтбора = Новый Массив;
МассивСвойствЭлементаОтбора.Добавить("ВидСравнения");
МассивСвойствЭлементаОтбора.Добавить("Значение");
МассивСвойствЭлементаОтбора.Добавить("ЗначениеС");
МассивСвойствЭлементаОтбора.Добавить("ЗначениеПо");
Для Каждого Свойство Из МассивСвойствЭлементаОтбора Цикл
Значение = пЭлементОтбораИсточник[Свойство];
Если пЭлементОтбораПриемник[Свойство] <> Значение Тогда
пЭлементОтбораПриемник[Свойство] = Значение;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ТрансформироватьОтборВОтборКомпоновкиЛкс(Знач ОтборКомпоновкиДанных, Знач ЭлементыОтбора, Знач СоответствиеИмен = Неопределено,
Знач ПропускатьНедоступныеПоля = Ложь, Знач ДоступныеПоляОтбора = Неопределено, ТолькоИспользуемые = Истина, ОчищатьПриемник = Истина, Знач ИгнорироватьЭлементы = "") Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый НастройкиКомпоновкиДанных;
ОтборКомпоновкиДанных = Пустышка.Отбор;
#КонецЕсли
Если СоответствиеИмен = Неопределено Тогда
СоответствиеИмен = Новый ТаблицаЗначений();
СоответствиеИмен.Колонки.Добавить("Источник");
//СоответствиеИмен.Колонки.Добавить("Приемник");
КонецЕсли;
Если ДоступныеПоляОтбора = Неопределено Тогда
ДоступныеПоляОтбора = ОтборКомпоновкиДанных.ДоступныеПоляОтбора;
КонецЕсли;
Если ОчищатьПриемник Тогда
ОтборКомпоновкиДанных.Элементы.Очистить();
КонецЕсли;
Если ЗначениеЗаполнено(ИгнорироватьЭлементы) Тогда
ИгнорироватьСтруктура = Новый Структура(ИгнорироватьЭлементы);
Иначе
ИгнорироватьСтруктура = Новый Структура;
КонецЕсли;
ИндексГраницы = ЭлементыОтбора.Количество() - 1;
ИзмененныеЭлементыОтбора = Новый Массив;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Для Каждого ЭлементОтбора Из ЭлементыОтбора Цикл
Если Истина
И ТолькоИспользуемые
И Не ЭлементОтбора.Использование
Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
ПриемникОтбора = ОтборКомпоновкиДанных.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ЗаполнитьЗначенияСвойств(ПриемникОтбора, ЭлементОтбора);
ТрансформироватьОтборВОтборКомпоновкиЛкс(ПриемникОтбора, ЭлементОтбора.Элементы, СоответствиеИмен, ПропускатьНедоступныеПоля, ДоступныеПоляОтбора, ТолькоИспользуемые);
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
Если ТипЗнч(ЭлементОтбора.ЛевоеЗначение) <> Тип("ПолеКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
//ПутьКДаннымЛевый = Неопределено;
//Если ТипЗнч(ЭлементОтбора.ЛевоеЗначение) = Тип("ПолеКомпоновкиДанных") Тогда
ПутьКДаннымЛевый = "" + ЭлементОтбора.ЛевоеЗначение;
//Иначе
// ЛевоеЗначение = ЭлементОтбора.ЛевоеЗначение;
//КонецЕсли;
ПутьКДаннымПравый = Неопределено;
Если ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("ПолеКомпоновкиДанных") Тогда
ПутьКДаннымПравый = "" + ЭлементОтбора.ПравоеЗначение;
Иначе
ПравоеЗначение = ЭлементОтбора.ПравоеЗначение;
КонецЕсли;
Иначе
ПутьКДаннымЛевый = ЭлементОтбора.ПутьКДанным;
ПутьКДаннымПравый = Неопределено;
ПравоеЗначение = ЭлементОтбора.Значение;
Если Истина
И Найти(ПутьКДаннымЛевый, " ") = 0 // Антибаг платформы 8.3.18 В динамическом списке обычной формы регистра бухгалтерии есть "Валюта Кор" https://www.hostedredmine.com/issues/936315
И ИгнорироватьСтруктура.Свойство(ПутьКДаннымЛевый)
Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
//Если ПутьКДаннымЛевый <> Неопределено Тогда
МассивФрагментов = СтрРазделитьЛкс(ПутьКДаннымЛевый);
СтрокаИсточника = СоответствиеИмен.Найти(НРег(МассивФрагментов[0]), "Источник");
Если СтрокаИсточника <> Неопределено Тогда
МассивФрагментов[0] = СтрокаИсточника.Приемник;
КонецЕсли;
ПутьКДанным = СтрСоединитьЛкс(МассивФрагментов, ".");
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
лВидСравнения = ЭлементОтбора.ВидСравнения;
Иначе
СтрокаВидаСравнения = мПлатформа.СоответствиеВидовСравнения.Найти(ЭлементОтбора.ВидСравнения, "Построитель");
Если СтрокаВидаСравнения = Неопределено Тогда
Если ЭлементОтбора.ВидСравнения = ВидСравнения.Интервал Тогда
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеС, ВидСравненияКомпоновкиДанных.Больше,, Ложь, ЭлементОтбора.Использование);
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеПо, ВидСравненияКомпоновкиДанных.Меньше,, Ложь, ЭлементОтбора.Использование);
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяГраницы Тогда
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеС, ВидСравненияКомпоновкиДанных.БольшеИлиРавно,, Ложь, ЭлементОтбора.Использование);
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеПо, ВидСравненияКомпоновкиДанных.МеньшеИлиРавно,, Ложь, ЭлементОтбора.Использование);
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяНачало Тогда
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеС, ВидСравненияКомпоновкиДанных.БольшеИлиРавно,, Ложь, ЭлементОтбора.Использование);
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеПо, ВидСравненияКомпоновкиДанных.Меньше,, Ложь, ЭлементОтбора.Использование);
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяОкончание Тогда
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеС, ВидСравненияКомпоновкиДанных.Больше,, Ложь, ЭлементОтбора.Использование);
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеПо, ВидСравненияКомпоновкиДанных.МеньшеИлиРавно,, Ложь, ЭлементОтбора.Использование);
КонецЕсли;
Продолжить;
КонецЕсли;
лВидСравнения = СтрокаВидаСравнения.Компоновка;
КонецЕсли;
ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ПутьКДанным);
ЭлементОтбораПриемник = Неопределено;
Для Каждого ЭлементОтбораЦикл Из ОтборКомпоновкиДанных.Элементы Цикл
Если Истина
И ТипЗнч(ЭлементОтбораЦикл) = Тип("ЭлементОтбораКомпоновкиДанных")
И ЭлементОтбораЦикл.ЛевоеЗначение = ПолеКомпоновки
И ИзмененныеЭлементыОтбора.Найти(ЭлементОтбораЦикл) = Неопределено
Тогда
ЭлементОтбораПриемник = ЭлементОтбораЦикл;
ИзмененныеЭлементыОтбора.Добавить(ЭлементОтбораПриемник);
Прервать;
КонецЕсли;
КонецЦикла;
Если ЭлементОтбораПриемник = Неопределено Тогда
ДоступноеПоле = ДоступныеПоляОтбора.НайтиПоле(ПолеКомпоновки);
Если Истина
И ПропускатьНедоступныеПоля
И ДоступноеПоле = Неопределено
Тогда
Продолжить;
КонецЕсли;
ЭлементОтбораПриемник = ОтборКомпоновкиДанных.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбораПриемник.ЛевоеЗначение = ПолеКомпоновки;
КонецЕсли;
//Иначе
// ПолеОтбора.ПравоеЗначение = ЛевоеЗначение;
//КонецЕсли;
Если ПутьКДаннымПравый <> Неопределено Тогда
МассивФрагментов = СтрРазделитьЛкс(ПутьКДаннымПравый);
СтрокаИсточника = СоответствиеИмен.Найти(НРег(МассивФрагментов[0]), "Источник");
Если СтрокаИсточника <> Неопределено Тогда
МассивФрагментов[0] = СтрокаИсточника.Приемник;
КонецЕсли;
ПутьКДанным = СтрСоединитьЛкс(МассивФрагментов, ".");
ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ПутьКДанным);
ЭлементОтбораПриемник.ПравоеЗначение = ПолеКомпоновки;
Иначе
ЭлементОтбораПриемник.ПравоеЗначение = ПравоеЗначение;
КонецЕсли;
ЭлементОтбораПриемник.ВидСравнения = лВидСравнения;
ЭлементОтбораПриемник.Использование = ЭлементОтбора.Использование;
ПроверитьВключитьЭлементНастроекКомпоновкиВПользовательскиеНастройки(ЭлементОтбораПриемник);
КонецЦикла;
КонецФункции
// Порт СкопироватьОтборЛкс.
Процедура СкопироватьОтборЛюбойЛкс(ОтборПриемник, ОтборИсточник, ТолькоИспользуемые = Ложь, ПропускатьНедоступныеПоля = Ложь, ОчищатьПриемник = Истина, ИмяБазовогоПоля = "",
Знач ИгнорироватьЭлементы = "") Экспорт
Если Истина
И ТипЗнч(ОтборИсточник) = Тип("Отбор")
И ТипЗнч(ОтборПриемник) = Тип("Отбор")
Тогда
СкопироватьОтборПостроителяЛкс(ОтборПриемник, ОтборИсточник, , ТолькоИспользуемые, ОчищатьПриемник);
ИначеЕсли Истина
И ТипЗнч(ОтборИсточник) = Тип("Структура")
И ТипЗнч(ОтборПриемник) = Тип("Отбор")
Тогда
Для Каждого КлючИЗначение Из ОтборИсточник Цикл
ИмяПоляПриемника = КлючИЗначение.Ключ;
ЭлементОтбора = ОтборПриемник.Найти(КлючИЗначение.Ключ);
Если ЭлементОтбора <> Неопределено Тогда
УстановитьЭлементОтбораЛкс(ЭлементОтбора,, КлючИЗначение.Значение);
КонецЕсли;
КонецЦикла;
ИначеЕсли Истина
И ТипЗнч(ОтборИсточник) = Тип("ОтборКомпоновкиДанных")
И ТипЗнч(ОтборПриемник) = Тип("ОтборКомпоновкиДанных")
Тогда
СкопироватьЭлементыКомпоновкиЛкс(ОтборПриемник, ОтборИсточник, , ОчищатьПриемник);
ИначеЕсли Истина
И ТипЗнч(ОтборИсточник) = Тип("Структура")
И ТипЗнч(ОтборПриемник) = Тип("ОтборКомпоновкиДанных")
Тогда
#Если Сервер И Не Сервер Тогда
ОтборПриемник = Новый НастройкиКомпоновкиДанных;
ОтборПриемник = ОтборПриемник.Отбор;
#КонецЕсли
Для Каждого КлючИЗначение Из ОтборИсточник Цикл
ИмяПоляПриемника = КлючИЗначение.Ключ;
Если ЗначениеЗаполнено(ИмяБазовогоПоля) Тогда
ИмяПоляПриемника = ИмяБазовогоПоля + "." + ИмяПоляПриемника;
КонецЕсли;
Если Истина
И ПропускатьНедоступныеПоля
И ОтборПриемник.ДоступныеПоляОтбора.НайтиПоле(Новый ПолеКомпоновкиДанных(ИмяПоляПриемника)) = Неопределено
Тогда
Продолжить;
КонецЕсли;
ЭлементОтбора = НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборПриемник, ИмяПоляПриемника, КлючИЗначение.Значение);
#Если Сервер И Не Сервер Тогда
ЭлементОтбора = Новый НастройкиКомпоновкиДанных;
ЭлементОтбора = ЭлементОтбора.Отбор.Элементы.Добавить();
#КонецЕсли
ПроверитьВключитьЭлементНастроекКомпоновкиВПользовательскиеНастройки(ЭлементОтбора);
КонецЦикла;
ИначеЕсли Истина
И ТипЗнч(ОтборИсточник) = Тип("Отбор")
И ТипЗнч(ОтборПриемник) = Тип("ОтборКомпоновкиДанных")
Тогда
ТрансформироватьОтборВОтборКомпоновкиЛкс(ОтборПриемник, ОтборИсточник,, ПропускатьНедоступныеПоля,, ТолькоИспользуемые, ОчищатьПриемник, ИгнорироватьЭлементы);
ИначеЕсли Истина
И ТипЗнч(ОтборИсточник) = Тип("ОтборКомпоновкиДанных")
И ТипЗнч(ОтборПриемник) = Тип("Отбор")
Тогда
#Если Сервер И Не Сервер Тогда
ОтборИсточник = Новый НастройкиКомпоновкиДанных;
ОтборИсточник = ОтборИсточник.Отбор;
#КонецЕсли
Если ОчищатьПриемник Тогда
ОтборПриемник.Сбросить();
КонецЕсли;
Для Каждого ЭлементОтбораИсточник Из ОтборИсточник.Элементы Цикл
Если ЭлементОтбораИсточник.Использование Тогда
ЭлементОтбораПриемник = ОтборПриемник.Найти("" + ЭлементОтбораИсточник.ЛевоеЗначение);
Если ЭлементОтбораПриемник <> Неопределено Тогда
ИмяВидаСравнения = ирОбщий.СтрЗаменитьЛкс(ПолучитьПолноеИмяПредопределенногоЗначения(ЭлементОтбораИсточник.ВидСравнения), "ВидСравненияКомпоновкиДанных", "ВидСравнения");
Попытка
ВидСравненияОтбора = ПредопределенноеЗначение(ИмяВидаСравнения);
Исключение
Продолжить;
КонецПопытки;
ЭлементОтбораПриемник.Использование = Истина;
ЭлементОтбораПриемник.ВидСравнения = ВидСравненияОтбора;
ЭлементОтбораПриемник.Значение = ЭлементОтбораИсточник.ПравоеЗначение;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе
ВызватьИсключение "Недопустимые типы параметров 1, 2";
КонецЕсли;
КонецПроцедуры
// Важно: установка идентификатора должна выполняться в конце настройки элемента,
// иначе он будет скопирован в пользовательские настройки частично заполненным.
Процедура ПроверитьВключитьЭлементНастроекКомпоновкиВПользовательскиеНастройки(Знач ЭлементНастроек, Знач ИдентификаторНастройки = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый НастройкиКомпоновкиДанных;
ЭлементНастроек = Пустышка.Отбор;
#КонецЕсли
Если ЗначениеЗаполнено(ЭлементНастроек.ИдентификаторПользовательскойНастройки) Тогда
Возврат;
КонецЕсли;
//Представление = "" + ЭлементНастроек;
Если ТипЗнч(ЭлементНастроек) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
//Если ЗначениеЗаполнено(ЭлементНастроек.Представление) Тогда
// Представление = ЭлементНастроек.Представление;
//Иначе
// Представление = ЭлементНастроек.ЛевоеЗначение;
//КонецЕсли;
Если Не ЗначениеЗаполнено(ИдентификаторНастройки) Тогда
ИдентификаторНастройки = "" + ЭлементНастроек.ЛевоеЗначение;
КонецЕсли;
Иначе
Если Не ЗначениеЗаполнено(ИдентификаторНастройки) Тогда
Попытка
ИдентификаторНастройки = "" + ЭлементНастроек.Поле;
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
//Попытка
// ЭлементНастроек.ПредставлениеПользовательскойНастройки = Представление;
//Исключение
// // Это ОтборКомпоновкиДанных внутри пользовательских настроек
//КонецПопытки;
Если Не ЗначениеЗаполнено(ИдентификаторНастройки) Тогда
ИдентификаторНастройки = Новый УникальныйИдентификатор;
КонецЕсли;
ЭлементНастроек.ИдентификаторПользовательскойНастройки = ИдентификаторНастройки;
КонецПроцедуры
// Копирует элементы из одной коллекции компоновки в другую
//
Процедура СкопироватьЭлементыКомпоновкиЛкс(ПриемникЗначения, ИсточникЗначения, _ПропускатьНедоступныеПоля = Ложь, ОчищатьПриемник = Истина, ЭлементыДляКопирования = Неопределено) Экспорт
Если Ложь
Или ТипЗнч(ИсточникЗначения) = Тип("УсловноеОформлениеКомпоновкиДанных")
ИЛИ ТипЗнч(ИсточникЗначения) = Тип("ВариантыПользовательскогоПоляВыборКомпоновкиДанных")
ИЛИ ТипЗнч(ИсточникЗначения) = Тип("ОформляемыеПоляКомпоновкиДанных")
ИЛИ ТипЗнч(ИсточникЗначения) = Тип("ЗначенияПараметровДанныхКомпоновкиДанных")
Тогда
СоздаватьПоТипу = Ложь;
Иначе
СоздаватьПоТипу = Истина;
КонецЕсли;
ПриемникЭлементов = ПриемникЗначения.Элементы;
ИсточникЭлементов = ИсточникЗначения.Элементы;
Если ОчищатьПриемник Тогда
ПриемникЭлементов.Очистить();
КонецЕсли;
Для каждого ЭлементИсточник Из ИсточникЭлементов Цикл
Если Истина
И ЭлементыДляКопирования <> Неопределено
И ЭлементыДляКопирования.Найти(ЭлементИсточник) = Неопределено
Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементИсточник) = Тип("ЭлементПорядкаКомпоновкиДанных") Тогда
// Элементы порядка добавляем в начало
Индекс = ИсточникЭлементов.Индекс(ЭлементИсточник);
ЭлементПриемник = ПриемникЭлементов.Вставить(Индекс, ТипЗнч(ЭлементИсточник));
Иначе
Если СоздаватьПоТипу Тогда
ЭлементПриемник = ПриемникЭлементов.Добавить(ТипЗнч(ЭлементИсточник));
Иначе
ЭлементПриемник = ПриемникЭлементов.Добавить();
КонецЕсли;
КонецЕсли;
ЗаполнитьЗначенияСвойств(ЭлементПриемник, ЭлементИсточник);
// В некоторых коллекциях необходимо заполнить другие коллекции
Если ТипЗнч(ИсточникЭлементов) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда
СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник.Поля, ЭлементИсточник.Поля);
СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник.Отбор, ЭлементИсточник.Отбор);
ЗаполнитьЭлементыКомпоновкиЛкс(ЭлементПриемник.Оформление, ЭлементИсточник.Оформление);
ИначеЕсли ТипЗнч(ИсточникЭлементов) = Тип("КоллекцияВариантовПользовательскогоПоляВыборКомпоновкиДанных") Тогда
СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник.Отбор, ЭлементИсточник.Отбор);
КонецЕсли;
// В некоторых элементах коллекции необходимо заполнить другие коллекции
Если ТипЗнч(ЭлементИсточник) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник, ЭлементИсточник);
ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ГруппаВыбранныхПолейКомпоновкиДанных") Тогда
СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник, ЭлементИсточник);
ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ПользовательскоеПолеВыборКомпоновкиДанных") Тогда
СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник.Варианты, ЭлементИсточник.Варианты);
ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ПользовательскоеПолеВыражениеКомпоновкиДанных") Тогда
ЭлементПриемник.УстановитьВыражениеДетальныхЗаписей (ЭлементИсточник.ПолучитьВыражениеДетальныхЗаписей());
ЭлементПриемник.УстановитьВыражениеИтоговыхЗаписей(ЭлементИсточник.ПолучитьВыражениеИтоговыхЗаписей());
ЭлементПриемник.УстановитьПредставлениеВыраженияДетальныхЗаписей(ЭлементИсточник.ПолучитьПредставлениеВыраженияДетальныхЗаписей ());
ЭлементПриемник.УстановитьПредставлениеВыраженияИтоговыхЗаписей(ЭлементИсточник.ПолучитьПредставлениеВыраженияИтоговыхЗаписей ());
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Заполняет элементы одной коллекции из другой
//
Процедура ЗаполнитьЭлементыКомпоновкиЛкс(ПриемникЗначения, ИсточникЗначения, ПервыйУровень = Неопределено) Экспорт
Если ТипЗнч(ПриемникЗначения) = Тип("КоллекцияЗначенийПараметровКомпоновкиДанных") Тогда
КоллекцияЗначений = ИсточникЗначения;
Иначе
КоллекцияЗначений = ИсточникЗначения.Элементы;
КонецЕсли;
Для каждого ЭлементИсточник Из КоллекцияЗначений Цикл
Если ПервыйУровень = Неопределено Тогда
ЭлементПриемник = ПриемникЗначения.НайтиЗначениеПараметра(ЭлементИсточник.Параметр);
Иначе
ЭлементПриемник = ПервыйУровень.НайтиЗначениеПараметра(ЭлементИсточник.Параметр);
КонецЕсли;
Если ЭлементПриемник = Неопределено Тогда
Продолжить;
КонецЕсли;
ЗаполнитьЗначенияСвойств(ЭлементПриемник, ЭлементИсточник);
Если ТипЗнч(ЭлементИсточник) = Тип("ЗначениеПараметраКомпоновкиДанных") Тогда
Если ЭлементИсточник.ЗначенияВложенныхПараметров.Количество() <> 0 Тогда
ЗаполнитьЭлементыКомпоновкиЛкс(ЭлементПриемник.ЗначенияВложенныхПараметров, ЭлементИсточник.ЗначенияВложенныхПараметров, ПриемникЗначения);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Копирует объект Отбор в другой объект Отбор.
// Если нужно, в приемнике создаются отсутствующие элементы отбора.
//
// Параметры:
// пОтборПриемник - Отбор - куда копируем;
// пОтборИсточник - Отбор, Структура - откуда копируем;
// пСоздаватьОтсутствующие - Булево, *Ложь - признак создания отсутствующих элементов отбора в приемнике.
//
Процедура СкопироватьОтборПостроителяЛкс(ОтборПриемник, ОтборИсточник, СоздаватьОтсутствующие = Истина, ТолькоИспользуемые = Ложь, ОчищатьПриемник = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый ПостроительЗапроса;
ОтборПриемник = Пустышка.Отбор;
#КонецЕсли
Если ОчищатьПриемник Тогда
ОтборПриемник.Сбросить();
КонецЕсли;
//Если пСоздаватьОтсутствующие Тогда
// ДоступныеПоля = пОтборПриемник.ПолучитьДоступныеПоля();
//КонецЕсли;
Для Каждого ЭлементОтбораИсточника Из ОтборИсточник Цикл
Если Истина
И ТолькоИспользуемые
И Не ЭлементОтбораИсточника.Использование
Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементОтбораИсточника) = Тип("КлючИЗначение") Тогда
ЭлементОтбораИсточника = ЭлементОтбораИсточника.Значение;
КонецЕсли;
//Если ЭлементОтбораИсточника.Имя = "" Тогда
// СообщитьЛкс("Невозможно определить элемент отбора приемника при копировании отбора.",
// СтатусСообщения.Внимание);
// Продолжить;
//КонецЕсли;
ЭлементОтбораПриемника = ОтборПриемник.Найти(ЭлементОтбораИсточника.Имя);
Если ЭлементОтбораПриемника = Неопределено Тогда
Если Истина
И СоздаватьОтсутствующие
//И НайтиПолеНастройкиПоПутиКДаннымЛкс(ДоступныеПоля, ЭлементОтбораИсточника.ПутьКДанным) <> Неопределено
Тогда
Попытка
ЭлементОтбораПриемника = ОтборПриемник.Добавить(ЭлементОтбораИсточника.ПутьКДанным, ЭлементОтбораИсточника.Имя);
Исключение
Продолжить;
КонецПопытки;
Иначе
Продолжить;
КонецЕсли;
КонецЕсли;
СкопироватьЭлементОтбораЛкс(ЭлементОтбораПриемника, ЭлементОтбораИсточника);
КонецЦикла;
КонецПроцедуры
// Получает инвертированный вид сравнения.
//
// Параметры:
// ВидСравнения - ВидСравнения.
//
// Возвращаемое значение:
// ВидСравнения;
//
Функция ИнвертированныйВидСравненияЛкс(ВидСравненияП) Экспорт
МассивИнвертируемыхТиповСравнения = Новый Массив;
МассивИнвертируемыхТиповСравнения.Добавить("ВИерархии");
МассивИнвертируемыхТиповСравнения.Добавить("ВСписке");
МассивИнвертируемыхТиповСравнения.Добавить("Равно");
МассивИнвертируемыхТиповСравнения.Добавить("Содержит");
МассивИнвертируемыхТиповСравнения.Добавить("ВСпискеПоИерархии");
Для Каждого ТипСравнения Из МассивИнвертируемыхТиповСравнения Цикл
ПрямойТипСравнения = Вычислить("ВидСравнения." + ТипСравнения);
Если ПрямойТипСравнения = ВидСравненияП Тогда
Возврат Вычислить("ВидСравнения.Не" + ТипСравнения);
КонецЕсли;
ОбратныйТипСравнения = Вычислить("ВидСравнения.Не" + ТипСравнения);
Если ОбратныйТипСравнения = ВидСравненияП Тогда
Возврат Вычислить("ВидСравнения." + ТипСравнения);
КонецЕсли;
КонецЦикла;
Возврат ВидСравненияП;
КонецФункции
// Копирует один порядок в другой. Приемник перед копированием очищается.
//
// Параметры:
// пПорядокПриемник - Порядок - куда копируем;
// пПорядокИсточник - Порядок - откуда копируем.
//
Процедура СкопироватьПорядокПостроителяЛкс(пПорядокПриемник, пПорядокИсточник) Экспорт
пПорядокПриемник.Очистить();
Для Каждого ЭлементПорядка Из пПорядокИсточник Цикл
пПорядокПриемник.Добавить(ЭлементПорядка.ПутьКДанным, ЭлементПорядка.Имя, , ЭлементПорядка.Направление);
КонецЦикла;
КонецПроцедуры // СкопироватьПорядокЛкс()
// Трансформирует порядок в порядок компоновки.
//
// Параметры:
// ПорядокКомпоновки - ПорядокКомпоновкиДанных;
// Порядок - Порядок.
//
Процедура ТрансформироватьПорядокВПорядокКомпоновкиЛкс(ПорядокКомпоновки, Порядок) Экспорт
ЭлементыКомпоновки = ПорядокКомпоновки.Элементы;
ЭлементыКомпоновки.Очистить();
Для Каждого Элемент Из Порядок Цикл
ЭлементКомпоновки = ЭлементыКомпоновки.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
ЭлементКомпоновки.Использование = Истина;
ЭлементКомпоновки.Поле = Новый ПолеКомпоновкиДанных(Элемент.ПутьКДанным);
Если Элемент.Направление = НаправлениеСортировки.Возр Тогда
ЭлементКомпоновки.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр;
Иначе//Если Элемент.Направление = НаправлениеСортировки.Убыв Тогда
ЭлементКомпоновки.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура СкопироватьПорядокЛюбойЛкс(ПорядокПриемник, ПорядокИсточник, ТолькоИспользуемые = Ложь, ПроверятьДоступность = Ложь, ОчищатьПриемник = Истина) Экспорт
Если Истина
И ТипЗнч(ПорядокИсточник) = Тип("Порядок")
И ТипЗнч(ПорядокПриемник) = Тип("Порядок")
Тогда
СкопироватьПорядокПостроителяЛкс(ПорядокПриемник, ПорядокИсточник);
ИначеЕсли Истина
И ТипЗнч(ПорядокИсточник) = Тип("ПорядокКомпоновкиДанных")
И ТипЗнч(ПорядокПриемник) = Тип("ПорядокКомпоновкиДанных")
Тогда
СкопироватьЭлементыКомпоновкиЛкс(ПорядокПриемник, ПорядокИсточник,, ОчищатьПриемник);
ИначеЕсли Истина
И ТипЗнч(ПорядокИсточник) = Тип("Порядок")
И ТипЗнч(ПорядокПриемник) = Тип("ПорядокКомпоновкиДанных")
Тогда
ТрансформироватьПорядокВПорядокКомпоновкиЛкс(ПорядокПриемник, ПорядокИсточник);
Иначе
ВызватьИсключение "Неверные типы параметров";
КонецЕсли;
КонецПроцедуры
// Возвращает текущее время в миллисекундах.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Число.
//
Функция ТекущееВремяВМиллисекундахЛкс() Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Результат = мПлатформа.ПолучитьТекущееВремяВМиллисекундах();
Возврат Результат;
КонецФункции
// Выполняет запрос. Опционально сообщает его текст и время выполнения.
// Удобно для оптимизации.
//
// Параметры:
// Запрос - Запрос;
// *ЛиОтладка - Булево, *Ложь - показывать тексты запросов и время выполнения.
// *Заголовок - Строка, *"" - название запроса.
//
// Возвращаемое значение:
// РезультатЗапроса.
//
Функция ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка = Ложь, Заголовок = "") Экспорт
Если ЛиОтладка Тогда
ВремяНачала = ТекущееВремяВМиллисекундахЛкс();
КонецЕсли;
Результат = Запрос.Выполнить();
Если ЛиОтладка Тогда
Текст = Новый ТекстовыйДокумент;
Текст.УстановитьТекст(Запрос.Текст);
Текст.Показать(Заголовок + " - " + Строка(ТекущееВремяВМиллисекундахЛкс() - ВремяНачала) + " мс");
КонецЕсли;
Возврат Результат;
КонецФункции // ВыполнитьЗамеритьЗапросЛкс()
// Получает константу языка запросов заданного типа с учетом квалификаторов описания типов.
//
// Параметры:
// ТипПоля - Тип;
// ОписаниеТипов - ОписаниеТипов - для обращения к квалификаторам.
//
// Возвращаемое значение:
// Строка.
//
Функция ПустоеЗначениеПоТипуНаЯзыкеЗапросовЛкс(ТипПоля, ОписаниеТипов = Неопределено) Экспорт
Если ТипПоля = Тип("Строка") Тогда
Результат = "ВЫРАЗИТЬ("""" КАК СТРОКА(" + Формат(ОписаниеТипов.КвалификаторыСтроки.Длина, "ЧН=; ЧГ=") + "))";
ИначеЕсли ТипПоля = Тип("Число") Тогда
Результат = "ВЫРАЗИТЬ(0 КАК ЧИСЛО(" + Формат(ОписаниеТипов.КвалификаторыЧисла.Разрядность, "ЧН=; ЧГ=") + ", "
+ Формат(ОписаниеТипов.КвалификаторыЧисла.РазрядностьДробнойЧасти, "ЧН=; ЧГ=") + "))";
ИначеЕсли ТипПоля = Тип("Дата") Тогда
Если ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Дата Тогда
Результат = "ДАТАВРЕМЯ(1,1,1)";
Иначе
Результат = "ДАТАВРЕМЯ(1,1,1,0,0,0)";
КонецЕсли;
ИначеЕсли ТипПоля = Тип("Булево") Тогда
Результат = "ЛОЖЬ";
ИначеЕсли ТипПоля = Тип("NULL") Тогда
Результат = "NULL";
ИначеЕсли ТипПоля = Тип("НЕОПРЕДЕЛЕНО") Тогда
Результат = "НЕОПРЕДЕЛЕНО";
ИначеЕсли ТипПоля = Тип("ВидДвиженияНакопления") Тогда
Результат = "ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)";
ИначеЕсли ТипПоля = Тип("ВидДвиженияБухгалтерии") Тогда
Результат = "ЗНАЧЕНИЕ(ВидДвиженияБухгалтерии.Дебет)";
ИначеЕсли ТипПоля = Тип("ВидСчета") Тогда
Результат = "ЗНАЧЕНИЕ(ВидСчета.Активный)";
Иначе
МетаданныеТипаПоля = Метаданные.НайтиПоТипу(ТипПоля);
Если МетаданныеТипаПоля <> Неопределено Тогда
// Антибаг платформы 8.1.10.50
Если КорневойТипКонфигурацииЛкс(МетаданныеТипаПоля) = "ПланОбмена" Тогда
Результат = "НЕОПРЕДЕЛЕНО";
Возврат Результат;
КонецЕсли;
Результат = "ЗНАЧЕНИЕ(" + МетаданныеТипаПоля.ПолноеИмя() + ".ПустаяСсылка)";
Иначе
//СообщитьЛкс("Неизвестный тип поля при формировании имитатора результата: " + ТипПоля, СтатусСообщения.Важное);
Результат = "NULL";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьКонстантуТипаЗапроса()
// Возвращает текст запроса только из констант, дающий идентичный переданному набор колонок.
//
// Параметры:
// КоллекцияПолей - КоллекцияКолонокТаблицыЗначений, КоллекцияКолонокДереваЗначений, КоллекцияКолонокРезультатаЗапроса.
//
// Возвращаемое значение:
// Текст.
//
Функция ПолучитьЗапросИмитаторКоллекцииПолейЛкс(КоллекцияПолей) Экспорт
// Формирование запроса-имитатора
ОписаниеПолей = "";
Для Каждого Колонка Из КоллекцияПолей Цикл
ОписаниеПолей = ОписаниеПолей + ", ";
МассивТипов = Колонка.ТипЗначения.Типы();
НачальноеКоличество = МассивТипов.Количество();
Для СчетчикМассивТипов = 1 По НачальноеКоличество Цикл
ТипПоля = МассивТипов[НачальноеКоличество - СчетчикМассивТипов];
Если ТипПоля = Тип("NULL") Тогда
МассивТипов.Удалить(НачальноеКоличество - СчетчикМассивТипов);
КонецЕсли;
КонецЦикла;
// Этот стиль строго фиксирован и0ие90цаун787
ОписаниеПолей = ОписаниеПолей + "ВЫБОР";
ЭтоПервыйТип = Истина;
Для Каждого ТипПоля Из МассивТипов Цикл
Если ЭтоПервыйТип Тогда
УсловиеТипа = " КОГДА ""!ИмяПоля!""=""" + Колонка.Имя + """";
ЭтоПервыйТип = Ложь;
Иначе
УсловиеТипа = " КОГДА ЛОЖЬ";
КонецЕсли;
ОписаниеПолей = ОписаниеПолей + УсловиеТипа + " ТОГДА " + ПустоеЗначениеПоТипуНаЯзыкеЗапросовЛкс(ТипПоля, Колонка.ТипЗначения);
КонецЦикла;
ОписаниеПолей = ОписаниеПолей + " КОНЕЦ КАК " + Колонка.Имя; // запрещенные имена например "Соединение" так вызывают ошибку?
КонецЦикла;
Результат = "ВЫБРАТЬ " + Сред(ОписаниеПолей, 3);
Возврат Результат;
КонецФункции
// Присваивает первому параметру второй в случае их неравенства.
// Удобно использовать для избежания установки признака модифицированности объекта в случае присвоения реквизиту объекта его же значения.
//
// Параметры:
// Переменная - Произвольный - переменная, которой нужно присвоить значение;
// Значение - Произвольный - присваиваемое значение;
// выхМодифицированность - Булево - в эту переменную записывается Истина, если значение было изменено в этом методе
//
// Возвращаемое значение:
// Булево - Истина если переменная теперь содержит указанное значение.
//
Функция ПрисвоитьЕслиНеРавноЛкс(Переменная, Значение, выхМодифицированность = Неопределено, ПодавитьОшибки = Ложь) Экспорт
Если Переменная <> Значение Тогда
Попытка
Переменная = Значение;
Исключение
Если Не ПодавитьОшибки Тогда
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
выхМодифицированность = Истина;
КонецЕсли;
Возврат Переменная = Значение;
КонецФункции
// Получает индекс картинки отражающей корневой тип и статус ссылки.
// Индекс потом используется с общей картинкой ЛксСостояниеСсылки.
//
// Параметры:
// пСсылка - Ссылка - целевая;
// *пЛиОпределятьСтатусСсылки - Булево, *Неопределено - признак необходимости определения статуса.
//
// Возвращаемое значение:
// - Число - индекс картинки.
//
Функция ПолучитьИндексКартинкиСсылкиЛкс(Ссылка, ЛиОпределятьСтатусСсылки = Неопределено, ЗначенияРеквизитов = Неопределено) Экспорт
Если ЛиОпределятьСтатусСсылки = Неопределено Тогда
//пЛиОпределятьСтатусСсылки = ПараметрыСеанса.ЛксОпределятьСтатусСсылкиПриВыводе;
ЛиОпределятьСтатусСсылки = Ложь;
КонецЕсли;
Если ЗначенияРеквизитов = Неопределено Тогда
ЗначенияРеквизитов = Ссылка;
КонецЕсли;
КорневойТип = КорневойТипКонфигурацииЛкс(Ссылка);
ИндексКартинки = -1;
Если КорневойТип = "Документ" Тогда
ИндексКартинки = 0;
Если ЛиОпределятьСтатусСсылки Тогда
Попытка
Проведен = ЗначенияРеквизитов.Проведен;
Исключение
Проведен = Ложь;
КонецПопытки;
Попытка
ПометкаУдаления = ЗначенияРеквизитов.ПометкаУдаления;
Исключение
ПометкаУдаления = Ложь;
КонецПопытки;
Если Проведен = Истина Тогда
ИндексКартинки = 0;
ИначеЕсли ПометкаУдаления = Истина Тогда
ИндексКартинки = 1;
Иначе
ИндексКартинки = 2;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "Справочник" Тогда
ИндексКартинки = 3;
Если ЛиОпределятьСтатусСсылки Тогда
Попытка
ЭтоГруппа = ЗначенияРеквизитов.ЭтоГруппа;
Исключение
ЭтоГруппа = Ложь;
КонецПопытки;
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = ?(ЭтоГруппа = Истина, 6, 4);
Иначе
ИндексКартинки = ?(ЭтоГруппа = Истина, 5, 3);
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "Задача" Тогда
ИндексКартинки = 7;
Если ЛиОпределятьСтатусСсылки Тогда
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = 8;
Иначе
ИндексКартинки = 7;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "ПланВидовХарактеристик" Тогда
ИндексКартинки = 9;
Если ЛиОпределятьСтатусСсылки Тогда
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = 10;
Иначе
ИндексКартинки = 9;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "ПланОбмена" Тогда
ИндексКартинки = 15;
Если ЛиОпределятьСтатусСсылки Тогда
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = 16;
Иначе
ИндексКартинки = 15;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "БизнесПроцесс" Тогда
ИндексКартинки = 19;
//Если пЛиОпределятьСтатусСсылки Тогда
// Если ЗначенияРеквизитов.ПометкаУдаления Тогда
// ИндексКартинки = 20;
// Иначе
// ИндексКартинки = 19;
// КонецЕсли;
//КонецЕсли;
ИначеЕсли КорневойТип = "ПланВидовРасчета" Тогда
ИндексКартинки = 17;
Если ЛиОпределятьСтатусСсылки Тогда
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = 18;
Иначе
ИндексКартинки = 17;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "Перечисление" Тогда
ИндексКартинки = 11;
ИначеЕсли КорневойТип = "РегистрСведений" Тогда
ИндексКартинки = 12;
ИначеЕсли КорневойТип = "Константа" Тогда
ИндексКартинки = 14;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции // ПолучитьИндексКартинкиСсылкиЛкс()
// Добавляет в таблицу строки из другой таблицы и в них значения колонок с совпадающими наименованиями.
//
// Параметры:
// ТаблицаИсточник - ТаблицаЗначений, ТабличнаяЧасть - откуда берутся значения;
// ТаблицаПриемник - ТаблицаЗначений, ТабличнаяЧасть - куда добавляются строки;
// СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк;
// СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет.
// ОчиститьПередЗагрузкой - Булево, *Ложь - очищать приемник перед загрузкой, ускоряет выполнение
// ОбязательныеКолонки - Структура, *Неопределено - имена колонок таблицы, которые нужно обязательно загрузить если они есть в приемнике.
// Остальные будут загружены, если приемник пустой. Если не указано, то все совпадающие колонки обязательны.
//
Процедура ЗагрузитьВТаблицуЗначенийЛкс(Знач ТаблицаИсточник, Знач ТаблицаПриемник, Знач СтруктураЗначенийПоУмолчанию = Неопределено, Знач СтруктураНовыхЗначений = Неопределено,
Знач ОчиститьПередЗагрузкой = Ложь, Знач ОбязательныеКолонки = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаПриемник = Новый ТаблицаЗначений;
ТаблицаИсточник = Новый ТаблицаЗначений;
СтруктураЗначенийПоУмолчанию = Новый Структура;
СтруктураНовыхЗначений = Новый Структура;
#КонецЕсли
Если ТаблицаИсточник = ТаблицаПриемник Тогда
ВызватьИсключение "Нельзя загружать коллекцию в саму себя";
КонецЕсли;
Если ОчиститьПередЗагрузкой Или ТаблицаПриемник.Количество() = 0 Тогда
ТаблицаПриемник.Очистить();
Если Истина
И СтруктураЗначенийПоУмолчанию = Неопределено
И СтруктураНовыхЗначений = Неопределено
И ЛиТабличнаяЧастьЛкс(ТаблицаПриемник)
Тогда
// оптимизация - для ТЧ это самый быстрый способ
Если ЛиТабличнаяЧастьЛкс(ТаблицаИсточник) Тогда
ТаблицаИсточник = ТаблицаИсточник.Выгрузить();
КонецЕсли;
ТаблицаПриемник.Загрузить(ТаблицаИсточник);
Возврат;
КонецЕсли;
КонецЕсли;
Если ТаблицаИсточник.Количество() = 0 Тогда
Возврат;
КонецЕсли;
СтрокаСовпадающихКолонок = "";
Если ТипЗнч(ТаблицаИсточник) = Тип("ТаблицаЗначений") Тогда
КолонкиИсточника = ТаблицаИсточник.Колонки;
Иначе
КолонкиИсточника = ТаблицаИсточник.ВыгрузитьКолонки().Колонки;
КонецЕсли;
ЛиПриемникТаблицаЗначений = ТипЗнч(ТаблицаПриемник) = Тип("ТаблицаЗначений");
Если ЛиПриемникТаблицаЗначений Тогда
КолонкиПриемника = ТаблицаПриемник.Колонки;
Иначе
КолонкиПриемника = ТаблицаПриемник.ВыгрузитьКолонки().Колонки;
КонецЕсли;
ИмяПоляНомерСтроки = ПеревестиСтроку("НомерСтроки");
СовпадающиеКолонки = Новый Массив;
// Ранее применялась однострочная форма кода
Для каждого Колонка Из КолонкиПриемника Цикл
Если СтруктураНовыхЗначений <> Неопределено Тогда
Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если Истина
И (Ложь
Или ЛиПриемникТаблицаЗначений
Или Колонка.Имя <> ИмяПоляНомерСтроки)
И (Ложь
Или ОбязательныеКолонки = Неопределено
Или ОбязательныеКолонки.Свойство(Колонка.Имя))
И КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено
Тогда
СовпадающиеКолонки.Добавить(НРег(Колонка.Имя));
КонецЕсли;
КонецЦикла;
Если ЛиПриемникТаблицаЗначений И ТаблицаПриемник.Количество() = 0 Тогда
// оптимизация - быстрый способ
Для Счетчик = 1 По ТаблицаИсточник.Количество() Цикл
ТаблицаПриемник.Добавить();
КонецЦикла;
Если СтруктураНовыхЗначений <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураНовыхЗначений Цикл
ТаблицаПриемник.ЗаполнитьЗначения(КлючИЗначение.Значение, КлючИЗначение.Ключ); // Несовместимо с ТЧ
КонецЦикла;
КонецЕсли;
ИндексыПересоздать = Новый Соответствие;
Для Каждого ИмяКолонки Из СовпадающиеКолонки Цикл
Массив = ТаблицаИсточник.ВыгрузитьКолонку(ИмяКолонки);
ТаблицаПриемник.ЗагрузитьКолонку(Массив, ИмяКолонки);
Для Каждого ИндексТаблицы Из ТаблицаПриемник.Индексы Цикл
Если Найти(" " + Нрег(ИндексТаблицы) + ",", " " + ИмяКолонки + ",") > 0 Тогда
ИндексыПересоздать.Вставить(ИндексТаблицы);
КонецЕсли;
КонецЦикла;
КонецЦикла;
// Антибаг https://www.hostedredmine.com/issues/936307
Для Каждого КлючИЗначение Из ИндексыПересоздать Цикл
ОпределениеИндекса = "" + КлючИЗначение.Ключ;
ТаблицаПриемник.Индексы.Удалить(КлючИЗначение.Ключ);
ТаблицаПриемник.Индексы.Добавить(ОпределениеИндекса);
КонецЦикла;
Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураЗначенийПоУмолчанию Цикл
Если СовпадающиеКолонки.Найти(НРег(КлючИЗначение.Ключ)) <> Неопределено Тогда
Продолжить;
КонецЕсли;
ТаблицаПриемник.ЗаполнитьЗначения(КлючИЗначение.Значение, КлючИЗначение.Ключ); // Несовместимо с ТЧ
КонецЦикла;
КонецЕсли;
Иначе
СтрокаСовпадающихКолонок = СтрСоединитьЛкс(СовпадающиеКолонки, ",");
Для каждого СтрокаТаблицыИсточника Из ТаблицаИсточник Цикл
СтрокаТаблицыПриемника = ТаблицаПриемник.Добавить();
Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураЗначенийПоУмолчанию);
КонецЕсли;
// Заполним значения в совпадающих колонках.
ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтрокаТаблицыИсточника, СтрокаСовпадающихКолонок);
//Для каждого ЭлементМассива Из МассивСовпадающихКолонок Цикл
// СтрокаТаблицыПриемника[ЭлементМассива] = СтрокаТаблицыИсточника[ЭлементМассива];
//КонецЦикла;
Если СтруктураНовыхЗначений <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураНовыхЗначений);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
// Слияние таблиц значений одинаковой структуры. Меньшая из таблиц вливается в бОльшую.
//
// Параметры:
// Таблица1 - ТаблицаЗначений -
// Таблица2 - ТаблицаЗначений -
// ОбязательныеКолонки1 - Структура, *Неопределено - имена колонок таблицы, которые нужно обязательно загрузить если они есть в приемнике.
// Остальные будут загружены, если приемник пустой. Если не указано, то все совпадающие колонки обязательны.
// ОбязательныеКолонки2 - Структура, *Неопределено - имена колонок таблицы, которые нужно обязательно загрузить если они есть в приемнике.
// Остальные будут загружены, если приемник пустой. Если не указано, то все совпадающие колонки обязательны.
//
// Возвращаемое значение:
// ТаблицаЗначений -
//
Функция ОбъединитьТаблицыЗначенийЛкс(Знач Таблица1, Знач Таблица2, Знач ОбязательныеКолонки1 = Неопределено, Знач ОбязательныеКолонки2 = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Таблица1 = Новый ТаблицаЗначений;
Таблица2 = Новый ТаблицаЗначений;
#КонецЕсли
Если Ложь
Или Таблица1 = Таблица2
Или Таблица2.Количество() = 0
Тогда
Возврат Таблица1;
ИначеЕсли Ложь
Или Таблица1.Количество() = 0
Тогда
Возврат Таблица2;
КонецЕсли;
Если Таблица1.Количество() > Таблица2.Количество() Тогда
ЗагрузитьВТаблицуЗначенийЛкс(Таблица2, Таблица1,,,, ОбязательныеКолонки2);
Результат = Таблица1;
Иначе
ЗагрузитьВТаблицуЗначенийЛкс(Таблица1, Таблица2,,,, ОбязательныеКолонки1);
Результат = Таблица2;
КонецЕсли;
Возврат Результат;
КонецФункции
// Непростетирована. Добавляет в дерево значений строки из другой таблицы значений и
// в них значения колонок с совпадающими наименованиями.
//
// Параметры:
// ТаблицаИсточник - таблица значений, откуда берутся значения;
// ТаблицаПриемник - таблица значений, куда добавляются строки;
// *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк;
// *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет.
//
Процедура ЗагрузитьВДеревоЗначенийЛкс(ДеревоИсточник, ДеревоПриемник, СтруктураЗначенийПоУмолчанию = Неопределено, СтруктураНовыхЗначений = Неопределено, ОчиститьПередЗагрузкой = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ДеревоИсточник = Новый ДеревоЗначений;
ДеревоПриемник = Новый ДеревоЗначений;
#КонецЕсли
СтрокаСовпадающихКолонок = "";
Разделитель = ",";
КолонкиИсточника = ДеревоИсточник.Колонки;
Для каждого Колонка Из ДеревоПриемник.Колонки Цикл
Если СтруктураНовыхЗначений <> Неопределено Тогда
Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено Тогда
СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя;
КонецЕсли;
КонецЦикла;
СтрокаСовпадающихКолонок = Сред(СтрокаСовпадающихКолонок, СтрДлина(Разделитель) + 1);
Если ОчиститьПередЗагрузкой Тогда
ДеревоПриемник.Строки.Очистить();
КонецЕсли;
ЗагрузитьВСтрокиДереваЗначенийЛкс(ДеревоИсточник, ДеревоПриемник, СтруктураЗначенийПоУмолчанию,
СтруктураНовыхЗначений, СтрокаСовпадающихКолонок);
КонецПроцедуры // ЗагрузитьВДеревоЗначенийЛкс()
// Непростетирована. Добавляет в дерево значений строки из другой таблицы значений и
// в них значения колонок с совпадающими наименованиями.
//
// Параметры:
// ТаблицаИсточник - таблица значений, откуда берутся значения;
// ТаблицаПриемник - таблица значений, куда добавляются строки;
// *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк;
// *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет.
//
Процедура ЗагрузитьВСтрокиДереваЗначенийЛкс(СтрокаРодительИсточника, СтрокаРодительПриемника,
СтруктураЗначенийПоУмолчанию, СтруктураНовыхЗначений, СтрокаСовпадающихКолонок) Экспорт
СтрокиПриемника = СтрокаРодительПриемника.Строки;
Для каждого СтрокаИсточника Из СтрокаРодительИсточника.Строки Цикл
СтрокаПриемника = СтрокиПриемника.Добавить();
Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтруктураЗначенийПоУмолчанию);
КонецЕсли;
// Заполним значения в совпадающих колонках.
ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтрокаИсточника, СтрокаСовпадающихКолонок);
Если СтруктураНовыхЗначений <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтруктураНовыхЗначений);
КонецЕсли;
ЗагрузитьВСтрокиДереваЗначенийЛкс(СтрокаИсточника, СтрокаПриемника, СтруктураЗначенийПоУмолчанию,
СтруктураНовыхЗначений, СтрокаСовпадающихКолонок);
КонецЦикла;
КонецПроцедуры
// Устарела. Вместо нее нужно вызывать СообщитьЛкс()
//
// Параметры:
// ТекстСообщения - Строка;
// МодальныйРежим - Булево, *Ложь;
// *Статус - СтатусСообщения, *Неопределено.
//
Процедура СообщитьСУчетомМодальностиЛкс(ТекстСообщения, _МодальныйРежим = Ложь, Статус = Неопределено) Экспорт
СообщитьЛкс(ТекстСообщения, Статус);
КонецПроцедуры
// Сообщает итог индикации (длительность).
//
// Параметры:
// Индикатор - Структура - индикатора, полученная методом ПолучитьИндикаторПроцессаЛкс.
//
Процедура СообщитьИтогИндикацииЛкс(Индикатор) Экспорт
ТекущаяДата = ТекущаяДата();
ПрошлоВремени = ТекущаяДата - Индикатор.ДатаНачалаПроцесса;
ПрошлоВремениСтрока = Формат(Дата(1,1,1) + ПрошлоВремени, "ДЛФ=T; ДП=");
Если Индикатор.КоличествоПроходов = 1 Тогда
ТекстСообщения = СтрШаблонЛкс("%1 завершено за %2 (%3 сек)", Индикатор.ПредставлениеПроцесса, ПрошлоВремениСтрока, ПрошлоВремени);
Иначе
ТекстСообщения = СтрШаблонЛкс(НСтр("ru = '%1 завершено за %2 (%3 сек), обработано %4 элементов.';
|en = '%1 completed in %2 (%3 sec), processed %4 elements.'"), Индикатор.ПредставлениеПроцесса, ПрошлоВремениСтрока, ПрошлоВремени, Индикатор.Счетчик);
Если Индикатор.Счетчик > 0 Тогда
ТекстСообщения = ТекстСообщения + СтрШаблонЛкс(НСтр("ru = 'Среднее время элемента - %1 мс';
|en = Average element time: %1 ms'"), Формат(ПрошлоВремени / Индикатор.Счетчик * 1000, "ЧЦ=15; ЧДЦ=2; ЧН="));
КонецЕсли;
КонецЕсли;
СообщитьЛкс(ТекстСообщения);
КонецПроцедуры
// Получает более подробное представление значения, чем штатное приведение к строковому типу.
//
// Параметры:
// Значение - Произвольный - что нужно представить.
//
// Возвращаемое значение:
// Строка - представление.
//
Функция РасширенноеПредставлениеЗначенияЛкс(Значение, Знач КолонкаТабличногоПоля = Неопределено, Знач ДобавлятьПредставлениеТипа = Ложь, РасширенноеПредставлениеХранилищЗначений = Ложь,
Знач ВозвращатьПредставлениеСсылки = Истина, Знач ЯвноеПреставлениеПустого = Ложь, Знач МаксЭлементовДляПредставления = 10) Экспорт
Результат = "";
ТипЗначения = ТипЗнч(Значение);
Если ТипЗначения = Тип("Строка") Тогда
Если ДобавлятьПредставлениеТипа Или ЯвноеПреставлениеПустого Тогда
Результат = Результат + """" + Значение + """";
Иначе
Результат = Результат + Значение;
КонецЕсли;
ИначеЕсли ТипЗначения = Тип("Дата") Тогда
Результат = "" + Значение; // Хорошо бы формат колонки применить
Миллисекунды = МиллисекундыДатыЛкс(Значение);
Если Миллисекунды > 0 Тогда
Результат = Результат + "." + Формат(Миллисекунды, "ЧЦ=3; ЧВН=");
КонецЕсли;
Иначе
Разделитель = ", ";
КоличествоЭлементов = КоличествоЭлементовКоллекцииЛкс(Значение);
Если КоличествоЭлементов <> Неопределено Тогда
Результат = "(" + КоличествоЭлементов + ")";
КонецЕсли;
Представления = Новый СписокЗначений;
Если ТипЗначения = Тип("Граница") Тогда
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗначения;
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + Значение.ВидГраницы + ", " + Значение.Значение;
ИначеЕсли ЛиТипСсылкиТочкиМаршрутаЛкс(ТипЗначения) Тогда
Результат = "" + Значение;
Если Не ЗначениеЗаполнено(Результат) Тогда
Результат = "(" + Значение.Имя + ")";
КонецЕсли;
ИначеЕсли ТипЗначения = Тип("ОписаниеТипов") Тогда
#Если Сервер И Не Сервер Тогда
Значение = Новый ОписаниеТипов;
#КонецЕсли
ПредставлениеКоллекции = "";
Коллекция = Значение.Типы();
ПредставлениеОбрезано = Ложь;
Для Каждого Тип Из Коллекция Цикл
Если МаксЭлементовДляПредставления = 0 Тогда
ПредставлениеОбрезано = Истина;
Прервать;
КонецЕсли;
Представления.Добавить(ПредставлениеТипаЛкс(Тип, Значение));
МаксЭлементовДляПредставления = МаксЭлементовДляПредставления - 1;
КонецЦикла;
Если ПредставлениеОбрезано Тогда
Представления.Добавить("…");
Иначе
Представления.СортироватьПоЗначению();
КонецЕсли;
Если Коллекция.Количество() > 1 Тогда
Результат = "(" + XMLСтрока(Коллекция.Количество()) + ")";
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗначения;
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
КонецЕсли;
Результат = Результат + СтрСоединитьЛкс(Представления, Разделитель);
ИмяОпределяемогоТипа = ИмяОпределяемогоТипаИзОписанияТиповЛкс(Значение);
Если ЗначениеЗаполнено(ИмяОпределяемогоТипа) Тогда
Результат = Результат + " = " + ИмяОпределяемогоТипа;
КонецЕсли;
ИначеЕсли Ложь
Или ТипЗначения = Тип("Структура")
Или ТипЗначения = Тип("Соответствие")
Или ТипЗначения = Тип("ФиксированнаяСтруктура")
Или ТипЗначения = Тип("ФиксированноеСоответствие")
Тогда
ПредставлениеКоллекции = "";
ПредставлениеОбрезано = Ложь;
Для Каждого КлючИЗначение Из Значение Цикл
Если МаксЭлементовДляПредставления = 0 Тогда
ПредставлениеОбрезано = Истина;
Прервать;
КонецЕсли;
Представления.Добавить("" + КлючИЗначение.Ключ + " = " + КлючИЗначение.Значение);
МаксЭлементовДляПредставления = МаксЭлементовДляПредставления - 1;
КонецЦикла;
Если ПредставлениеОбрезано Тогда
Представления.Добавить("…");
Иначе
Представления.СортироватьПоЗначению();
КонецЕсли;
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗначения;
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + СтрСоединитьЛкс(Представления, Разделитель);
ИначеЕсли Ложь
Или ТипЗначения = Тип("Массив")
Или ТипЗначения = Тип("ФиксированныйМассив")
Или ТипЗначения = Тип("СписокЗначений")
Тогда
ПредставлениеКоллекции = "";
НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
ПредставлениеОбрезано = Ложь;
Для Каждого ЭлементМассива Из Значение Цикл
Если МаксЭлементовДляПредставления = 0 Тогда
ПредставлениеОбрезано = Истина;
Представления.Добавить("…");
Прервать;
КонецЕсли;
Если Ложь
Или (Истина
// http://www.hostedredmine.com/issues/881633
И НомерВерсииПлатформы >= 803006
И ТипЗнч(ЭлементМассива) = Тип("РасширениеКонфигурации"))
Или ТипЗнч(ЭлементМассива) = Тип("ЗначениеПоляАнализаДанных") // https://www.hostedredmine.com/issues/932745
Тогда
ПредставлениеЭлемента = "" + ТипЗнч(ЭлементМассива);
Иначе
ПредставлениеЭлемента = "" + ЭлементМассива;
КонецЕсли;
Представления.Добавить(ПредставлениеЭлемента);
МаксЭлементовДляПредставления = МаксЭлементовДляПредставления - 1;
КонецЦикла;
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗначения;
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + СтрСоединитьЛкс(Представления, Разделитель);
ИначеЕсли ТипЗначения = Тип("ТабличныйДокумент") Тогда
#Если Сервер И Не Сервер Тогда
Значение = Новый ТабличныйДокумент;
#КонецЕсли
Результат = "(" + Значение.ВысотаТаблицы + ")" + Значение;
ИначеЕсли ТипЗначения = Тип("ТекстовыйДокумент") Тогда
#Если Сервер И Не Сервер Тогда
Значение = Новый ТабличныйДокумент;
#КонецЕсли
Результат = "(" + Значение.КоличествоСтрок() + ")" + Значение;
ИначеЕсли ТипЗначения = Тип("COMОбъект") Тогда
ирПлатформа = ирКэш.Получить();
ИмяОбщегоТипа = ирПлатформа.ПолноеИмяТипаCOMОбъекта(Значение);
ПолноеИмяОсновногоКласса = СтрокаМеждуМаркерамиЛкс(ИмяОбщегоТипа, "{", "}", Ложь);
ИмяОбщегоТипа = СтрЗаменить(ИмяОбщегоТипа, ".{" + ПолноеИмяОсновногоКласса + "}", "");
Результат = Результат + ИмяОбщегоТипа;
ИначеЕсли Истина
И РасширенноеПредставлениеХранилищЗначений
И ТипЗначения = Тип("ХранилищеЗначения")
Тогда
Результат = Результат + ТипЗначения;
ВложенноеЗначение = Значение.Получить();
Результат = Результат + ": " + ВложенноеЗначение;
ИначеЕсли ТипЗначения = Тип("Файл") Тогда
Результат = Результат + ТипЗначения;
Результат = Результат + ": " + Значение.ПолноеИмя;
ИначеЕсли ТипЗначения = Тип("РезультатЗапроса") Тогда
Результат = Результат + ТипЗначения;
ИначеЕсли ТипЗначения = Тип("СочетаниеКлавиш") Тогда
Результат = Результат + ТипЗначения;
Результат = Результат + ": " + ПредставлениеСочетанияКлавишЛкс(Значение);
Иначе
СтрокаФормата = "ЧН=";
Если КолонкаТабличногоПоля <> Неопределено Тогда
СтрокаФормата = КолонкаТабличногоПоля.Формат;
// Отключено из-за потери дробной части при 0,0. Зачем это было сделано изначально, пока не разобрался
//Если Истина
// И ПустаяСтрока(СтрокаФормата)
// И ТипЗнч(КолонкаТабличногоПоля.ЭлементУправления) = Тип("ПолеВвода")
//Тогда
// КвалификаторыЧисла = КолонкаТабличногоПоля.ЭлементУправления.ТипЗначения.КвалификаторыЧисла;
// СтрокаФормата = "ЧЦ = " + КвалификаторыЧисла.Разрядность + "; ЧДЦ = " + КвалификаторыЧисла.РазрядностьДробнойЧасти;
//КонецЕсли;
КонецЕсли;
Если ВозвращатьПредставлениеСсылки Или Не ЛиТипСсылкиБДЛкс(ТипЗначения) Тогда
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗначения + ": ";
КонецЕсли;
Результат = Результат + Формат(Значение, СтрокаФормата);
Если Истина
И ЯвноеПреставлениеПустого
//И Не ЗначениеЗаполнено(Значение)
И Не ЗначениеЗаполнено(Результат)
Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Результат = мПлатформа.ПредставлениеПустогоЗначенияЛкс(Значение);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПредставлениеЗначенияЛкс(Значение) Экспорт
Попытка
Результат = "" + Значение;
Исключение
// Некоторые типы ошибочно не имеют отображения в строку https://www.hostedredmine.com/issues/937039
Результат = ТипЗнч(Значение);
КонецПопытки;
Возврат Результат;
КонецФункции
Функция КодПроверкиЗначенияВыраженияЛкс(Знач ПроверяемоеЗначение, Знач ПроверяемоеВыражение, МаксДлинаСтроки = 20, МаксДробныхЗнаков = 6)
ТипЗначения = ТипЗнч(ПроверяемоеЗначение);
Если Ложь
Или ТипЗначения = Тип("Булево")
Или ТипЗначения = Тип("Дата")
Или ТипЗначения = Тип("Неопределено")
Или ТипЗначения = Тип("Null")
Тогда
УсловиеСвойства = ПроверяемоеВыражение + "=" + СтрЗаменить(ПредставлениеЗначенияВоВстроенномЯзыкеЛкс(ПроверяемоеЗначение), " ", "");
ИначеЕсли ТипЗначения = Тип("Число") Тогда
УсловиеСвойства = "Окр(" + ПроверяемоеВыражение + "," + XMLСтрока(МаксДробныхЗнаков) + ")=" + ПредставлениеЗначенияВоВстроенномЯзыкеЛкс(Окр(ПроверяемоеЗначение, МаксДробныхЗнаков));
Иначе
Попытка
ПолучитьПолноеИмяПредопределенногоЗначения(ПроверяемоеЗначение);
ЭтоПримитивное = Истина;
Исключение
ЭтоПримитивное = Ложь
Или ТипЗначения = Тип("Строка")
Или ЛиТипСсылкиБДЛкс(ТипЗначения, Ложь);
КонецПопытки;
Если ЭтоПримитивное Тогда
УсловиеСвойства = "Лев(" + ПроверяемоеВыражение + "," + XMLСтрока(МаксДлинаСтроки) + ")=""" + Лев(ПроверяемоеЗначение, МаксДлинаСтроки) + """";
Иначе
УсловиеСвойства = "";
КонецЕсли;
КонецЕсли;
Возврат УсловиеСвойства;
КонецФункции
Функция МиллисекундыДатыЛкс(Знач Дата) Экспорт
Возврат 1000 * (Дата - НачалоМинуты(Дата) - Секунда(Дата));
КонецФункции
Функция ПредставлениеСвязейПараметровВыбораЛкс(ПолеФормыИлиРеквизитМетаданных) Экспорт
Попытка
СвязиПараметровВыбора = ПолеФормыИлиРеквизитМетаданных.СвязиПараметровВыбора;
Исключение
Возврат "";
КонецПопытки;
#Если Сервер И Не Сервер Тогда
СвязиПараметровВыбора = Новый ФиксированныйМассив();
#КонецЕсли
Результат = "";
Для Каждого Связь Из СвязиПараметровВыбора Цикл
#Если Сервер И Не Сервер Тогда
Связь = Новый СвязьПараметраВыбора;
#КонецЕсли
Если Результат <> "" Тогда
Результат = Результат + ", ";
КонецЕсли;
Результат = Результат + Связь.ПутьКДанным;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ПредставлениеТипаЛкс(Знач Тип, Знач ОписаниеТипов = Неопределено, ИспользоватьИмя = Ложь) Экспорт
Если ИспользоватьИмя Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
ОписаниеТипов = Новый ОписаниеТипов;
#КонецЕсли
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(Тип);
ПредставлениеТипа = мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипа);
Иначе
ПредставлениеТипа = "" + Тип;
КонецЕсли;
Если ОписаниеТипов <> Неопределено Тогда
ДобавитьКвалификаторыВПредставлениеТипаЛкс(ПредставлениеТипа, Тип, ОписаниеТипов);
КонецЕсли;
Возврат ПредставлениеТипа;
КонецФункции
Процедура ДобавитьКвалификаторыВПредставлениеТипаЛкс(ПредставлениеТипа, Знач Тип, Знач ОписаниеТипов) Экспорт
Если Тип = Тип("Число") Тогда
ПредставлениеТипа = ПредставлениеТипа + "(" + ОписаниеТипов.КвалификаторыЧисла.Разрядность + "," + ОписаниеТипов.КвалификаторыЧисла.РазрядностьДробнойЧасти
+ ?(ОписаниеТипов.КвалификаторыЧисла.ДопустимыйЗнак = ДопустимыйЗнак.Неотрицательный, ",Н", "") + ")";
ИначеЕсли Тип = Тип("Строка") Тогда
Если ОписаниеТипов.КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная Тогда
//ВариантДлины = "п";
Иначе
ВариантДлины = ",Ф";
КонецЕсли;
ПредставлениеТипа = ПредставлениеТипа + "(" + XMLСтрока(ОписаниеТипов.КвалификаторыСтроки.Длина) + ВариантДлины + ")";
ИначеЕсли Тип = Тип("Дата") Тогда
Если ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Время Тогда
ПредставлениеКвалификатора = "В";
ИначеЕсли ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда
ПредставлениеКвалификатора = "ДВ";
ИначеЕсли ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Дата Тогда
ПредставлениеКвалификатора = "Д";
КонецЕсли;
ПредставлениеТипа = ПредставлениеТипа + "(" + ПредставлениеКвалификатора + ")";
КонецЕсли;
КонецПроцедуры
// Сравнивает значения свойств объекта <Первый> со значениями свойств объекта <Второй>. Сопоставление производится по именам свойств.
// Отсутствие свойства приравнивается к значению Неопределено.
//
// Параметры:
// Первый - Произвольный - первый объект для сравнения;
// Второй - Произвольный - первый объект для сравнения;
// СвойстваДляСравнения - Строка - перечисленные через запятую свойства для сравнения, допускается не указывать если второй объект является структурой.
//
// Возвращаемое значение:
// Булево - Равны ли значения всех указанных свойств.
//
Функция СравнитьЗначенияСвойствЛкс(Знач Первый, Знач Второй, СвойстваДляСравнения = "") Экспорт
Если ТипЗнч(Второй) = Тип("Структура") И Не ЗначениеЗаполнено(СвойстваДляСравнения) Тогда
СвойстваДляСравнения = СтрСоединитьЛкс(ВыгрузитьСвойствоКоллекцииЛкс(Второй, "Ключ"));
Структура2 = Второй;
ИначеЕсли ТипЗнч(Второй) = Тип("Структура") И СтрЧислоВхождений(СвойстваДляСравнения, ",") = Второй.Количество() - 1 Тогда
Структура2 = Второй;
Иначе
Структура2 = Новый Структура(СвойстваДляСравнения);
ЗаполнитьЗначенияСвойств(Структура2, Второй);
КонецЕсли;
Структура1 = Новый Структура(СвойстваДляСравнения);
ЗаполнитьЗначенияСвойств(Структура1, Первый);
Результат = ОбъектВСтрокуДляСравненияВнутрЛкс(Структура1) = ОбъектВСтрокуДляСравненияВнутрЛкс(Структура2);
Возврат Результат;
КонецФункции
Функция КоличествоОшибокВЖурналеЛкс(Знач Начало, Знач Конец, Знач СтруктураОтбора, Знач МаксимальныйРазмерВыгрузки = Неопределено) Экспорт
АнализЖурналаРегистрации = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирАнализЖурналаРегистрации");
#Если Сервер И Не Сервер Тогда
АнализЖурналаРегистрации = Обработки.ирАнализЖурналаРегистрации.Создать();
#КонецЕсли
СобытияЗадания = АнализЖурналаРегистрации.ПолучитьДанные(Начало, Конец, СтруктураОтбора, МаксимальныйРазмерВыгрузки);
КоличествоОшибокВЖурнале = СобытияЗадания.Количество();
Возврат КоличествоОшибокВЖурнале;
КонецФункции
#Если Клиент Тогда
Процедура ИзменитьОтборКлиентаПоМетаданнымЛкс(ТабличноеПоле, Знач ИмяКолонкиСреднегоИмениМД = "Метаданные", ЭтоКолонкаПолногоИмениМД = Ложь) Экспорт
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
лСтруктураПараметров.Вставить("ОтображатьРегистры", Истина);
лСтруктураПараметров.Вставить("ОтображатьПерерасчеты", Истина);
лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина);
лСтруктураПараметров.Вставить("ОтображатьТабличныеЧасти", Истина);
лСтруктураПараметров.Вставить("ОтображатьКонстанты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", Истина);
лСтруктураПараметров.Вставить("ОтображатьРегламентныеЗадания", Истина);
лСтруктураПараметров.Вставить("ОтображатьОтчеты", Истина);
лСтруктураПараметров.Вставить("ОтображатьОбработки", Истина);
лСтруктураПараметров.Вставить("ОтображатьПоследовательности", Истина);
лСтруктураПараметров.Вставить("МножественныйВыбор", Истина);
лДоступныеОбъекты = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле);
лДоступныеОбъекты.Свернуть(ИмяКолонкиСреднегоИмениМД);
лДоступныеОбъекты = лДоступныеОбъекты.ВыгрузитьКолонку(ИмяКолонкиСреднегоИмениМД);
Если ЭтоКолонкаПолногоИмениМД Тогда
ДоступныеОбъекты = Новый Массив;
Для Каждого ПолноеИмяМД Из лДоступныеОбъекты Цикл
СреднееИмяМД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
ДоступныеОбъекты.Добавить(СреднееИмяМД);
КонецЦикла;
Иначе
//лСтруктураПараметров.Вставить("ОтображатьВиртуальныеТаблицы", Истина);
//лСтруктураПараметров.Вставить("ОтображатьТаблицыИзменений", Истина);
ДоступныеОбъекты = лДоступныеОбъекты;
КонецЕсли;
ЭлементОтбора = ТабличноеПоле.ОтборСтрок[ИмяКолонкиСреднегоИмениМД];
Если Истина
И ЭлементОтбора.Использование
И ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке
Тогда
лНачальноеЗначениеВыбора = ЭлементОтбора.Значение.ВыгрузитьЗначения();
Если ЭтоКолонкаПолногоИмениМД Тогда
НачальноеЗначениеВыбора = Новый Массив;
Для Каждого ПолноеИмяМД Из лНачальноеЗначениеВыбора Цикл
СреднееИмяМД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
НачальноеЗначениеВыбора.Добавить(СреднееИмяМД);
КонецЦикла;
Иначе
НачальноеЗначениеВыбора = лНачальноеЗначениеВыбора;
КонецЕсли;
Иначе
НачальноеЗначениеВыбора = ДоступныеОбъекты;
КонецЕсли;
мПлатформа = ирКэш.Получить();
Форма = мПлатформа.ПолучитьФорму("ВыборОбъектаМетаданных");
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора);
лСтруктураПараметров.Вставить("ДоступныеОбъекты", ДоступныеОбъекты);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
ЗначениеВыбора = Форма.ОткрытьМодально();
Если ЗначениеВыбора <> Неопределено Тогда
Если ЭтоКолонкаПолногоИмениМД Тогда
ТаблицаВсехТаблицБД = ирКэш.ТаблицаВсехТаблицБДЛкс();
МассивИменМД = Новый Массив;
Для Каждого СреднееИмяМД Из ЗначениеВыбора Цикл
СтрокаОписанияТаблицы = ТаблицаВсехТаблицБД.Найти(СреднееИмяМД, "ПолноеИмя");
Если СтрокаОписанияТаблицы <> Неопределено Тогда
МассивИменМД.Добавить(СтрокаОписанияТаблицы.ПолноеИмяМД);
Иначе
МассивИменМД.Добавить(СреднееИмяМД);
КонецЕсли;
КонецЦикла;
Иначе
МассивИменМД = ЗначениеВыбора;
КонецЕсли;
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(МассивИменМД);
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке;
ЭлементОтбора.Значение = СписокЗначений;
ЭлементОтбора.Использование = Истина;
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьДиалогЗаменыИдентификаторовОбъектовЛкс(Знач Объекты) Экспорт
ФормаОбработки = ирОбщий.ПолучитьФормуЛкс("Обработка.ирПоискДублейИЗаменаСсылок.Форма");
Дерево = Новый ДеревоЗначений;
Дерево.Колонки.Добавить("Объект");
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Объекты.Количество(), "Создание дублей объектов");
НачатьТранзакцию();
Попытка
Для Каждого Объект Из Объекты Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КопияОбъекта = Объект.Ссылка.ПолучитьОбъект();
ирОбщий.ЗаменитьИдентификаторОбъектаЛкс(КопияОбъекта);
Попытка
КопияОбъекта.ОбменДанными.Загрузка = Истина;
Исключение
СообщитьЛкс("Для узлов планов обмена групповая замена внутренних идентификаторов не поддерживается");
Возврат;
КонецПопытки;
КопияОбъекта.Записать();
СтрокаГруппы = Дерево.Строки.Добавить();
СтрокаЭлемента = СтрокаГруппы.Строки.Добавить();
СтрокаЭлемента[0] = КопияОбъекта.Ссылка;
СтрокаЭлемента = СтрокаГруппы.Строки.Добавить();
СтрокаЭлемента[0] = Объект;
КонецЦикла;
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
ЗафиксироватьТранзакцию();
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
ФормаОбработки.ОткрытьДляЗаменыПоДеревуСсылок(Дерево,, Ложь);
ФормаОбработки.ОтключатьКонтрольЗаписи = Истина;
ФормаОбработки.РазрешитьУдалениеСНарушениемСсылочнойЦелостности = Ложь;
КонецПроцедуры // ПередОткрытием()
// Оформляет ячейку табличного поля, допускающую значения, не имеющие стандартного отображения в платформе и хранимые отдельно.
// Иными словам колонка отображает данные, хранимые отдельно.
//
// Параметры:
// ОформлениеЯчейки - ОформлениеЯчейки
// Значение - Произвольный - значение для отображения.
//
Процедура ОформитьЯчейкуСРасширеннымЗначениемЛкс(ОформлениеЯчейки, Знач Значение = Неопределено, КолонкаТабличногоПоля = Неопределено, ВыводитьПиктограммуТипа = Истина) Экспорт
Если Значение = Неопределено Тогда
Значение = ОформлениеЯчейки.Значение;
КонецЕсли;
Если ВыводитьПиктограммуТипа Тогда
ТипЗначения = ТипЗнч(Значение);
Если Истина
И ТипЗначения = Тип("Булево")
И ОформлениеЯчейки.ОтображатьФлажок
Тогда
//
Иначе
КартинкаТипа = КартинкаТипаЛкс(ТипЗначения);
Если КартинкаТипа <> Неопределено Тогда
ОформлениеЯчейки.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
РасширенноеПредставление = РасширенноеПредставлениеЗначенияЛкс(Значение, КолонкаТабличногоПоля);
Если Ложь
Или ОформлениеЯчейки.Текст = РасширенноеПредставление
Тогда
Возврат;
КонецЕсли;
//ОформлениеЯчейки.ТолькоПросмотр = Истина;
//ОформлениеЯчейки.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаРасширенногоПредставленияЗначения");
ОформлениеЯчейки.УстановитьТекст(РасширенноеПредставление);
КонецПроцедуры
// Находит файлы в иерархии заданного каталога локальной файловой системы.
//
// Параметры:
// Путь - Строка;
// Маска - Строка.
//
// Возвращаемое значение:
// Массив - элементы типа Файл.
//
Функция НайтиФайлыВИерархииЛкс(Путь, Маска) Экспорт
НайденныеКаталоги = НайтиФайлы(Путь, "*.*");
МассивРезультатов = Новый Массив;
Для каждого НайденныйФайл Из НайденныеКаталоги Цикл
Если НайденныйФайл.ЭтоКаталог() Тогда
МассивРезультатов.Добавить(НайтиФайлыВИерархииЛкс(НайденныйФайл.ПолноеИмя, Маска));
КонецЕсли;
КонецЦикла;
МассивРезультатов.Добавить(НайтиФайлы(Путь, Маска));
Результат = Новый Массив;
Для Каждого ЭлементРезультат Из МассивРезультатов Цикл
Для Каждого Файл Из ЭлементРезультат Цикл
Результат.Добавить(Файл);
КонецЦикла;
КонецЦикла;
Возврат Результат;
КонецФункции
// Проверяет, является ли тип типом элемента формы.
//
// Параметры:
// пТип - Тип - проверяемый тип.
//
// Возвращаемое значение:
// Истина - тип элемента формы подтвержден;
// Ложь - тип элемента формы не подтвержден.
//
Функция ЛиТипЭлементаФормыЛкс(пТип) Экспорт
Если Ложь
ИЛИ пТип = Тип("Индикатор")
ИЛИ пТип = Тип("Кнопка")
ИЛИ пТип = Тип("КоманднаяПанель")
ИЛИ пТип = Тип("Надпись")
ИЛИ пТип = Тип("Панель")
ИЛИ пТип = Тип("Переключатель")
ИЛИ пТип = Тип("ПолеВвода")
ИЛИ пТип = Тип("ПолеВыбора")
ИЛИ пТип = Тип("ПолеСписка")
ИЛИ пТип = Тип("ПолеТекстовогоДокумента")
ИЛИ пТип = Тип("ПолеТабличногоДокумента")
ИЛИ пТип = Тип("ПолосаРегулирования")
ИЛИ пТип = Тип("ТабличноеПоле")
ИЛИ пТип = Тип("РамкаГруппы")
ИЛИ пТип = Тип("Флажок")
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиТипЭлементаФормыЛкс()
// Сообщает об ошибке в тексте запроса и устанавливает выделение на ошибочную строку, если это возможно.
//
// Параметры:
// *ПолеТекста - ПолеТекста, *Неопределено;
// *СтартоваяСтрока - Число, *0 - стартовое смещение строки;
// *СтартоваяКолонка - Число, *0 - стартовое смещение колонки;
// *ЯзыкПрограммы - Число, *0 - признак обработки ошибки при установке текста запроса;
// *ЛиМодально - Булево, *Ложь - модальный режим формы - будет использовано Предупреждение() вместо СообщитьЛкс().
// *ИнформацияОбОшибке - ИнформацияОбОшибке, *Неопределено;
// *ИмяМодуля - Строка, *Неопределено - имя модуля в котором произошла ошибка.
//
// Возвращаемое значение:
// Строка - истинное описание ошибки.
//
Функция ПоказатьОшибкуВТекстеПрограммыЛкс(Знач ПолеТекста = Неопределено,
СтартоваяСтрока = 0, СтартоваяКолонка = 0, ЯзыкПрограммы = 0, ЛиМодально = Ложь, ИнформацияОбОшибке = Неопределено,
ИмяМодуля = Неопределено, ПредставлениеКонтекста = "", ЭтаФорма = Неопределено) Экспорт
ПолеТекста = ОболочкаПоляТекстаЛкс(ПолеТекста);
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если ЭтаФорма <> Неопределено Тогда
// Баг платформы. Зависает приложение, если пытаемся установить выделение на невидимой странице.
ЭтаФорма.ТекущийЭлемент = ПолеТекста.ЭлементФормы;
КонецЕсли;
НомерСтроки = 0;
Если ИмяМодуля <> Неопределено Тогда
Вступление = Символы.Таб;
Иначе
Вступление = "";
КонецЕсли;
Если ИнформацияОбОшибке = Неопределено Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецЕсли;
ОписаниеОшибки = ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке);
ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(ОписаниеОшибки, Истина, ЛиМодально);
Если Истина
И ЯзыкПрограммы = 0
И ИмяМодуля <> Неопределено
И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля
Тогда
ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке);
Возврат ОписаниеОшибки;
КонецЕсли;
Если ЯзыкПрограммы = 2 Тогда
Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
Выражение = "";
Если Выражение = "" Тогда
Маркер = "Ошибка в выражении """;
Если Найти(НРег(ИнформацияОбОшибке.Описание), Нрег(Маркер)) = 1 Тогда
Выражение = Сред(ИнформацияОбОшибке.Описание, СтрДлина(Маркер) + 2, СтрДлина(ИнформацияОбОшибке.Описание) - СтрДлина(Маркер) - 3);
КонецЕсли;
КонецЕсли;
Если Выражение = "" Тогда
Маркер = "Поле не найдено """;
Если Найти(НРег(ИнформацияОбОшибке.Описание), Нрег(Маркер)) = 1 Тогда
МаркерНайден = Истина;
Выражение = Сред(ИнформацияОбОшибке.Описание, СтрДлина(Маркер) + 1, СтрДлина(ИнформацияОбОшибке.Описание) - СтрДлина(Маркер) - 1);
КонецЕсли;
КонецЕсли;
Если Выражение <> "" Тогда
ТекстПоля = ПолеТекста.ПолучитьТекст();
ПозицияВыражения = Найти(ТекстПоля, Выражение);
Если ПозицияВыражения > 0 Тогда
ПолеТекста.УстановитьГраницыВыделения(ПозицияВыражения, ПозицияВыражения + СтрДлина(Выражение));
Пустышка = 0;
НомерСтроки = 0;
ПолеТекста.ПолучитьГраницыВыделения(НомерСтроки, Пустышка, Пустышка, Пустышка);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И ИнформацияОбОшибке.Причина <> Неопределено
И ИнформацияОбОшибке.ИмяМодуля <> ""
И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля
Тогда
ФигурноеОписаниеОшибки = СтрокаМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "{", "}", Ложь);
Если Истина
И ФигурноеОписаниеОшибки <> Неопределено
//И ИнформацияОбОшибке.Причина.ИмяМодуля <> "" // В закомментированном виде в некоторых случаях неоправдано спускается до ошибки в запросе в модуле, а в раскомментированном ломает нахождение ошибки в строке алгоритма
Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЕсли;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 0
И ИнформацияОбОшибке.ИмяМодуля <> ""
И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля
Тогда
ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке);
Возврат ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке);
КонецЕсли;
МаксимальныйНомерСтроки = 100000;
Если ПолеТекста <> Неопределено Тогда
МаксимальныйНомерСтроки = ПолеТекста.КоличествоСтрок();
КонецЕсли;
ФигурноеОписаниеОшибки = СтрокаМеждуМаркерамиЛкс(ИнформацияОбОшибке.Описание, "{", "}", Ложь);
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если НомерСтроки = 0 Тогда
НомерСтроки = Мин(ИнформацияОбОшибке.НомерСтроки + СтартоваяСтрока, МаксимальныйНомерСтроки);
Если ИнформацияОбОшибке.ИсходнаяСтрока = "" Тогда
СтрокаКоординатыОшибки = СтрокаМеждуМаркерамиЛкс(ФигурноеОписаниеОшибки, "(", ")", Ложь);
Если СтрокаКоординатыОшибки <> Неопределено Тогда
НомерКолонки = 0;
МассивФрагментов = СтрРазделитьЛкс(СтрокаКоординатыОшибки, ",");
СтрокаНомерСтроки = МассивФрагментов[0];
Попытка
НомерСтроки = Число(СтрокаНомерСтроки);
Исключение
КонецПопытки;
НомерСтроки = Мин(НомерСтроки + СтартоваяСтрока, МаксимальныйНомерСтроки);
Если МассивФрагментов.Количество() > 1 Тогда
СтрокаНомерКолонки = МассивФрагментов[1];
Попытка
НомерКолонки = Число(СтрокаНомерКолонки);
Исключение
КонецПопытки;
НомерКолонки = НомерКолонки + СтартоваяКолонка;
КонецЕсли;
Если НомерСтроки = 0 Тогда
НомерКолонки = 1;
НомерСтроки = 1;
КонецЕсли;
ОписаниеОшибки = СтрЗаменить(ОписаниеОшибки, ФигурноеОписаниеОшибки, "(" + НомерСтроки + "," + НомерКолонки + ")");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 0
И НомерСтроки <= 0
Тогда
Если ЗначениеЗаполнено(ОписаниеОшибки) Тогда
ОписаниеОшибки = "Ошибка передачи переменной: " + ОписаниеОшибки;
Иначе
ОписаниеОшибки = "Ошибка без описания";
КонецЕсли;
Иначе
ОписаниеОшибки = "Строка кода " + НомерСтроки + ": " + ОписаниеОшибки;
КонецЕсли;
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке.Причина);
КонецЕсли;
ТекстСообщения = "";
Если ПолеТекста <> Неопределено Тогда
Если НомерСтроки > 0 Тогда
ПолеТекста.ПоказатьОшибку(НомерСтроки, НомерКолонки);
КонецЕсли;
ТекстСообщения = ТекстСообщения + ПредставлениеИзИдентификатораЛкс(ПолеТекста.ЭлементФормы.Имя) + ПредставлениеКонтекста;
ТекстСообщения = ТекстСообщения + ": " + ОписаниеОшибки;
ПолныйТекстСообщения = Вступление + ТекстСообщения;
СообщитьЛкс(ПолныйТекстСообщения, СтатусСообщения.Важное);
Иначе
ПолныйТекстСообщения = Вступление + ТекстСообщения;
СообщитьЛкс(ПолныйТекстСообщения, СтатусСообщения.Важное);
КонецЕсли;
Возврат ПолныйТекстСообщения;
КонецФункции
Функция ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(Знач ОписаниеОшибки, ЭтоПроизвольныйАлгоритм = Ложь, Знач ЛиМодально = Ложь) Экспорт
Результат = Ложь;
Если Истина
//И (Ложь
// Или Не ирКэш.ЛиПортативныйРежимЛкс()
// Или ирПортативный.ЛиСерверныйМодульДоступенЛкс())
И Найти(ОписаниеОшибки, "мутабельн") > 0
И Найти(ОписаниеОшибки, "Записать") > 0
Тогда
ТекстСообщения = "Чтобы избежать ошибки передачи мутабельного значения при записи объектов, используйте ";
Если ирКэш.ЛиПортативныйРежимЛкс() И Не ирПортативный.ЛиСерверныйМодульДоступенЛкс() Тогда
ТекстСообщения = ТекстСообщения + " вариант ""Расширение"" http://devtool1c.ucoz.ru/index/rasshirenie_variant/0-52";
Иначе
Если ЭтоПроизвольныйАлгоритм Тогда
ТекстСообщения = ТекстСообщения + "функцию ""ирОбщий.ЗаписатьОбъектЛкс(Объект, Истина)""";
Иначе
ТекстСообщения = ТекстСообщения + "опцию ""Запись на сервере"" инструмента";
КонецЕсли;
КонецЕсли;
СообщитьЛкс(ТекстСообщения, СтатусСообщения.Внимание);
Результат = Истина;
КонецЕсли;
Возврат Результат;
КонецФункции
// Рассчитывает и устанавливает ширину колонок табличного документа. Ориентирована на обработку
// результата построителя отчета.
//
// Параметры:
// ТабличныйДокумент - ТабличныйДокумент;
// *ЛиМинимальный - Булево, *Ложь - признак установки необходимой ширины, иначе достаточной;
// *ЛиИгнорироватьОбразание - Булево, *Ложь - признак игнорирования ячеек с обрезанием;
// *ШиринаОбластиПолей - Число, *0 - ширина области полей (не показателей);
// *РассчитыватьШиринуКолонкиПоНазванию - Булево, *Истина - признак расчета ширины колонки по названию;
// *МинимальнаяШиринаКолонкиПоказатель - Число, *10 - минимальная ширина колонки показателя;
// *ПорогКоличестваЯчеекДляАнализа - Число, *100000 - пороговое количество ячеек для анализа (усечение по высоте).
//
Процедура УстановитьАвтоширинуКолонокТабличногоДокументаЛкс(ТабличныйДокумент, ЛиМинимальный = Ложь,
ЛиИгнорироватьОбрезание = Ложь, ШиринаОбластиПолей = 0, РассчитыватьШиринуКолонкиПоНазванию = Ложь,
МинимальнаяШиринаКолонкиПоказатель = 10, ПорогКоличестваЯчеекДляАнализа = 10000) Экспорт
Перем МаксимальнаяШиринаКолонки;
Перем КонечнаяСтрока, НачальнаяСтрока, ТекущаяКолонка, ТекущаяСтрока, НачалоДанных;
Перем ОбластьШапки, ОбластьПодвала;
Перем ШиринаКолонки, ТекстЯчейки, НомерСтрокиТекста;
Перем КоличествоУровнейГруппировокСтрок, Отступ;
Перем ШириныКолонок;
СтрокаСостояния = "Расчет ширины колонок табличного документа ";
КоличествоОбновленийСостояния = 10;
// Ограничение максимальной ширины колонки
МаксимальнаяШиринаКолонки = 50;
// Массив, в который будут помещаться ширины колонок
ШириныКолонок = Новый Массив;
// Получим количество уровней группировок в отчете для учета автоматического отступа
КоличествоУровнейГруппировокСтрок = ТабличныйДокумент.КоличествоУровнейГруппировокСтрок();
// Инициализируем начальные строки
НачальнаяСтрока = 0;
НачалоДанных = 0;
// Найдем в результирующем документе область шапки таблицы
ОбластьШапки = ТабличныйДокумент.Области.Найти("ШапкаТаблицы");
Если ТипЗнч(ОбластьШапки) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда
// Из шапки таблицы получим начальную строку с которой будем рассчитывать ширины
НачальнаяСтрока = ОбластьШапки.Верх;
НачалоДанных = ОбластьШапки.Низ + 1;
Иначе
// Если область шапки таблицы не найдена, найдем область шапки строк
ОбластьШапки = ТабличныйДокумент.Области.Найти("ШапкаСтрок");
Если ТипЗнч(ОбластьШапки) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда
// Из шапки таблицы получим начальную строку с которой будем рассчитывать ширины
НачальнаяСтрока = ОбластьШапки.Верх;
НачалоДанных = ОбластьШапки.Низ + 1;
КонецЕсли;
КонецЕсли;
// Получим область подвала отчета и вычислим конечную строку расчета
ОбластьПодвала = ТабличныйДокумент.Области.Найти("Подвал");
Если ТипЗнч(ОбластьПодвала) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда
// Область подвала найдена
КонечнаяСтрока = ОбластьПодвала.Верх - 1;
Иначе
// Область подвала не найдена
КонечнаяСтрока = ТабличныйДокумент.ВысотаТаблицы;
КонецЕсли;
СтарыйПрогресс = 0;
КоличествоЯчеекПоказателейДляРасчета = (КонечнаяСтрока - НачальнаяСтрока) * (ТабличныйДокумент.ШиринаТаблицы - 1);
Если КоличествоЯчеекПоказателейДляРасчета > ПорогКоличестваЯчеекДляАнализа Тогда
КонечнаяСтрока = Мин(КонечнаяСтрока, ПорогКоличестваЯчеекДляАнализа / (ТабличныйДокумент.ШиринаТаблицы - 1));
КонецЕсли;
// Переберем все колонки отчета
Для ТекущаяКолонка = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
ПрогрессКолонок = ТекущаяКолонка / ТабличныйДокумент.ШиринаТаблицы / КонечнаяСтрока;
АвтоОтступ = 0;
// Переберем строки, которые будут использованы для расчета ширин колонок
Для ТекущаяСтрока = НачальнаяСтрока По КонечнаяСтрока Цикл
ОбработкаПрерыванияПользователя();
Прогресс = КоличествоОбновленийСостояния * ПрогрессКолонок * ТекущаяСтрока;
Если Прогресс - СтарыйПрогресс >= 1 Тогда
СтарыйПрогресс = Прогресс;
СостояниеЛкс(СтрокаСостояния + Цел(100 * ПрогрессКолонок * ТекущаяСтрока) + "%");
КонецЕсли;
ШиринаКолонки = 0;
// Получим область текущей ячейки
ОбластьЯчейки = ТабличныйДокумент.Область(ТекущаяСтрока, ТекущаяКолонка);
Если ОбластьЯчейки.Лево <> ТекущаяКолонка Или ОбластьЯчейки.Верх <> ТекущаяСтрока Тогда
// Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой
Продолжить;
КонецЕсли;
// Данная ячейка обрезает текст
Если Истина
И ЛиИгнорироватьОбрезание
И ОбластьЯчейки.РазмещениеТекста = ТипРазмещенияТекстаТабличногоДокумента.Обрезать
Тогда
Продолжить;
КонецЕсли;
Если КоличествоУровнейГруппировокСтрок > 0 И ТекущаяСтрока = НачалоДанных Тогда
// Для первой строки с данными получим значение автоотступа
АвтоОтступ = ОбластьЯчейки.АвтоОтступ;
КонецЕсли;
// Получим текст ячейки
ТекстЯчейки = ОбластьЯчейки.Текст;
КоличествоСтрокВТекстеЯчейки = СтрЧислоСтрок(ТекстЯчейки);
ТекстЯчейкиТД = Новый ТекстовыйДокумент;
ТекстЯчейкиТД.УстановитьТекст(ТекстЯчейки);
// Для каждой строки из текста ячейки рассчитаем количество символов в строке
Для НомерСтрокиТекста = 1 По КоличествоСтрокВТекстеЯчейки Цикл
ШиринаТекстаЯчейки = СтрДлина(ТекстЯчейкиТД.ПолучитьСтроку(НомерСтрокиТекста));
Если Истина
И НЕ РассчитыватьШиринуКолонкиПоНазванию
И ТекущаяСтрока < НачалоДанных
И ШиринаТекстаЯчейки > 0
Тогда
ШиринаТекстаЯчейки = МинимальнаяШиринаКолонкиПоказатель;
КонецЕсли;
// Если используется автоотступ, то прибавим к ширине ячейки его величину
Если АвтоОтступ <> Неопределено И АвтоОтступ > 0 Тогда
ШиринаТекстаЯчейки = ШиринаТекстаЯчейки + КоличествоУровнейГруппировокСтрок * АвтоОтступ;
КонецЕсли;
ШиринаКолонки = Макс(ШиринаКолонки, ШиринаТекстаЯчейки);
КонецЦикла;
Если ШиринаКолонки > МаксимальнаяШиринаКолонки Тогда
// Ограничим ширину колонки
ШиринаКолонки = МаксимальнаяШиринаКолонки;
КонецЕсли;
Если ШиринаКолонки <> 0 Тогда
// Ширина колонки рассчитана
// Определим, сколько ячеек по ширине используется в области для текущей ячейки
КоличествоКолонок = ОбластьЯчейки.Право - ОбластьЯчейки.Лево;
// Переберем все ячейки, расположенные в области
Для НомерКолонки = 0 По КоличествоКолонок Цикл
Если ШириныКолонок.ВГраница() >= ТекущаяКолонка - 1 + НомерКолонки Тогда
// В массиве ширин колонок уже был элемент для текущей колонки
Если ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = Неопределено Тогда
// Значение ширины колонки еще не было установлено
ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = ШиринаКолонки / (КоличествоКолонок + 1);
Иначе
// Значение ширины колонки уже было установлено
// Вычислим максимум ширины колонки
ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] =
Макс(ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки], ШиринаКолонки / (КоличествоКолонок + 1));
КонецЕсли;
Иначе
// В массиве ширин колонок еще не было элемента для данной колонки
// Добавим элемент в массив ширин колонок
ШириныКолонок.Вставить(ТекущаяКолонка - 1 + НомерКолонки, ШиринаКолонки / (КоличествоКолонок + 1));
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла; // Конец цикла перебора строк
КонецЦикла; // Конец цикла перебора колонок
// Переберем все элементы в массиве вычисленных ширин колонок
Для ТекущаяКолонка = 0 По ШириныКолонок.ВГраница() Цикл
Если ШиринаОбластиПолей >= ТекущаяКолонка Тогда
УстановитьМинимальнуюШирину = Ложь;
Иначе
УстановитьМинимальнуюШирину = ЛиМинимальный;
КонецЕсли;
Если ШириныКолонок[ТекущаяКолонка] <> Неопределено Тогда
ОбластьКолонки = ТабличныйДокумент.Область(, ТекущаяКолонка + 1, НачалоДанных, ТекущаяКолонка + 1);
// Ширина колонок установлена
// Установим ширину области ячеек
Если УстановитьМинимальнуюШирину Тогда
ОбластьКолонки.ШиринаКолонки = Макс(ШириныКолонок[ТекущаяКолонка] + 1, МинимальнаяШиринаКолонкиПоказатель);
Иначе
ОбластьКолонки.ШиринаКолонки = ШириныКолонок[ТекущаяКолонка] + 1;
КонецЕсли;
КонецЕсли;
КонецЦикла;
СостояниеЛкс("");
КонецПроцедуры // УстановитьАвтоширинуКолонокТабличногоДокументаЛкс()
// Устанавливает отбор построителя по расшифровке, содержащей NULL'ы.
// Устанавливает значение каждого NULL элемента отбора в "<Отсутствует>" и вид сравнения в "Равно".
// Для измерений, которые могут содержать значение "NULL" в запросах в секции условий построителя следует
// писать "ЕСТЬNULL(ПутьКДаннымИзмерения, "<Отсутствует>") КАК ИмяИзмерения".
//
// Параметры:
// пПостроительОтчета - ПостроительОтчета - чей отбор обрабатываем;
// пРасшифровка - Структура - расшифровка.
//
Процедура УстановитьОтборПостроителяПриРасшифровкеЛкс(пПостроительОтчета, пРасшифровка) Экспорт
Для каждого ЭлементРасшифровки Из пРасшифровка Цикл
Если ЭлементРасшифровки.Значение = NULL Тогда
ЭлементОтбора = пПостроительОтчета.Отбор[ЭлементРасшифровки.Ключ];
Если ЭлементОтбора.ТипЗначения.СодержитТип(Тип("Строка")) Тогда
ЭлементОтбора.Значение = "<Отсутствует>";
Если ЭлементОтбора.ВидСравнения = ВидСравнения.ВИерархии Тогда
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
КонецЕсли;
Иначе
СообщитьЛкс(СтрШаблонИменЛкс("Запрос не поддерживает расшифровку по отсутствующему значению элемента отбора %1!",, ЭлементОтбора.Представление));
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // УстановитьОтборПостроителяПриРасшифровкеЛкс()
// Получает копию построителя отчетов.
//
// Параметры:
// Оригинал - ПостроительОтчета.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция _СкопироватьПостроительОтчетаЛкс(Оригинал, ВосстанавливатьНастройки = Истина) Экспорт
Копия = Новый ПостроительОтчета;
Для Каждого ДоступноеПоле Из Оригинал.ДоступныеПоля Цикл
ЗаполнитьЗначенияСвойств(Копия.ДоступныеПоля.Добавить(ДоступноеПоле.Имя, ДоступноеПоле.Представление), ДоступноеПоле);
КонецЦикла;
Если ВосстанавливатьНастройки Тогда
Копия.Текст = Оригинал.Текст;
Копия.ЗаполнитьНастройки(); // Баг платформы. Без этого почему то иногда измерения не восстанавливаются!
Копия.УстановитьНастройки(Оригинал.ПолучитьНастройки());
КонецЕсли;
Возврат Копия;
КонецФункции
// Возвращает менеджер временных таблиц, в котором создана временная таблица по переданному источнику.
//
// Параметры:
// ТаблицаЗначений - ТаблицаЗначений;
// ИмяТаблицы - Строка;
// *МенеджерВременныхТаблиц - МенеджерВременныхТаблиц, *Неопределено.
//
// Возвращаемое значение:
// МенеджерВременныхТаблиц.
//
Функция _МенеджерВременныхТаблицИзТаблицыЛкс(ТаблицаЗначений, ИмяТаблицы, МенеджерВременныхТаблиц = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
Если МенеджерВременныхТаблиц = Неопределено Тогда
МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
КонецЕсли;
ТекстВЫБРАТЬ = "";
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
ТекстВЫБРАТЬ = ТекстВЫБРАТЬ + ", " + Колонка.Имя;
КонецЦикла;
ТекстЗапроса = "ВЫБРАТЬ " + Сред(ТекстВЫБРАТЬ, 3);
ТекстЗапроса = ТекстЗапроса + " ПОМЕСТИТЬ " + ИмяТаблицы;
ТекстЗапроса = ТекстЗапроса + " ИЗ &ВнешнийИсточник КАК ВнешнийИсточник";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.УстановитьПараметр("ВнешнийИсточник", ТаблицаЗначений);
Запрос.Выполнить();
Возврат МенеджерВременныхТаблиц;
КонецФункции
Процедура ПанельИнструментовОПодсистемеЛкс() Экспорт
ОткрытьСправкуПоПодсистемеЛкс();
КонецПроцедуры
// Открывает обработку ирПоискДублейИЗаменаСсылок и заполняет группы дублей по табличному полю, связанному с таблицей или деревом значений.
//
Процедура ОткрытьФормуЗаменыСсылокИзТабличногоПоляЛкс(ТабличноеПоле) Экспорт
Если ТабличноеПоле.ТекущаяКолонка = Неопределено Тогда
Возврат;
КонецЕсли;
ФормаОбработки = ПолучитьФормуЛкс("Обработка.ирПоискДублейИЗаменаСсылок.Форма");
Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений") Тогда
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
СписокВыбора = Новый СписокЗначений;
СписокВыбора.Добавить(0, "Создать группы дублей из пар неправильных значений текущей и правильных значений следующей колонок");
СписокВыбора.Добавить(1, "Создать одну группу дублей из значений текущей колонки выделенных строк");
//СписокВыбора.Добавить(2, "Создать правила замены значений из текущей колонки на значения следующей колонки");
ВыбранныйВариант = СписокВыбора.ВыбратьЭлемент("Выберите вариант");
Если ВыбранныйВариант = Неопределено Тогда
Возврат;
КонецЕсли;
Если ВыбранныйВариант.Значение = 1 Тогда
Если ВыделенныеСтроки.Количество() = 0 Тогда
Возврат ;
КонецЕсли;
ИмяКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Возврат;
КонецЕсли;
МассивСсылок = Новый Массив;
Для Каждого Строка Из ВыделенныеСтроки Цикл
ЗначениеСтроки = Строка[ИмяКолонки];
ТипЗначения = ТипЗнч(ЗначениеСтроки);
Если Метаданные.НайтиПоТипу(ТипЗначения) = Неопределено Тогда
Продолжить;
КонецЕсли;
МассивСсылок.Добавить(ЗначениеСтроки);
КонецЦикла;
ФормаОбработки.ОткрытьДляЗаменыПоСпискуСсылок(МассивСсылок,, 0);
ИначеЕсли ВыбранныйВариант.Значение = 0 Тогда
ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка;
Если Ложь
Или ТекущаяКолонка = Неопределено
Или ТекущаяКолонка.Данные = ""
Тогда
Возврат;
КонецЕсли;
ИндексКолонки = ТабличноеПоле.Колонки.Индекс(ТекущаяКолонка);
Если ТабличноеПоле.Колонки.Количество() = ИндексКолонки + 1 Тогда
Возврат;
КонецЕсли;
СледующаяКолонка = ТабличноеПоле.Колонки[ИндексКолонки + 1];
Если СледующаяКолонка.Данные = "" Тогда
Возврат;
КонецЕсли;
ФормаОбработки.ОткрытьСЗаполнениемГруппДублейПоТаблицеПар(ТабличноеПоле.Значение, ТекущаяКолонка.Данные, СледующаяКолонка.Данные);
КонецЕсли;
ИначеЕсли ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда
ФормаОбработки.ОткрытьДляЗаменыПоДеревуСсылок(ТабличноеПоле.Значение, ТабличноеПоле.ТекущаяКолонка.Имя);
КонецЕсли;
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// ТЕХНОЛОГИЯ КОМПОНЕНТ
// Возвращает кнопку командной панели компоненты по ее имени из макета.
//
// Параметры:
// ОбъектКомпоненты - ОбработкаОбъект - компонента;
// КраткоеИмяКнопки - Строка - имя кнопки из макета компоненты;
// *КоманднаяПанель - КоманднаяПанель, *Неопределено - на случай, если у компоненты несколько командных панелей.
//
// Возвращаемое значение:
// Кнопка.
//
Функция КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ОбъектКомпоненты, КраткоеИмяКнопки,
Знач КоманднаяПанель = Неопределено) Экспорт
Если КоманднаяПанель = Неопределено Тогда
КоманднаяПанель = ОбъектКомпоненты.КоманднаяПанель;
КонецЕсли;
Если КоманднаяПанель = Неопределено Тогда
// Был вызван деструктор
Возврат Неопределено;
КонецЕсли;
ПолноеИмяКнопки = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КраткоеИмяКнопки);
Кнопка = КоманднаяПанель.Кнопки.Найти(ПолноеИмяКнопки);
Если Кнопка = Неопределено Тогда
Для Каждого Подменю Из КоманднаяПанель.Кнопки Цикл
Если Подменю.ТипКнопки <> ТипКнопкиКоманднойПанели.Подменю Тогда
Продолжить;
КонецЕсли;
Кнопка = КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ОбъектКомпоненты, КраткоеИмяКнопки, Подменю);
Если Кнопка <> Неопределено Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Кнопка;
КонецФункции
// Формирует имя элемента управления экземпляра компоненты.
//
// Параметры:
// ИмяКласса - Строка;
// ИмяЭкземпляра - Строка;
// КраткоеИмяЭлементаУправления - Строка.
//
// Возвращаемое значение:
// Строка - имя.
//
Функция СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КраткоеИмяЭлементаУправления) Экспорт
Возврат ПрефиксИменЭлементовЭкземпляраКомпонентыЛкс(ОбъектКомпоненты) + КраткоеИмяЭлементаУправления;
КонецФункции
Функция ПрефиксИменЭлементовЭкземпляраКомпонентыЛкс(ОбъектКомпоненты) Экспорт
Возврат ОбъектКомпоненты.ИмяКласса + "_" + ОбъектКомпоненты.Имя + "_";
КонецФункции // СформироватьИмяЭлементаУправленияЭкземпляраЛкс()
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция НоваяТаблицуСобытийЭлементаУправленияКомпонентыЛкс() Экспорт
ТаблицаСобытий = Новый ТаблицаЗначений;
ТаблицаСобытий.Колонки.Добавить("СобытиеОбъекта");
ТаблицаСобытий.Колонки.Добавить("БлижайшийВидАлгоритма");
ТаблицаСобытий.Колонки.Добавить("ИмяСобытия");
ТаблицаСобытий.Колонки.Добавить("Компонента");
ТаблицаСобытий.Колонки.Добавить("ВызовОбработчика");
Возврат ТаблицаСобытий;
КонецФункции
// Добавляет в кнопки командной панели приемника коллекцию кнопок командной панели источника.
//
// Параметры:
// ОбъектКомпоненты - ОбработкаОбъект - компонента;
// КнопкиМакета - КоллекцияКнопокКоманднойПанели - источник;
// КнопкиПриемника - КоллекцияКнопокКоманднойПанели - приемник;
// *ДействияКнопокКомпонент - ТаблицаЗначений, *Неопределено;
//
Процедура ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ОбъектКомпоненты, КнопкиМакета, КнопкаПриемника,
ДействияКнопокКомпонент = Неопределено, ОбщийПриемник = Неопределено, НеДобавлятьЕслиСуществует = Ложь) Экспорт
КнопкиПриемника = КнопкаПриемника.Кнопки;
ИмяКласса = ОбъектКомпоненты.ИмяКласса;
Если ДействияКнопокКомпонент = Неопределено Тогда
ДействиеТранслятор = Новый Действие("Клс" + ИмяКласса + "Нажатие");
Иначе
ЭтоКоманднаяПанель = (ТипЗнч(КнопкаПриемника) = Тип("КоманднаяПанель"));
ДопКнопкиКомандныхПанелей = ОбъектКомпоненты.ДопКнопкиКомандныхПанелей;
ДопКнопкиКоманднойПанели = Новый Массив;
ДопКнопкиКомандныхПанелей.Вставить(КнопкаПриемника.Имя, ДопКнопкиКоманднойПанели);
ДействиеТранслятор = Новый Действие("КнопкаКоманднойПанели_Действие")
КонецЕсли;
ИмяЭкземпляра = ОбъектКомпоненты.Имя;
Для Каждого КнопкаМакета Из КнопкиМакета Цикл
Кнопка = Неопределено;
Если КнопкаМакета.ТипКнопки = ТипКнопкиКоманднойПанели.Действие Тогда
Если Истина
И Строка(КнопкаМакета.Действие) = ""
Тогда
ИмяКнопки = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КнопкаМакета.Имя);
Если НеДобавлятьЕслиСуществует И КнопкиПриемника.Найти(ИмяКнопки) <> Неопределено Тогда
Продолжить;
КонецЕсли;
// Это пустое действие
Кнопка = КнопкиПриемника.Добавить(, КнопкаМакета.ТипКнопки);
ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Действие, Имя");
Кнопка.Имя = ИмяКнопки;
//Попытка
Кнопка.Действие = ДействиеТранслятор;
//Исключение
// ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
// Возврат;
//КонецПопытки;
Если ДействияКнопокКомпонент <> Неопределено Тогда
СтрокаДействия = ДействияКнопокКомпонент.Добавить();
СтрокаДействия.Кнопка = Кнопка;
СтрокаДействия.Компонента = ОбъектКомпоненты;
ВызовОбработчика = "Действие_";
Если ОбщийПриемник = Неопределено Тогда
ВызовОбработчика = ВызовОбработчика + КнопкаМакета.Имя;
Иначе
ВызовОбработчика = ВызовОбработчика + ОбщийПриемник;
КонецЕсли;
СтрокаДействия.ВызовОбработчика = ВызовОбработчика + "(П0, П1)";
КонецЕсли;
Иначе
Кнопка = КнопкиПриемника.Добавить(КнопкаМакета.Имя, КнопкаМакета.ТипКнопки, , КнопкаМакета.Действие);
// Автокартинки предопределенных действий платформа подключает до вызова ПередОткрытием, а потом они уже пустые
Если КнопкаМакета.Картинка.Вид <> ВидКартинки.Пустая Тогда
Кнопка.Картинка = КнопкаМакета.Картинка;
КонецЕсли;
ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Имя, ТипКнопки, Картинка");
КонецЕсли;
КонецЕсли;
Если Кнопка = Неопределено Тогда
Кнопка = КнопкиПриемника.Добавить();
ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Действие, Имя");
Кнопка.Имя = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КнопкаМакета.Имя);
Если КнопкаМакета.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда
ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ОбъектКомпоненты, КнопкаМакета.Кнопки, Кнопка, ДействияКнопокКомпонент, ОбщийПриемник);
КонецЕсли;
КонецЕсли;
Если Истина
И ДействияКнопокКомпонент <> Неопределено
И ЭтоКоманднаяПанель
Тогда
ДопКнопкиКоманднойПанели.Добавить(Кнопка.Имя);
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс()
// Возвращает имя экземпляра компоненты, которой принадлежит элемент управления.
//
// Параметры:
// ЭлементУправления - ЭлементУправления.
//
// Возвращаемое значение:
// Строка - имя.
//
Функция ИмяЭкземпляраКомпонентыЛкс(ЭлементУправления) Экспорт
Результат = СтрРазделитьЛкс(ЭлементУправления.Имя, "_")[1];
Возврат Результат;
КонецФункции
// Устанавливает свойство у элементов коллекции.
//
// Параметры:
// Коллекция - Любая индексированная коллекция;
// МассивИлиСтрока - Массив (индексов), Строка (имена элементов, разделенные запятыми), *Неопределено - фильтр;
// Свойство - Строка - имя Свойства которое нужно установить; если обращение к свойству черех [] недоступно, то нужно указать "-" в начале имени свойства
// ЗначениеСвойства - Произвольный.
//
Процедура УстановитьСвойствоВКоллекцииЛкс(Коллекция, Свойство, ЗначениеСвойства = Неопределено, ИменаЭлементов = Неопределено) Экспорт
ДоступенИндексСвойств = Лев(Свойство, 1) <> "-";
Если ИменаЭлементов <> Неопределено Тогда
Если ТипЗнч(ИменаЭлементов) = Тип("Строка") Тогда
МассивИндексов = СтрРазделитьЛкс(ИменаЭлементов, ",", Истина);
Иначе
МассивИндексов = ИменаЭлементов;
КонецЕсли;
Для Каждого ИмяЭлемента Из МассивИндексов Цикл
ЭлементКоллекции = Коллекция[ИмяЭлемента];
Если ДоступенИндексСвойств Тогда
ЭлементКоллекции[Свойство] = ЗначениеСвойства;
Иначе
Выполнить("ЭлементКоллекции." + Сред(Свойство, 2) + " = ЗначениеСвойства");
КонецЕсли;
КонецЦикла;
Иначе
Для Каждого ЭлементКоллекции Из Коллекция Цикл
Если ДоступенИндексСвойств Тогда
ЭлементКоллекции[Свойство] = ЗначениеСвойства;
Иначе
Выполнить("ЭлементКоллекции." + Сред(Свойство, 2) + " = ЗначениеСвойства");
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция ОтобратьЭлементыКоллекцииЛкс(Коллекция, СтруктураОтбора = Неопределено) Экспорт
Результат = Новый Массив;
СтрокаСвойств = "";
Для Каждого ЭлементКоллекции Из Коллекция Цикл
Если СтруктураОтбора = Неопределено Или СравнитьЗначенияСвойствЛкс(ЭлементКоллекции, СтруктураОтбора, СтрокаСвойств) Тогда
Результат.Добавить(ЭлементКоллекции);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура ТабличноеПолеКолонокПриВыводеСтрокиЛкс(Знач ОформлениеСтроки, Знач ДанныеСтроки, Знач ИмяКолонкиОписанияТипов = "ТипЗначения") Экспорт
ИндексКартинки = ИндексКартинкиТипаЗначенияБДЛкс(ДанныеСтроки[ИмяКолонкиОписанияТипов]);
Если ИндексКартинки <> Неопределено Тогда
ОформлениеСтроки.Ячейки[ИмяКолонкиОписанияТипов].ОтображатьКартинку = Истина;
ОформлениеСтроки.Ячейки[ИмяКолонкиОписанияТипов].ИндексКартинки = ИндексКартинки;
КонецЕсли;
КонецПроцедуры
// Глобальный обработчик события ПриПолученииДанных для табличных полей доступных полей компоновки.
//
// Параметры:
// ОформленияСтрок - ОформленияСтрок.
//
Процедура ПриПолученииДанныхДоступныхПолейКомпоновкиЛкс(ЭтаФорма, Элемент, ОформленияСтрок, ТабличноеПолеВыбранныхПолей = Неопределено) Экспорт
//СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
//ОбработчикиПриВыводеСтроки = СлужебныеДанныеФормы.ОбработчикиПриВыводеСтроки;
//ОбработчикПриВыводеСтроки = ОбработчикиПриВыводеСтроки[Элемент.Имя];
//Если Истина
// И ОбработчикПриВыводеСтроки <> Неопределено
// И Не МетодРеализованЛкс(ЭтаФорма, ОбработчикПриВыводеСтроки) // Сообщение о его отсутствии выдаем в общем обработчике Форма_ПриОткрытии
//Тогда
// ОбработчикПриВыводеСтроки = Неопределено;
//КонецЕсли;
Если Истина
И ТабличноеПолеВыбранныхПолей <> Неопределено
И ОформленияСтрок[0].Ячейки.Найти("Использовано") <> Неопределено
Тогда
ВсеПоляВыбранныхПолей = ирОбщий.ВсеВыбранныеПоляГруппировкиКомпоновкиЛкс(ТабличноеПолеВыбранныхПолей.Значение,,, Истина);
КонецЕсли;
КартинкаРеквизита = ирКэш.КартинкаПоИмениЛкс("ирРеквизит");
Для каждого ОформлениеСтроки Из ОформленияСтрок Цикл
ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
Если ДанныеСтроки = Неопределено Тогда
Продолжить;
КонецЕсли;
Ячейки = ОформлениеСтроки.Ячейки;
ЯчейкаТипа = Ячейки.Найти("Тип");
Если ЯчейкаТипа <> Неопределено Тогда
Ячейки.Тип.УстановитьТекст(ДанныеСтроки.ТипЗначения);
КонецЕсли;
ИндексКартинки = Неопределено;
Попытка
ЭтоПапка = ДанныеСтроки.Папка;
ЭтоРесурс = ДанныеСтроки.Ресурс;
Исключение
ЭтоПапка = Ложь;
ЭтоРесурс = Ложь;
КонецПопытки;
Если ЭтоПапка Тогда
ПапкаСРесурсами = ДанныеСтроки.Элементы.Количество() > 0;
Для каждого ДоступноеПоле Из ДанныеСтроки.Элементы Цикл
Если Не ДоступноеПоле.Ресурс Тогда
ПапкаСРесурсами = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПапкаСРесурсами Тогда
ИндексКартинки = 17;
КонецЕсли;
КонецЕсли;
Если Не ЭтоРесурс И Не ЭтоПапка Тогда
ИндексКартинки = ИндексКартинкиТипаЗначенияБДЛкс(ДанныеСтроки.ТипЗначения);
КонецЕсли;
Если ИндексКартинки <> Неопределено Тогда
Ячейки[0].ОтображатьКартинку = Истина;
Ячейки[0].ИндексКартинки = ИндексКартинки;
КонецЕсли;
Если Истина
И ВсеПоляВыбранныхПолей <> Неопределено
И ВсеПоляВыбранныхПолей.Найти(ДанныеСтроки.Поле) <> Неопределено
Тогда
Ячейки.Использовано.УстановитьКартинку(КартинкаРеквизита);
КонецЕсли;
Если Ячейки.Найти("Заголовок") <> Неопределено Тогда
Типы = ДанныеСтроки.ТипЗначения.Типы();
Если Типы.Количество() > 1 Тогда
Ячейки.Заголовок.УстановитьТекст(Ячейки.Заголовок.Текст + " (" + XMLСтрока(Типы.Количество()) + "т)");
КонецЕсли;
КонецЕсли;
//Если ОбработчикПриВыводеСтроки = Неопределено Тогда
ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки);
//Иначе
// Выполнить("ЭтаФорма." + ОбработчикПриВыводеСтроки + "(Элемент, ОформлениеСтроки, ДанныеСтроки);");
//КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ОформитьСтрокуДоступногоПоляЛкс(ОформлениеСтроки, СтрокаПоля, Знач СтрокаДоступнойТаблицы = Неопределено, ИмяКолонки = "Заголовок", Знач ЭтоИндекс = Ложь, Использовано = Ложь) Экспорт
Ячейки = ОформлениеСтроки.Ячейки;
ЭтоСистемное = Истина
И СтрокаПоля <> Неопределено
И СтрокаПоля.Метаданные = Неопределено
И Не СтрокаПоля.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений"))
И (Ложь
Или СтрокаДоступнойТаблицы = Неопределено
Или (Истина
И СтрокаДоступнойТаблицы.Тип <> "ДвиженияССубконто"
И СтрокаДоступнойТаблицы.Тип <> "ВиртуальнаяТаблица"
И СтрокаДоступнойТаблицы.Тип <> "ВременнаяТаблица"
И СтрокаДоступнойТаблицы.Тип <> "Параметр"
И СтрокаДоступнойТаблицы.Тип <> "Константы"));
ТекстВСкобках = "";
ЭтоИзмерение = Найти(ПолноеИмяМДПоляТаблицыЛкс(СтрокаПоля), ".Измерение.") > 0;
Если Истина
И СтрокаПоля <> Неопределено
И ИмяКолонки <> "Заголовок"
Тогда
Типы = СтрокаПоля.ТипЗначения.Типы();
Если Типы.Количество() > 1 Тогда
ТекстВСкобках = ТекстВСкобках + "," + XMLСтрока(Типы.Количество()) + "т";
КонецЕсли;
КонецЕсли;
Если ЭтоИзмерение Тогда
ТекстВСкобках = ТекстВСкобках + ",Измер";
ОформлениеСтроки.ЦветФона = Новый Цвет(255, 245, 240);
КонецЕсли;
Если ЭтоСистемное Тогда
ТекстВСкобках = ТекстВСкобках + ",Систем";
//ОформлениеСтроки.ЦветФона = Новый Цвет(250, 250, 255);
КонецЕсли;
Если ЭтоИндекс Тогда
ТекстВСкобках = ТекстВСкобках + ",Индекс";
КонецЕсли;
Если ЗначениеЗаполнено(ТекстВСкобках) Тогда
ТекстВСкобках = " (" + Сред(ТекстВСкобках, 2) + ")";
Ячейки[ИмяКолонки].УстановитьТекст(Ячейки[ИмяКолонки].Текст + ТекстВСкобках);
КонецЕсли;
Если Использовано И Ячейки.Найти("Использовано") <> Неопределено Тогда
Ячейки.Использовано.УстановитьКартинку(ирКэш.КартинкаПоИмениЛкс("ирРеквизит"));
КонецЕсли;
КонецПроцедуры
Процедура УсловноеОформлениеПриВыводеСтрокиЛкс(Знач ЭтаФорма, Знач Элемент, Знач ОформлениеСтроки, Знач ДанныеСтроки, Знач КомпоновщикНастроек = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ДанныеСтроки = Новый НастройкиКомпоновкиДанных;
ДанныеСтроки = ДанныеСтроки.УсловноеОформление.Элементы[0];
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
#КонецЕсли
ирОбщий.ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки);
МассивОформляемыхКолонок = Новый Массив;
//МассивОформляемыхКолонок.Добавить("ОформлениеДляКраткогоОтображенияЭлемента");
//МассивОформляемыхКолонок.Добавить("ПредставлениеДляКраткогоОтображенияЭлемента");
//МассивОформляемыхКолонок.Добавить("ОформлениеДляПодробногоОтображенияЭлемента");
//МассивОформляемыхКолонок.Добавить("ПредставлениеДляПодробногоОтображенияЭлемента");
МассивОформляемыхКолонок.Добавить("Пример");
//МассивТекстовыхКолонок = Новый Массив;
//МассивТекстовыхКолонок.Добавить("ОформлениеДляПодробногоОтображенияЭлемента");
//МассивТекстовыхКолонок.Добавить("ОформлениеДляКраткогоОтображенияЭлемента");
ИменаКолонокОбласти = Новый Массив;
ИменаКолонокОбласти.Добавить("ОбластиДляКраткогоОтображенияЭлемента");
ИменаКолонокОбласти.Добавить("ОбластиДляПодробногоОтображенияЭлемента");
ИменаКолонокОтбора = Новый Массив;
ИменаКолонокОтбора.Добавить("ОтборДляКраткогоОтображенияЭлемента");
ИменаКолонокОтбора.Добавить("ОтборДляПодробногоОтображенияЭлемента");
ПараметрФормат = Новый ПараметрКомпоновкиДанных("Format");
ПараметрТекст = Новый ПараметрКомпоновкиДанных("Text");
//Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
// ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
//: ДанныеСтроки = Новый ("ЭлементУсловногоОформленияКомпоновкиДанных")
Ячейки = ОформлениеСтроки.Ячейки;
ЯчейкаОформления = Ячейки.Пример;
//Для Каждого ИмяКолонки Из МассивТекстовыхКолонок Цикл
// ЯчейкаТекста = Ячейки[ИмяКолонки];
// Если ЯчейкаТекста.Видимость Тогда
// Прервать;
// КонецЕсли;
//КонецЦикла;
Для Каждого ИмяКолонки Из ИменаКолонокОбласти Цикл
ЯчейкаОбласти = Ячейки[ИмяКолонки];
Если ЯчейкаОбласти.Видимость Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Для Каждого ИмяКолонки Из ИменаКолонокОтбора Цикл
ЯчейкаОтбор = Ячейки[ИмяКолонки];
Если ЯчейкаОтбор.Видимость Тогда
Прервать;
КонецЕсли;
КонецЦикла;
ЗначенияПараметров = ДанныеСтроки.Оформление.Элементы;
ПредставлениеЗначенийПараметра = "";
Для Каждого ЗначениеПараметра Из ЗначенияПараметров Цикл
Если НЕ ЗначениеПараметра.Использование Тогда
Продолжить;
КонецЕсли;
Если ЗначениеПараметра.Параметр = ПараметрФормат Тогда
ИначеЕсли ЗначениеПараметра.Параметр = ПараметрТекст Тогда
Иначе
Попытка
Выполнить("ЯчейкаОформления." + ЗначениеПараметра.Параметр + " = ЗначениеПараметра.Значение;");
Исключение
КонецПопытки;
КонецЕсли;
Если ПредставлениеЗначенийПараметра <> "" Тогда
ПредставлениеЗначенийПараметра = ПредставлениеЗначенийПараметра + ", ";
КонецЕсли;
ПредставлениеЗначенийПараметра = ПредставлениеЗначенийПараметра + ЗначениеПараметра.Параметр + "=" + ЗначениеПараметра.Значение;
КонецЦикла;
//Выполнить("ЯчейкаТекста.УстановитьТекст(ПредставлениеЗначенийПараметра);");
ЯчейкаОформления.УстановитьТекст("Пример");
// Антибаг платформы 8.2.13. Если область элемента оформления содержит включенные пустые поля, то представление области выглядит пустым,
// а элемент оформления не будет применяться даже если он включен. Поэтому нужно отобразить такие пустые поля
Если Истина
И ЯчейкаОбласти.Видимость
//И "" + ДанныеСтроки.Поля = ""
И ЯчейкаОбласти.Текст = ""
И ДанныеСтроки.Поля.Элементы.Количество() > 0
Тогда
Для Каждого Поле Из ДанныеСтроки.Поля.Элементы Цикл
Если Поле.Использование Тогда
ЯчейкаОбласти.УстановитьТекст("<>");
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если КомпоновщикНастроек <> Неопределено Тогда
Для Каждого Поле Из ДанныеСтроки.Поля.Элементы Цикл
Если Истина
И ЗначениеЗаполнено("" + Поле.Поле)
И КомпоновщикНастроек.Настройки.ДоступныеПоляВыбора.НайтиПоле(Поле.Поле) = Неопределено
Тогда
ЯчейкаОбласти.УстановитьКартинку(ирКэш.КартинкаПоИмениЛкс("ирНедоступноеПоле"));
Прервать;
КонецЕсли;
КонецЦикла;
Если ЛиЕстьНеактуальныеПоляВГруппеОтбораЛкс(КомпоновщикНастроек, ДанныеСтроки.Отбор) Тогда
ЯчейкаОтбор.УстановитьКартинку(ирКэш.КартинкаПоИмениЛкс("ирНедоступноеПоле"));
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ЛиЕстьНеактуальныеПоляВГруппеОтбораЛкс(Знач КомпоновщикНастроек, Знач ГруппаОтбора) Экспорт
#Если Сервер И Не Сервер Тогда
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
ГруппаОтбора = КомпоновщикНастроек.Настройки.Отбор;
#КонецЕсли
Результат = Ложь;
Для Каждого ЭлементОтбора Из ГруппаОтбора.Элементы Цикл
Если ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
Результат = ЛиЕстьНеактуальныеПоляВГруппеОтбораЛкс(КомпоновщикНастроек, ЭлементОтбора);
Иначе
Результат = КомпоновщикНастроек.Настройки.ДоступныеПоляВыбора.НайтиПоле(ЭлементОтбора.ЛевоеЗначение) = Неопределено;
КонецЕсли;
Если Результат Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура ОформитьЯчейкуРазностиЛкс(Знач ОформлениеСтроки, Знач ИмяКолонки = "Разность") Экспорт
РазностьОбъекта = ОформлениеСтроки.ДанныеСтроки[ИмяКолонки];
Если ТипЗнч(РазностьОбъекта) = Тип("Число") Тогда
ЦветТекста = Новый Цвет;
Ячейка = ОформлениеСтроки.Ячейки[ИмяКолонки];
ТекстЯчейки = Ячейка.Текст;
Если РазностьОбъекта > 0 Тогда
ЦветТекста = WebЦвета.Зеленый;
ТекстЯчейки = "+" + ТекстЯчейки;
ИначеЕсли РазностьОбъекта < 0 Тогда
ЦветТекста = WebЦвета.Красный;
КонецЕсли;
Ячейка.ЦветТекста = ЦветТекста;
Ячейка.Текст = ТекстЯчейки;
КонецЕсли;
КонецПроцедуры
// Подключает обработчики событий для табличного поля отбора компоновки данных.
//
// Параметры:
// ТабличноеПоле - ТабличноеПоле - отбора компоновки.
//
Процедура ПодключитьОбработчикиСобытийДоступныхПолейКомпоновкиЛкс(ТабличноеПоле) Экспорт
Обработчик = ТабличноеПоле.ПолучитьДействие("ПриПолученииДанных");
Если Истина
И Обработчик <> Неопределено
И Не СтрокиРавныЛкс(Обработчик, "ТабличноеПолеПриПолученииДанных")
Тогда
СообщитьЛкс(СтрШаблонИменЛкс("Обнаружено переопределение обработчика ПриПолученииДанных табличного поля %1",, ТабличноеПоле.Имя));
КонецЕсли;
ТабличноеПоле.УстановитьДействие("ПриПолученииДанных", Новый Действие("ПриПолученииДанныхДоступныхПолей"));
ТабличноеПоле.Колонки[0].КартинкиСтрок = ирКэш.КартинкаПоИмениЛкс("ирТипыДоступныхПолейКомпоновки");
КонецПроцедуры
Процедура УстановитьПолеВПравомЗначенииЭлементаОтбораЛкс(Знач ТабличноеПолеОтбора, Знач ТабличноеПолеДоступныхПолей = Неопределено) Экспорт
Если ТабличноеПолеДоступныхПолей <> Неопределено И ТабличноеПолеДоступныхПолей.ТекущаяСтрока <> Неопределено Тогда
ПолеКомпоновки = ТабличноеПолеДоступныхПолей.ТекущаяСтрока.Поле;
Иначе
ПолеКомпоновки = Новый ПолеКомпоновкиДанных("");
КонецЕсли;
ТекущаяСтрока = ТабличноеПолеОтбора.ТекущаяСтрока;
Если ТипЗнч(ТекущаяСтрока) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
Если ТипЗнч(ТекущаяСтрока.ПравоеЗначение) <> Тип("ПолеКомпоновкиДанных") Или ЗначениеЗаполнено("" + ПолеКомпоновки) Тогда
ТекущаяСтрока.ПравоеЗначение = ПолеКомпоновки;
КонецЕсли;
ТабличноеПолеОтбора.ТекущаяКолонка = ТабличноеПолеОтбора.Колонки.ПравоеЗначениеДляКраткогоОтображенияЭлемента;
КонецЕсли;
КонецПроцедуры
// Получает макет компоновки данных по схеме с использованием временных таблиц.
//
// Параметры:
// Схема - СхемаКомпоновкиДанных;
// Настройки - НастройкиКомпоновкиДанных;
// *ВнешниеНаборыДанных - Структура, *Неопределено - туда добавляются временные таблицы;
// *ДанныеРасшифровки - ДанныеРасшифровкиКомпоновкиДанных, *Неопределено;
// *ЛиОтладка - Булево, *Ложь - показывать тексты запросов и время выполнения этапов.
//
// Возвращаемое значение:
// МакетКомпоновкиДанных.
//
Функция МакетКомпоновкиДанныхСВременнымиТаблицамиЛкс(Схема, Настройки, ВнешниеНаборыДанных = Неопределено,
ДанныеРасшифровки = Неопределено, ЛиОтладка = Ложь, СвойМакетОформления = Неопределено, ПроверятьДоступностьПолей = Ложь) Экспорт
RegExp = ирОбщий.НовыйВычислительРегВыражений();
RegExp.Global = Истина;
RegExp.MultiLine = Истина;
RegExp.IgnoreCase = Истина;
// Допустим 1 уровень скобок.
шСкобки = "\([^\)\(]*?\)";
RegExp.Pattern = "\(ВЫБРАТЬ(?:" + шСкобки + "|[^$\(\)])*?""ВременнаяТаблица"" = ""(.*?)""\)";
Если ВнешниеНаборыДанных = Неопределено Тогда
ВнешниеНаборыДанных = Новый Структура;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
// Выполним создание всех временных таблиц. Временной таблицей считаем набор данных запрос,
// имя которого начинается с "@". Наборы данных временных таблиц удаляются из предварительной схемы.
ПредварительнаяСхема = КопияОбъектаЛкс(Схема);
НаборыДанныхСхемы = ПредварительнаяСхема.НаборыДанных;
ЕстьВременныеТаблицы = Ложь;
НачальноеКоличество = НаборыДанныхСхемы.Количество();
Для СчетчикНаборыДанныхСхемы = 1 По НачальноеКоличество Цикл
НаборДанных = НаборыДанныхСхемы[НачальноеКоличество - СчетчикНаборыДанныхСхемы];
Если Истина
И Лев(НаборДанных.Имя, 1) = "@"
И ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросСхемыКомпоновкиДанных")
Тогда
ВременнаяСхема = КопияОбъектаЛкс(Схема);
// Кривое копирование набора данных в новую схемы, где он будет один.
ВременнаяСхема.СвязиНаборовДанных.Очистить();
НаборыДанныхВременнойСхемы = ВременнаяСхема.НаборыДанных;
НаборыДанныхВременнойСхемыВГраница = НаборыДанныхВременнойСхемы.Количество() - 1;
Для СчетчикВременнойСхемы = 0 По НаборыДанныхВременнойСхемыВГраница Цикл
НаборДанныхВременнойСхемы = НаборыДанныхВременнойСхемы[НаборыДанныхВременнойСхемыВГраница - СчетчикВременнойСхемы];
Если НаборДанныхВременнойСхемы.Имя <> НаборДанных.Имя Тогда
НаборыДанныхВременнойСхемы.Удалить(НаборДанныхВременнойСхемы);
КонецЕсли;
КонецЦикла;
Для Каждого ПолеНабора Из НаборыДанныхВременнойСхемы[0].Поля Цикл
ПолеНабора.ОграничениеИспользования.Поле = Ложь;
ПолеНабора.ВыражениеПредставления = ПолеНабора.ПутьКДанным;
КонецЦикла;
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ВременнаяСхема));
КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
КомпоновщикНастроек.Настройки.Структура.Очистить();
КомпоновщикНастроек.Настройки.Выбор.Элементы.Очистить();
ирОбщий.КомпоновщикНастроекВосстановитьЛкс(КомпоновщикНастроек);
ВременныеНастройки = КомпоновщикНастроек.Настройки;
// Установим использование параметров
Для Каждого ЭлементПараметра Из ВременныеНастройки.ПараметрыДанных.Элементы Цикл
ЭлементПараметра.Использование = Истина;
КонецЦикла;
// Установим структуру и выбранные поля
ЭлементСтруктуры = ВременныеНастройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
Для Каждого ДоступноеПоле Из ВременныеНастройки.ДоступныеПоляВыбора.Элементы Цикл
// Чтобы пропустить системные папки
Если Не ДоступноеПоле.Папка Тогда
НовоеВыбранноеПоле = ВременныеНастройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
НовоеВыбранноеПоле.Поле = ДоступноеПоле.Поле;
НовоеВыбранноеПоле.Использование = Истина;
КонецЕсли;
КонецЦикла;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ВременнаяСхема, ВременныеНастройки,,,, ПроверятьДоступностьПолей);
Запрос.Текст = МакетКомпоновкиДанных.НаборыДанных[0].Запрос;
Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл
Запрос.УстановитьПараметр(Параметр.Имя, Параметр.Значение);
КонецЦикла;
Запрос.Текст = RegExp.Заменить(Запрос.Текст, "$1");
ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Предварительный запрос - " + НаборДанных.Имя);
//// Недоступные поля набора данных цепляются в настройках при совпадении имен с выбранными полями
//// http://partners.v8.1c.ru/forum/thread.jsp?id=514094
//Для Каждого Поле Из НаборДанных.Поля Цикл
// Поле.ПутьКДанным = "_поле_" + Поле.ПутьКДанным;
//КонецЦикла;
НаборыДанныхСхемы.Удалить(НаборДанных);
ЕстьВременныеТаблицы = Истина;
КонецЕсли;
КонецЦикла;
Если Не ЕстьВременныеТаблицы Тогда
Если ЛиОтладка Тогда
ВремяНачалаКомпоновкиМакета = ТекущееВремяВМиллисекундахЛкс();
КонецЕсли;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ПредварительнаяСхема, Настройки, ДанныеРасшифровки, СвойМакетОформления,, ПроверятьДоступностьПолей);
Если ЛиОтладка Тогда
СообщитьЛкс(СтрШаблонИменЛкс("Компоновка макета - %1мс",, ТекущееВремяВМиллисекундахЛкс() - ВремяНачалаКомпоновкиМакета));
КонецЕсли;
Иначе
// Выполним получение результата предварительного запроса
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ПредварительнаяСхема));
КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
ирОбщий.КомпоновщикНастроекВосстановитьЛкс(КомпоновщикНастроек);
ПредварительныеНастройки = КомпоновщикНастроек.Настройки;
Если ЛиОтладка Тогда
ВремяНачалаКомпоновкиМакета = ТекущееВремяВМиллисекундахЛкс();
КонецЕсли;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ПредварительнаяСхема, ПредварительныеНастройки, ДанныеРасшифровки, СвойМакетОформления,, ПроверятьДоступностьПолей);
Если ЛиОтладка Тогда
СообщитьЛкс(СтрШаблонИменЛкс("Компоновка макета - %1мс",, ТекущееВремяВМиллисекундахЛкс() - ВремяНачалаКомпоновкиМакета));
КонецЕсли;
Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл
Запрос.УстановитьПараметр(Параметр.Имя, Параметр.Значение);
КонецЦикла;
СтруктураНаборовДанныхЗапросовМакета = ВсеНаборыДанныхЗапросовКомпоновкиЛкс(МакетКомпоновкиДанных.НаборыДанных);
Для Каждого ЭлементНаборДанныхМакета Из СтруктураНаборовДанныхЗапросовМакета Цикл
НаборДанных = ЭлементНаборДанныхМакета.Значение.НаборДанных;
Запрос.Текст = НаборДанных.Запрос;
Запрос.Текст = RegExp.Заменить(Запрос.Текст, "$1");
РезультатЗапроса = ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Предварительный запрос - " + НаборДанных.Имя);
ВнешниеНаборыДанных.Вставить(НаборДанных.Имя, РезультатЗапроса);
КонецЦикла;
// Получение конечного макета
Для Каждого ЭлементНаборДанных Из СтруктураНаборовДанныхЗапросовМакета Цикл
КоллекцияВладелец = ЭлементНаборДанных.Значение.КоллекцияВладелец;
НаборДанныхЗапрос = ЭлементНаборДанных.Значение.НаборДанных;
НаборДанныхОбъект = КоллекцияВладелец.Добавить(Тип("НаборДанныхОбъектМакетаКомпоновкиДанных"));
// Копируем Свойства набора данных запроса в набор данных объекта
ЗаполнитьЗначенияСвойств(НаборДанныхОбъект, НаборДанныхЗапрос);
НаборДанныхОбъект.ИмяОбъекта = НаборДанныхЗапрос.Имя;
Для Каждого ПолеНабораДанныхОригинала Из НаборДанныхЗапрос.Поля Цикл
ПолеРезультата = НаборДанныхОбъект.Поля.Добавить();
ЗаполнитьЗначенияСвойств(ПолеРезультата, ПолеНабораДанныхОригинала);
ЗаполнитьЗначенияСвойств(ПолеРезультата.Роль, ПолеНабораДанныхОригинала.Роль);
КонецЦикла;
КоллекцияВладелец.Удалить(НаборДанныхЗапрос);
КонецЦикла;
КонецЕсли;
// Баг платформы. Пустая дата превращается в Неопределено.
Для Каждого ПараметрСхемы Из ПредварительнаяСхема.Параметры Цикл
Если ПараметрСхемы.ОграничениеИспользования Тогда
Если Не ПараметрСхемы.ДоступенСписокЗначений Тогда
ЗначениеПараметра = МакетКомпоновкиДанных.ЗначенияПараметров.Найти(ПараметрСхемы.Имя);
ЗначениеПараметра.Значение = ПараметрСхемы.ТипЗначения.ПривестиЗначение(ЗначениеПараметра.Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат МакетКомпоновкиДанных;
КонецФункции
#КонецЕсли
Функция КоличествоИзмененийПоУзлуЛкс(Узел, МассивМетаданных = Неопределено) Экспорт
#Если Клиент Тогда
СостояниеЛкс("Вычисление количества изменений на узле…");
#КонецЕсли
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Узел", Узел);
МетаПланОбмена = Узел.Метаданные();
ТекстЗапроса = "";
Для Каждого ЭлементСОстава Из МетаПланОбмена.Состав Цикл
МетаОбъект = ЭлементСОстава.Метаданные;
Если Ложь
Или МетаОбъект = Неопределено
Или (Истина
И МассивМетаданных <> Неопределено
И МассивМетаданных.Найти(МетаОбъект) = Неопределено)
Тогда
Продолжить;
КонецЕсли;
ИмяТаблицыДляПоискаЗарегистрированных = ирКэш.ИмяТаблицыИзМетаданныхЛкс(МетаОбъект.ПолноеИмя(), Истина);
Если ИмяТаблицыДляПоискаЗарегистрированных = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ТекстЗапроса <> "" Тогда
ТекстЗапроса = ТекстЗапроса + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС;
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + "ВЫБРАТЬ Количество(*) КАК Количество
|ИЗ
| " + ИмяТаблицыДляПоискаЗарегистрированных + " КАК РегистрацияИзменений
|ГДЕ
| РегистрацияИзменений.Узел = &Узел
|";
КонецЦикла;
Если ТекстЗапроса <> "" Тогда
Запрос.Текст = ТекстЗапроса;
ТаблицаКоличестваИзменений = Запрос.Выполнить().Выгрузить();
КоличествоИзменений = ТаблицаКоличестваИзменений.Итог("Количество");
Иначе
КоличествоИзменений = 0;
КонецЕсли;
#Если Клиент Тогда
СостояниеЛкс("");
#КонецЕсли
Возврат КоличествоИзменений;
КонецФункции
// Параметры:
// СтрокаТаблицыИлиДерева - СтрокаТаблицыЗначений, СтрокаДереваЗначений, ВыборкаИзРезультатаЗапроса
// Результат - Структура
Функция СтруктураИзСтрокиТаблицыИлиДереваИлиВыборкиЛкс(СтрокаТаблицыИлиДереваИлиВыборки) Экспорт
Результат = Новый Структура;
Для Каждого МетаРеквизит Из СтрокаТаблицыИлиДереваИлиВыборки.Владелец().Колонки Цикл
Результат.Вставить(МетаРеквизит.Имя, СтрокаТаблицыИлиДереваИлиВыборки[МетаРеквизит.Имя]);
КонецЦикла;
Возврат Результат;
КонецФункции
// Получает структуру свойств объекта по имени типа или объекту.
//
// Параметры:
// пОбъект - Произвольный - имя типа или сам объект;
//
// Возвращаемое значение:
// - Структура - свойств.
//
Функция СтруктураСвойствСтрокиТаблицыИлиДереваЛкс(ОбъектИлиТип) Экспорт
СтруктураСвойств = Новый Структура;
ТипОбъекта = ТипЗнч(ОбъектИлиТип);
МетаОбъект = ПолучитьМетаданныеЛкс(ТипОбъекта);
Если МетаОбъект <> Неопределено Тогда
КорневойТип = КорневойТипКонфигурацииЛкс(МетаОбъект, Истина);
Если Ложь
ИЛИ КорневойТип = "Обработка"
ИЛИ КорневойТип = "Отчет"
Тогда
Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
Для Каждого МетаРеквизит Из МетаОбъект.ТабличныеЧасти Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
КонецЕсли;
Если КорневойТипСтрокиТабличнойЧастиЛкс(ТипОбъекта) <> Неопределено Тогда
Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
КонецЕсли;
ИначеЕсли Ложь
Или ТипОбъекта = Тип("СтрокаТаблицыЗначений")
Или ТипОбъекта = Тип("СтрокаДереваЗначений")
Тогда
Попытка
МетаОбъект = ОбъектИлиТип.Владелец();
Исключение
// Строка была удалена
МетаОбъект = Неопределено;
КонецПопытки;
Если МетаОбъект <> Неопределено Тогда
Для Каждого МетаРеквизит Из МетаОбъект.Колонки Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат СтруктураСвойств;
КонецФункции
// Переустанавливает значения недоступных параметров из схемы (антибаг платформы).
//
// Параметры:
// СхемаКомпоновкиДанных - СхемаКомпоновкиДанных;
// КомпоновщикНастроек - КомпоновщикНастроекКомпоновкиДанных.
//
Процедура ОбновитьЗначенияНедоступныхПараметровИзСхемыЛкс(КомпоновщикНастроек, СхемаКомпоновкиДанных) Экспорт
#Если Сервер И Не Сервер Тогда
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
#КонецЕсли
Для Каждого ЗначениеПараметра Из КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы Цикл
ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти("" + ЗначениеПараметра.Параметр);
Если Истина
И ПараметрСхемы <> Неопределено
И ПараметрСхемы.ОграничениеИспользования
Тогда
//Если ЗначениеЗаполнено(ЗначениеПараметра.Выражение) Тогда
// Попытка
// ЗначениеПараметра.Значение = Вычислить();
// Исключение
// КонецПопытки;
//Иначе
ЗначениеПараметра.Значение = ПараметрСхемы.Значение;
//КонецЕсли;
//ЗначениеПараметра.Использование = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновкиДанных) Экспорт
ПолеКоличества = "КоличествоСтрокАвто";
ВычисляемоеПоле = СхемаКомпоновкиДанных.ВычисляемыеПоля.Добавить();
ВычисляемоеПоле.Выражение = "1";
ВычисляемоеПоле.Заголовок = "Количество строк (авто)";
ВычисляемоеПоле.ПутьКДанным = ПолеКоличества;
РесурсКоличествоЗаписей = СхемаКомпоновкиДанных.ПоляИтога.Добавить();
РесурсКоличествоЗаписей.ПутьКДанным = ПолеКоличества;
РесурсКоличествоЗаписей.Выражение = "Сумма(1)";
КонецПроцедуры
Функция СоздатьСхемуПоТаблицеЗначенийЛкс(ТаблицаЗначений1, выхНаборыДанных = Неопределено) Экспорт
выхНаборыДанных = Новый Структура("ТаблицаЗначений", ТаблицаЗначений1);
Схема = СоздатьСхемуПоТаблицамЗначенийЛкс(выхНаборыДанных,,,, Ложь);
Возврат Схема;
КонецФункции
// Создает новую или добавляет в существующую схему компоновки наборы данных объекты из структуры таблиц значений.
//
// Параметры:
// СтруктураТаблиц - Структура - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Функция СоздатьСхемуПоТаблицамЗначенийЛкс(СтруктураТаблиц, СхемаКомпоновкиДанных = Неопределено, СоздаватьПапкиПолей = Ложь, СоздаватьРесурсыЧисловыхПолей = Ложь,
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
СтруктураТаблиц = Новый Структура;
#КонецЕсли
Если СхемаКомпоновкиДанных = Неопределено Тогда
СхемаКомпоновкиДанных = СоздатьСхемуКомпоновкиЛкс();
КонецЕсли;
Для Каждого КлючИЗначение Из СтруктураТаблиц Цикл
КолонкиНабора = КолонкиИсточникаДанныхЛкс(КлючИЗначение.Значение);
СоздатьИлиОбновитьНаборДанныхОбъектПоМетаданнымЛкс(СхемаКомпоновкиДанных, КолонкиНабора, КлючИЗначение.Ключ, СоздаватьПапкиПолей, СоздаватьРесурсыЧисловыхПолей, КлючИЗначение.Значение);
КонецЦикла;
Если ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок Тогда
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновкиДанных);
КонецЕсли;
Возврат СхемаКомпоновкиДанных;
КонецФункции
Функция СоздатьСхемуКомпоновкиЛкс() Экспорт
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных);
Возврат СхемаКомпоновкиДанных;
КонецФункции
Функция КолонкиИсточникаДанныхЛкс(Знач ИсточникДанных)
Если Ложь
Или ТипЗнч(ИсточникДанных) = Тип("ДеревоЗначений")
Или ТипЗнч(ИсточникДанных) = Тип("ТаблицаЗначений")
Тогда
КолонкиНабора = ИсточникДанных.Колонки;
Иначе
КолонкиНабора = ИсточникДанных.ВыгрузитьКолонки().Колонки;
КонецЕсли;
Возврат КолонкиНабора;
КонецФункции
// Создает новую или добавляет в существующую схему компоновки набор данных объект из полей настройки.
//
// Параметры:
// ПоляНастройки - ПоляНастройки - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Функция СоздатьСхемуПоПолямНастройкиЛкс(ПоляНастройки, СхемаКомпоновкиДанных = Неопределено, ИмяНабора = "Основной") Экспорт
Если СхемаКомпоновкиДанных = Неопределено Тогда
СхемаКомпоновкиДанных = СоздатьСхемуКомпоновкиЛкс();
КонецЕсли;
#Если Сервер И Не Сервер Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
НаборДанных.Имя = ИмяНабора;
НаборДанных.ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных[0].Имя;
НаборДанных.ИмяОбъекта = ИмяНабора;
Для Каждого ПолеНастройки Из ПоляНастройки Цикл
Поле = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
Поле.ПутьКДанным = ПолеНастройки.Имя;
Поле.Поле = ПолеНастройки.ПутьКДанным;
Поле.Заголовок = ПолеНастройки.Представление;
Поле.ТипЗначения = ПолеНастройки.ТипЗначения;
ОграничениеИспользования = Поле.ОграничениеИспользования;
ОграничениеИспользования.Поле = Не ПолеНастройки.Поле;
ОграничениеИспользования.Условие = Не ПолеНастройки.Отбор;
ОграничениеИспользования.Порядок = Не ПолеНастройки.Порядок;
ОграничениеИспользования.Группировка = Не ПолеНастройки.Измерение;
ЗначениеОграничения = ПолеНастройки.Поля.Количество() = 0;
ОграничениеИспользованияРеквизитов = Поле.ОграничениеИспользованияРеквизитов;
ОграничениеИспользованияРеквизитов.Поле = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Условие = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Порядок = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Группировка = ЗначениеОграничения;
КонецЦикла;
Возврат СхемаКомпоновкиДанных;
КонецФункции
// Параметры:
// Поле -
// Доступность -
// ПрименитьГруппировка -
// ПрименитьПоле -
// ПрименитьПорядок -
// ПрименитьУсловие -
// Возвращаемое значение:
//
Функция УстановитьОграниченияИспользованияПоляНабораДанныхСхемыКомпоновкиЛкс(Знач ПолеИлиОграничениеИспользования, Знач Ограничивать = Ложь, Знач ПрименитьГруппировка = Истина,
Знач ПрименитьПоле = Истина, Знач ПрименитьПорядок = Истина, Знач ПрименитьУсловие = Истина) Экспорт
МассивГруппОграничений = Новый Массив;
Если ТипЗнч(ПолеИлиОграничениеИспользования) = Тип("ОграничениеИспользованияПоляСхемыКомпоновкиДанных") Тогда
МассивГруппОграничений.Добавить(ПолеИлиОграничениеИспользования);
Иначе
Поле = ПолеИлиОграничениеИспользования;
МассивГруппОграничений.Добавить(Поле.ОграничениеИспользования);
Попытка
МассивГруппОграничений.Добавить(Поле.ОграничениеИспользованияРеквизитов);
Исключение
КонецПопытки;
КонецЕсли;
Для Каждого ОграничениеИспользования Из МассивГруппОграничений Цикл
Если ПрименитьГруппировка Тогда
ОграничениеИспользования.Группировка = Ограничивать;
КонецЕсли;
Если ПрименитьПоле Тогда
ОграничениеИспользования.Поле = Ограничивать;
КонецЕсли;
Если ПрименитьПорядок Тогда
ОграничениеИспользования.Порядок = Ограничивать;
КонецЕсли;
Если ПрименитьУсловие Тогда
ОграничениеИспользования.Условие = Ограничивать;
КонецЕсли;
КонецЦикла;
КонецФункции
// Функция добавляет в схему компоновки источник данных с типом "Local"
Функция ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных) Экспорт
ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить();
ИсточникДанных.Имя = "ИсточникДанных1";
ИсточникДанных.ТипИсточникаДанных = "Local";
Возврат ИсточникДанных;
КонецФункции
// Функция добавляет набор данных - запрос в указанную в параметре коллекцию наборов данных
Функция ДобавитьНаборДанныхЗапросЛкс(НаборыДанных, ИсточникДанных, ИмяНабораДанных = "Основной") Экспорт
НаборДанных = НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
НаборДанных.Имя = ИмяНабораДанных;
НаборДанных.ИсточникДанных = ИсточникДанных.Имя;
Возврат НаборДанных;
КонецФункции
// Конструктор массива через Параметры.
//
// Параметры:
// *п... - Произвольный - элементы массива.
//
// Возвращаемое значение:
// Массив - полученный массив.
//
Функция ЗначенияВМассивЛкс(
п1 = Неопределено, п2 = Неопределено, п3 = Неопределено, п4 = Неопределено, п5 = Неопределено,
п6 = Неопределено, п7 = Неопределено, п8 = Неопределено, п9 = Неопределено, п10= Неопределено,
п11= Неопределено, п12= Неопределено, п13= Неопределено, п14= Неопределено, п15= Неопределено,
п16= Неопределено, п17= Неопределено, п18= Неопределено, п19= Неопределено, п20= Неопределено
) Экспорт
Перем М;
М = Новый Массив();
Если п1 = Неопределено Тогда Возврат М; Иначе М.Добавить(п1 ); КонецЕсли;
Если п2 = Неопределено Тогда Возврат М; Иначе М.Добавить(п2 ); КонецЕсли;
Если п3 = Неопределено Тогда Возврат М; Иначе М.Добавить(п3 ); КонецЕсли;
Если п4 = Неопределено Тогда Возврат М; Иначе М.Добавить(п4 ); КонецЕсли;
Если п5 = Неопределено Тогда Возврат М; Иначе М.Добавить(п5 ); КонецЕсли;
Если п6 = Неопределено Тогда Возврат М; Иначе М.Добавить(п6 ); КонецЕсли;
Если п7 = Неопределено Тогда Возврат М; Иначе М.Добавить(п7 ); КонецЕсли;
Если п8 = Неопределено Тогда Возврат М; Иначе М.Добавить(п8 ); КонецЕсли;
Если п9 = Неопределено Тогда Возврат М; Иначе М.Добавить(п9 ); КонецЕсли;
Если п10= Неопределено Тогда Возврат М; Иначе М.Добавить(п10); КонецЕсли;
Если п11= Неопределено Тогда Возврат М; Иначе М.Добавить(п11); КонецЕсли;
Если п12= Неопределено Тогда Возврат М; Иначе М.Добавить(п12); КонецЕсли;
Если п13= Неопределено Тогда Возврат М; Иначе М.Добавить(п13); КонецЕсли;
Если п14= Неопределено Тогда Возврат М; Иначе М.Добавить(п14); КонецЕсли;
Если п15= Неопределено Тогда Возврат М; Иначе М.Добавить(п15); КонецЕсли;
Если п16= Неопределено Тогда Возврат М; Иначе М.Добавить(п16); КонецЕсли;
Если п17= Неопределено Тогда Возврат М; Иначе М.Добавить(п17); КонецЕсли;
Если п18= Неопределено Тогда Возврат М; Иначе М.Добавить(п18); КонецЕсли;
Если п19= Неопределено Тогда Возврат М; Иначе М.Добавить(п19); КонецЕсли;
Если п20= Неопределено Тогда Возврат М; Иначе М.Добавить(п20); КонецЕсли;
Возврат М;
КонецФункции // ЗначенияВМассивЛкс()
Функция ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение, Название, XMLПредставлениеДляНеизвестныхТипов = Истина) Экспорт
Если Ложь
Или ТипЗнч(Значение) = Тип("ТабличныйДокумент")
Или ТипЗнч(Значение) = Тип("ТекстовыйДокумент")
Тогда
Документ = Значение;
Иначе
Документ = Новый ТекстовыйДокумент;
Если ТипЗнч(Значение) = Тип("ХранилищеЗначения") Тогда
Значение = Значение.Получить();
КонецЕсли;
Если ТипЗнч(Значение) <> Тип("Строка") И XMLПредставлениеДляНеизвестныхТипов Тогда
Представление = ОбъектВСтрокуXMLЛкс(Значение);
Представление = ДекодироватьТекстИзXMLЛкс(Представление);
Иначе
Представление = Значение;
КонецЕсли;
Документ.УстановитьТекст(Представление);
КонецЕсли;
Путь = ПолучитьИмяВременногоФайла(Название);
Документ.Записать(Путь);
Возврат Путь;
КонецФункции
// Получает строку путем отсечения заданного числа последних символов.
//
// Параметры:
// пСтрока - Строка - исходная;
// пДлинаКонца - Число, *1 - количество отсекаемых символов;
//
// Возвращаемое значение:
// - Строка.
//
Функция СтрокаБезКонцаЛкс(пСтрока, пДлинаКонца = 1) Экспорт
Если СтрДлина(пСтрока) < пДлинаКонца Тогда
Возврат "";
Иначе
Возврат Лев(пСтрока, СтрДлина(пСтрока) - пДлинаКонца);
КонецЕсли;
КонецФункции
Функция СтрокаБезПоследнегоФрагментаЛкс(Знач Строка, Знач Разделитель = ".") Экспорт
Фрагменты = СтрРазделитьЛкс(Строка, Разделитель);
#Если Сервер И Не Сервер Тогда
Фрагменты = Новый Массив;
#КонецЕсли
Фрагменты.Удалить(Фрагменты.ВГраница());
Результат = СтрСоединитьЛкс(Фрагменты, Разделитель);
Возврат Результат;
КонецФункции
// Получает строку путем повтора переданной строки заданное количество раз.
//
// Параметры:
// СтрокаДляПовтора - Строка;
// ЧислоПовторов - Число.
//
// Возвращаемое значение:
// Строка.
//
Функция СтрокаПовторомЛкс(СтрокаДляПовтора, ЧислоПовторов) Экспорт
Результат = "";
Для Счетчик = 1 По ЧислоПовторов Цикл
Результат = Результат + СтрокаДляПовтора;
КонецЦикла;
Возврат Результат;
КонецФункции // СтрокаПовторомЛкс()
// Преобразует исходную строку в число без вызова исключений.
//
// Параметры:
// Значение - Строка - строка, которую необходимо привести к числу.
// Например, "10", "+10", "010", вернет 10;
// "(10)", "-10",вернет -10;
// "10,2", "10.2",вернет 10.2;
// "000", " ", "",вернет 0;
// "10текст", вернет Неопределено.
// ОписаниеТипов - ОписаниеТипов - Допустимое описание типов численного значения
// выхПримечание - Строка - описание ошибки
//
// Возвращаемое значение:
// Число - полученное число.
//
Функция СтрокаВЧислоЛкс(Представление, Знач ОписаниеТипов = Неопределено, выхПримечание = "") Экспорт
Если ОписаниеТипов = Неопределено Тогда
ОписаниеТипов = Новый ОписаниеТипов("Число");
КонецЕсли;
НРегПредставление = НРег(Представление);
Если Ложь
Или НРегПредставление = "да"
Или НРегПредставление = "yes"
или НРегПредставление = "истина"
Или НРегПредставление = "true"
или НРегПредставление = "включено"
или НРегПредставление = "on"
Тогда
Возврат 1;
ИначеЕсли Ложь
Или НРегПредставление = "нет"
Или НРегПредставление = "no"
или НРегПредставление = "ложь"
Или НРегПредставление = "false"
или НРегПредставление = "выключено"
или НРегПредставление = "off"
Тогда
Возврат 0;
КонецЕсли;
Результат = Представление;
Результат = СтрЗаменить(Результат, " ", "");
Результат = СтрЗаменить(Результат, "−", "-");
Если Найти(Результат, ",") > 0 Тогда
Если Найти(Результат, ".") > 0 Тогда
Результат = СтрЗаменить(Результат, ",", "");
Иначе
Результат = СтрЗаменить(Результат, ",", ".");
КонецЕсли;
КонецЕсли;
Попытка
Результат = Число(Результат);
Исключение
Результат = СокрП(Результат);
Если Прав(Результат, 1) = "%" Тогда
Результат = СтрокаБезКонцаЛкс(Результат, 1);
Попытка
Результат = Число(Результат) / 100;
Исключение
КонецПопытки;
КонецЕсли;
КонецПопытки;
Если ТипЗнч(Результат) = Тип("Строка") Тогда
Если ОписаниеТипов.СодержитТип(Тип("Булево")) Тогда
ИмяТипа = "булева";
Иначе
ИмяТипа = "числа";
КонецЕсли;
выхПримечание = "Неправильный формат " + ИмяТипа;
Возврат 0;
КонецЕсли;
Результат1 = ОписаниеТипов.ПривестиЗначение(Результат);
Если Результат1 <> Результат Тогда
выхПримечание = "Числовое значение вне границ типа";
КонецЕсли;
Возврат Результат1;
КонецФункции
// Функция возвращает части представления даты
//
// Параметры:
// Представление - Представление даты
//
// Возвращаемое значение:
// массив частей даты
//
Функция ЧастиПредставленияДаты(Знач Представление, выхПозицияГода = Неопределено)
МассивЧастей = Новый Массив;
НачалоЧисла = 0;
// TODO переделать на рег. выражения
Если ирКэш.РежимОтладкиЛкс() Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для к = 1 По СтрДлина(Представление) Цикл
Символ = Сред(Представление, к ,1);
ЭтоЦифра = Символ >= "0" и Символ <= "9";
Если ЭтоЦифра Тогда
Если НачалоЧисла = 0 Тогда
НачалоЧисла = к;
КонецЕсли;
Иначе
Если НачалоЧисла <> 0 Тогда
СтрокаЧисла = Сред(Представление, НачалоЧисла, к - НачалоЧисла);
Если СтрДлина(СтрокаЧисла) = 4 Тогда
выхПозицияГода = МассивЧастей.Количество();
КонецЕсли;
МассивЧастей.Добавить(Число(СтрокаЧисла));
КонецЕсли;
НачалоЧисла = 0;
КонецЕсли;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для к = 1 По СтрДлина(Представление) Цикл Символ = Сред(Представление, к ,1); ЭтоЦифра = Символ >= "0" и Символ <= "9"; Если ЭтоЦифра Тогда Если НачалоЧисла = 0 Тогда НачалоЧисла = к; КонецЕсли; Иначе Если НачалоЧисла <> 0 Тогда СтрокаЧисла = Сред(Представление, НачалоЧисла, к - НачалоЧисла); Если СтрДлина(СтрокаЧисла) = 4 Тогда выхПозицияГода = МассивЧастей.Количество(); КонецЕсли; МассивЧастей.Добавить(Число(СтрокаЧисла)); КонецЕсли; НачалоЧисла = 0; КонецЕсли; КонецЦикла;
КонецЕсли;
Если НачалоЧисла <> 0 Тогда
МассивЧастей.Добавить(Число(Сред(Представление, НачалоЧисла)));
КонецЕсли;
Возврат МассивЧастей;
КонецФункции
// Функция приводит строковое представление даты к его значению
//
// Параметры:
// Представление - Представление числа
// ОписаниеТипов - Допустимое описание типов значения типа дата
//
// Возвращаемое значение:
// Значение типа дата
//
Функция СтрокаВДатуЛкс(Представление, ОписаниеТипов = Неопределено, выхПримечание = "", АмериканскоеПоложениеМесяца = Ложь) Экспорт
Если ОписаниеТипов = Неопределено Тогда
ОписаниеТипов = Новый ОписаниеТипов("Дата");
КонецЕсли;
Результат = ОписаниеТипов.ПривестиЗначение(Представление);
Если Результат = '00010101' Тогда
ЛиНеправильныйФормат = Ложь;
ПозицияГода = Неопределено;
МассивЧастей = ЧастиПредставленияДаты(Представление, ПозицияГода);
Если ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Время Тогда
Попытка
Если МассивЧастей.Количество() = 3 Тогда
Результат = Дата(1,1,1, МассивЧастей[0], МассивЧастей[1], МассивЧастей[2]);
ИначеЕсли МассивЧастей.Количество() = 6 Тогда
Результат = Дата(1,1,1, МассивЧастей[3], МассивЧастей[4], МассивЧастей[5]);
КонецЕсли;
Исключение
ЛиНеправильныйФормат = Истина;
КонецПопытки;
ИначеЕсли Ложь
Или МассивЧастей.Количество() = 3
Или МассивЧастей.Количество() = 6
Или МассивЧастей.Количество() = 7 // С миллисекундами. Просто выбрасываем их
Тогда
Если МассивЧастей[0] >= 1000 Тогда
ПозицияГода = 0;
КонецЕсли;
Если Истина
И ПозицияГода <> Неопределено
И ПозицияГода <> 2
Тогда
Временно = МассивЧастей[ПозицияГода];
МассивЧастей[ПозицияГода] = МассивЧастей[2];
МассивЧастей[2] = Временно;
КонецЕсли;
// Теперь год всегда на 3-й позиции (индекс=2)
Если МассивЧастей[2] < 100 Тогда
МассивЧастей[2] = МассивЧастей[2] + ?(МассивЧастей[2] < 30, 2000,1900);
КонецЕсли;
//Если МассивЧастей.Количество() = 7 Тогда
// ДробнаяЧасть = МассивЧастей[7];
//Иначе
// ДробнаяЧасть = 0;
//КонецЕсли;
Если АмериканскоеПоложениеМесяца Тогда
Временно = МассивЧастей[0];
МассивЧастей[0] = МассивЧастей[1];
МассивЧастей[1] = Временно;
КонецЕсли;
Попытка
Если МассивЧастей.Количество() = 3 или ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Дата Тогда
Результат = Дата(МассивЧастей[2], МассивЧастей[1], МассивЧастей[0]);
Иначе
Результат = Дата(МассивЧастей[2], МассивЧастей[1], МассивЧастей[0], МассивЧастей[3], МассивЧастей[4], МассивЧастей[5]);
КонецЕсли;
Исключение
ЛиНеправильныйФормат = Истина;
КонецПопытки;
Иначе
ЛиНеправильныйФормат = Истина;
КонецЕсли;
Если ЛиНеправильныйФормат Тогда
выхПримечание = "Неправильный формат даты";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Разделяет URL по составным частям: протокол, сервер, путь к ресурсу.
//
// Параметры:
// URL - Строка - ссылка на ресурс в сети Интернет
//
// Возвращаемое значение:
// Структура:
// Протокол - Строка - протокол доступа к ресурсу
// ИмяСервера - Строка - сервер, на котором располагается ресурс
// ПутьКФайлуНаСервере - Строка - путь к ресурсу на сервере
//
Функция РазделитьURLЛкс(Знач URL) Экспорт
СтруктураURL = СтруктураURIЛкс(URL);
Результат = Новый Структура;
Результат.Вставить("Протокол", ?(ПустаяСтрока(СтруктураURL.Схема), "http", СтруктураURL.Схема));
Результат.Вставить("ИмяСервера", СтруктураURL.ИмяСервера);
Результат.Вставить("ПутьКФайлуНаСервере", СтруктураURL.ПутьНаСервере);
Возврат Результат;
КонецФункции
// Разбирает строку URI на составные части и возвращает в виде структуры.
// На основе RFC 3986.
//
// Параметры:
// СтрокаURI - Строка - ссылка на ресурс в формате: <схема>://<логин>:<пароль>@<хост>:<порт>/<путь>?<параметры>#<якорь>
//
// Возвращаемое значение:
// Структура - составные части URI согласно формату:
// * Схема - Строка
// * Логин - Строка
// * Пароль - Строка
// * ИмяСервера - Строка - часть <хост>:<порт> входного параметра
// * Хост - Строка
// * Порт - Строка
// * ПутьНаСервере - Строка - часть <путь>?<параметры>#<якорь> входного параметра
//
Функция СтруктураURIЛкс(Знач СтрокаURI) Экспорт
СтрокаURI = СокрЛП(СтрокаURI);
// схема
Схема = "";
Позиция = Найти(СтрокаURI, "://");
Если Позиция > 0 Тогда
Схема = НРег(Лев(СтрокаURI, Позиция - 1));
СтрокаURI = Сред(СтрокаURI, Позиция + 3);
КонецЕсли;
// строка соединения и путь на сервере
СтрокаСоединения = СтрокаURI;
ПутьНаСервере = "";
Позиция = Найти(СтрокаСоединения, "/");
Если Позиция > 0 Тогда
ПутьНаСервере = Сред(СтрокаСоединения, Позиция + 1);
СтрокаСоединения = Лев(СтрокаСоединения, Позиция - 1);
КонецЕсли;
// информация пользователя и имя сервера
СтрокаАвторизации = "";
ИмяСервера = СтрокаСоединения;
Позиция = Найти(СтрокаСоединения, "@");
Если Позиция > 0 Тогда
СтрокаАвторизации = Лев(СтрокаСоединения, Позиция - 1);
ИмяСервера = Сред(СтрокаСоединения, Позиция + 1);
КонецЕсли;
// логин и пароль
Логин = СтрокаАвторизации;
Пароль = "";
Позиция = Найти(СтрокаАвторизации, ":");
Если Позиция > 0 Тогда
Логин = Лев(СтрокаАвторизации, Позиция - 1);
Пароль = Сред(СтрокаАвторизации, Позиция + 1);
КонецЕсли;
// хост и порт
Хост = ИмяСервера;
Порт = "";
Позиция = Найти(ИмяСервера, ":");
Если Позиция > 0 Тогда
Хост = Лев(ИмяСервера, Позиция - 1);
Порт = Сред(ИмяСервера, Позиция + 1);
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("Схема", Схема);
Результат.Вставить("ИспользоватьHTTPS", ирОбщий.СтрокиРавныЛкс(Схема, "HTTPS"));
Результат.Вставить("Логин", Логин);
Результат.Вставить("Пароль", Пароль);
Результат.Вставить("ИмяСервера", ИмяСервера);
Результат.Вставить("Хост", Хост);
Результат.Вставить("Порт", ?(ПустаяСтрока(Порт), Неопределено, Число(Порт)));
Результат.Вставить("ПортHTTP", ?(ПустаяСтрока(Порт), ?(Результат.ИспользоватьHTTPS, 443, 80), Результат.Порт));
Результат.Вставить("ПутьНаСервере", ПутьНаСервере);
Возврат Результат;
КонецФункции
// Получает значения параметров из строки.
//
// Параметры:
// СтрокаПараметров - Строка - строка, содержащая параметры, каждый из которых представляет собой
// фрагмент вида <Имя параметра>=<Значение>, где:
// Имя параметра - имя параметра;
// Значение - его значение.
// Фрагменты отделяются друг от друга символами ';'.
// Если значение содержит пробельные символы, то оно должно быть заключено в двойные
// кавычки (").
// Например:
// "File=""c:\InfoBases\Trade""; Usr=""Director"";"
// Разделитель - Строка - символ, которым фрагменты отделяются друг от друга.
//
// Возвращаемое значение:
// Структура - значения параметров, где ключ - имя параметра, значение - значение параметра.
//
// Пример:
// Результат = СтроковыеФункцииКлиентСервер.ПараметрыИзСтроки("File=""c:\InfoBases\Trade""; Usr=""Director"";""", ";");
// - вернет структуру:
// ключ "File" и значение "c:\InfoBases\Trade"
// ключ "Usr" и значение "Director".
//
Функция ЗначенияПараметровИзСтрокиЛкс(Знач СтрокаПараметров, Знач Разделитель = ";") Экспорт
Результат = Новый Структура;
ОписаниеПараметра = "";
НайденоНачалоСтроки = Ложь;
НомерПоследнегоСимвола = СтрДлина(СтрокаПараметров);
Для НомерСимвола = 1 По НомерПоследнегоСимвола Цикл
Символ = Сред(СтрокаПараметров, НомерСимвола, 1);
Если Символ = """" Тогда
НайденоНачалоСтроки = Не НайденоНачалоСтроки;
КонецЕсли;
Если Символ <> Разделитель Или НайденоНачалоСтроки Тогда
ОписаниеПараметра = ОписаниеПараметра + Символ;
КонецЕсли;
Если Символ = Разделитель И Не НайденоНачалоСтроки Или НомерСимвола = НомерПоследнегоСимвола Тогда
Позиция = Найти(ОписаниеПараметра, "=");
Если Позиция > 0 Тогда
ИмяПараметра = СокрЛП(Лев(ОписаниеПараметра, Позиция - 1));
ЗначениеПараметра = СокрЛП(Сред(ОписаниеПараметра, Позиция + 1));
ЗначениеПараметра = СтрокаИзВыраженияВстроенногоЯзыкаЛкс(ЗначениеПараметра);
Результат.Вставить(ИмяПараметра, ЗначениеПараметра);
КонецЕсли;
ОписаниеПараметра = "";
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
// Получает представление из идентификатора по правилу
// "Дебиторка_По_контрагентамСИнтерваламиСНГДля__Руководства" => "Дебиторка По контрагентам с интервалами СНГ для Руководства".
// После символа "_" регистр не меняется, а сам символ заменяется на " ".
//
// Параметры:
// ИсходнаяСтрока - Строка - идентификатор.
//
// Возвращаемое значение:
// - Строка - представление.
//
Функция ПредставлениеИзИдентификатораЛкс(ИсходнаяСтрока) Экспорт
СтрокаВозврата = Сред(ИсходнаяСтрока, 1, 1);
Для Сч = 2 По СтрДлина(ИсходнаяСтрока) Цикл
ПредыдущийСимвол = Сред(ИсходнаяСтрока, Сч - 1, 1);
ТекущийСимвол = Сред(ИсходнаяСтрока, Сч, 1);
СледующийСимвол = Сред(ИсходнаяСтрока, Сч + 1, 1);
ПослеследующийСимвол = Сред(ИсходнаяСтрока, Сч + 2, 1);
Если ТекущийСимвол = "_" Тогда
СтрокаВозврата = СтрокаВозврата + " ";
Продолжить;
ИначеЕсли Истина
И ВРЕГ(ТекущийСимвол) = ТекущийСимвол
// В идентификаторе не должны встречаться пробелы. Поэтому было решено закомментировать следующую строку.
//И ПредыдущийСимвол <> " "
Тогда
Если Ложь
ИЛИ ВРЕГ(ПредыдущийСимвол) <> ПредыдущийСимвол
ИЛИ (Истина
И ПредыдущийСимвол <> "_"
И ВРЕГ(ПредыдущийСимвол) = ПредыдущийСимвол
И ВРЕГ(СледующийСимвол) <> СледующийСимвол)
Тогда
СтрокаВозврата = СтрокаВозврата + " ";
Если Ложь
ИЛИ ВРЕГ(СледующийСимвол) <> СледующийСимвол
ИЛИ ВРЕГ(ПослеследующийСимвол) <> ПослеследующийСимвол
Тогда
ТекущийСимвол = НРЕГ(ТекущийСимвол);
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтрокаВозврата = СтрокаВозврата + ТекущийСимвол;
КонецЦикла;
Возврат СтрокаВозврата;
КонецФункции
// Преобразует строку для использования в регулярных выражениях.
// Производится
//
// Параметры:
// пТекст - Строка.
//
// Возвращаемое значение:
// Строка - для вставки в регулярные выражения.
//
Функция ПреобразоватьТекстДляРегулярныхВыраженийЛкс(пТекст) Экспорт
Текст = пТекст;
СтрокаСлужебныхСимволов = "\[]^$()?*+.|"; // "\" должен быть первым
Для Счетчик = 1 По СтрДлина(СтрокаСлужебныхСимволов) Цикл
СпецСимвол = Сред(СтрокаСлужебныхСимволов, Счетчик, 1);
Текст = СтрЗаменить(Текст, СпецСимвол, "\" + СпецСимвол);
КонецЦикла;
Возврат Текст;
КонецФункции // ПреобразоватьТекстДляРегулярныхВыраженийЛкс()
// Шаблон для вызова
//Вхождения = ирОбщий.НайтиРегулярноеВыражениеЛкс(Текст, Шаблон);
//#Если Сервер И Не Сервер Тогда
// Вхождения = Обработки.ирПлатформа.Создать().ВхожденияРегВыражения;
//#КонецЕсли
//Для каждого Вхождение Из Вхождения Цикл
//КонецЦикла;
Функция НайтиРегулярноеВыражениеЛкс(Знач Текст, Знач Шаблон, Знач ИменаПодгрупп = "", Знач ИскатьВсеВхождения = Истина, Знач ИгнорироватьРегистрБукв = Истина,
Знач МногострочныйРежим = Ложь, ВызыватьИсключение = Истина, БезПодгрупп = Ложь, Вычислитель = Неопределено) Экспорт
_РежимОтладки = ирКэш.РежимОтладкиЛкс();
Если _РежимОтладки Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
// ирПлатформа.ВхожденияРегВыражения
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Номер", Новый ОписаниеТипов("Число"));
Результат.Колонки.Добавить("ТекстВхождения", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("ПозицияВхождения", Новый ОписаниеТипов("Число"));
Результат.Колонки.Добавить("ДлинаВхождения", Новый ОписаниеТипов("Число"));
Результат.Колонки.Добавить("Подгруппы");
Если Не ЗначениеЗаполнено(Шаблон) Тогда
Возврат Результат;
КонецЕсли;
Если Вычислитель = Неопределено Тогда
Вычислитель = ирКэш.ВычислительРегВыраженийЛкс();
КонецЕсли;
Если Вычислитель = Неопределено Тогда
ПроверитьПлатформаНеWindowsЛкс();
Возврат Результат;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
Вычислитель = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
Вычислитель.IgnoreCase = ИгнорироватьРегистрБукв;
Вычислитель.Global = ИскатьВсеВхождения;
Вычислитель.Multiline = МногострочныйРежим;
Вычислитель.Pattern = Шаблон;
Попытка
Вхождения = Вычислитель.НайтиВхождения(Текст);
Исключение
Если Не ВызыватьИсключение Тогда
Возврат ОписаниеОшибки();
Иначе
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
#Если Сервер И Не Сервер Тогда
Результат = Обработки.ирПлатформа.Создать().ВхожденияРегВыражения;
#КонецЕсли
ИндексПервойКолонкиПодгруппы = Результат.Колонки.Количество();
Если Не БезПодгрупп Тогда
ИменаПодгруппМассив = СтрРазделитьЛкс(ИменаПодгрупп, ",", Истина, Ложь);
Для Каждого ИмяПодгруппы Из ИменаПодгруппМассив Цикл
Если Результат.Колонки.Найти(ИмяПодгруппы) <> Неопределено Тогда
ВызватьИсключение "Имя """ + ИмяПодгруппы + """ добавляемой колонки подгруппы результатов поиска не уникально";
КонецЕсли;
Результат.Колонки.Добавить(ИмяПодгруппы);
КонецЦикла;
КоличествоИменПодгрупп = ИменаПодгруппМассив.Количество();
КонецЕсли;
ДобавитьКолонкиПодгрупп = КоличествоИменПодгрупп = 0;
Для Каждого Вхождение Из Вхождения Цикл
//Если Результат.Количество() = 0 Тогда
// Для ИндексПодгруппы = ИменаПодгруппМассив.Количество() По Вычислитель.КоличествоПодгрупп(Вхождение) - 1 Цикл
// Результат.Колонки.Добавить("Подгруппа" + XMLСтрока(ИндексПодгруппы));
// КонецЦикла;
//КонецЕсли;
СтрокаРезультата = Результат.Добавить();
СтрокаРезультата.Номер = Результат.Количество();
СтрокаРезультата.ТекстВхождения = Вхождение.Value;
СтрокаРезультата.ПозицияВхождения = Вхождение.FirstIndex;
СтрокаРезультата.ДлинаВхождения = Вхождение.Length;
Если Не БезПодгрупп Тогда
Подгруппы = Новый Массив;
Для ИндексПодгруппы = 0 По Вычислитель.КоличествоПодгрупп(Вхождение) - 1 Цикл
Если ДобавитьКолонкиПодгрупп Тогда
Результат.Колонки.Добавить("Подгруппа" + ИндексПодгруппы);
КоличествоИменПодгрупп = КоличествоИменПодгрупп + 1;
КонецЕсли;
Если ИндексПодгруппы < КоличествоИменПодгрупп Тогда
СтрокаРезультата[ИндексПервойКолонкиПодгруппы + ИндексПодгруппы] = Вхождение.SubMatches(ИндексПодгруппы);
КонецЕсли;
Подгруппы.Добавить(Вхождение.SubMatches(ИндексПодгруппы));
КонецЦикла;
СтрокаРезультата.Подгруппы = Подгруппы;
Если ДобавитьКолонкиПодгрупп Тогда
ДобавитьКолонкиПодгрупп = Ложь;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Результат = Новый ТаблицаЗначений; Результат.Колонки.Добавить("Номер", Новый ОписаниеТипов("Число")); Результат.Колонки.Добавить("ТекстВхождения", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("ПозицияВхождения", Новый ОписаниеТипов("Число")); Результат.Колонки.Добавить("ДлинаВхождения", Новый ОписаниеТипов("Число")); Результат.Колонки.Добавить("Подгруппы"); Если Не ЗначениеЗаполнено(Шаблон) Тогда Возврат Результат; КонецЕсли; Если Вычислитель = Неопределено Тогда Вычислитель = ирКэш.ВычислительРегВыраженийЛкс(); КонецЕсли; Если Вычислитель = Неопределено Тогда ПроверитьПлатформаНеWindowsЛкс(); Возврат Результат; КонецЕсли; Если Ложь Тогда Вычислитель = Обработки.ирОболочкаРегВыражение.Создать(); КонецЕсли; Вычислитель.IgnoreCase = ИгнорироватьРегистрБукв; Вычислитель.Global = ИскатьВсеВхождения; Вычислитель.Multiline = МногострочныйРежим; Вычислитель.Pattern = Шаблон; Попытка Вхождения = Вычислитель.НайтиВхождения(Текст); Исключение Если Не ВызыватьИсключение Тогда Возврат ОписаниеОшибки(); Иначе ВызватьИсключение; КонецЕсли; КонецПопытки; Если Ложь Тогда Результат = Обработки.ирПлатформа.Создать().ВхожденияРегВыражения; КонецЕсли; ИндексПервойКолонкиПодгруппы = Результат.Колонки.Количество(); Если Не БезПодгрупп Тогда ИменаПодгруппМассив = СтрРазделитьЛкс(ИменаПодгрупп, ",", Истина, Ложь); Для Каждого ИмяПодгруппы Из ИменаПодгруппМассив Цикл Если Результат.Колонки.Найти(ИмяПодгруппы) <> Неопределено Тогда ВызватьИсключение "Имя """ + ИмяПодгруппы + """ добавляемой колонки подгруппы результатов поиска не уникально"; КонецЕсли; Результат.Колонки.Добавить(ИмяПодгруппы); КонецЦикла; КоличествоИменПодгрупп = ИменаПодгруппМассив.Количество(); КонецЕсли; ДобавитьКолонкиПодгрупп = КоличествоИменПодгрупп = 0; Для Каждого Вхождение Из Вхождения Цикл СтрокаРезультата = Результат.Добавить(); СтрокаРезультата.Номер = Результат.Количество(); СтрокаРезультата.ТекстВхождения = Вхождение.Value; СтрокаРезультата.ПозицияВхождения = Вхождение.FirstIndex; СтрокаРезультата.ДлинаВхождения = Вхождение.Length; Если Не БезПодгрупп Тогда Подгруппы = Новый Массив; Для ИндексПодгруппы = 0 По Вычислитель.КоличествоПодгрупп(Вхождение) - 1 Цикл Если ДобавитьКолонкиПодгрупп Тогда Результат.Колонки.Добавить("Подгруппа" + ИндексПодгруппы); КоличествоИменПодгрупп = КоличествоИменПодгрупп + 1; КонецЕсли; Если ИндексПодгруппы < КоличествоИменПодгрупп Тогда СтрокаРезультата[ИндексПервойКолонкиПодгруппы + ИндексПодгруппы] = Вхождение.SubMatches(ИндексПодгруппы); КонецЕсли; Подгруппы.Добавить(Вхождение.SubMatches(ИндексПодгруппы)); КонецЦикла; СтрокаРезультата.Подгруппы = Подгруппы; Если ДобавитьКолонкиПодгрупп Тогда ДобавитьКолонкиПодгрупп = Ложь; КонецЕсли; КонецЕсли; КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НовыйВычислительРегВыражений() Экспорт
Результат = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирОболочкаРегВыражение");
#Если Сервер И Не Сервер Тогда
Результат = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
Возврат Результат;
КонецФункции
// Преобразует строку для правого операнда оператора ПОДОБНО языка запросов.
//
// Параметры:
// пТекст - Строка.
//
// Возвращаемое значение:
// Строка.
//
Функция ПреобразоватьСтрокуДляПОДОБНОЛкс(Знач Результат, Спецсимвол = "~") Экспорт
ЗарезервированныеСимволы = Новый Массив;
ЗарезервированныеСимволы.Добавить("~");
//ЗарезервированныеСимволы.Добавить("%");
ЗарезервированныеСимволы.Добавить("_");
ЗарезервированныеСимволы.Добавить("[");
ЗарезервированныеСимволы.Добавить("-");
ЗарезервированныеСимволы.Добавить("]");
Для Каждого ЗарезервированныйСимвол Из ЗарезервированныеСимволы Цикл
Результат = СтрЗаменить(Результат, ЗарезервированныйСимвол, Спецсимвол + ЗарезервированныйСимвол);
КонецЦикла;
Возврат Результат;
КонецФункции // ПреобразоватьСтрокуДляПОДОБНОЛкс()
// Обновляет в строковом свойстве объекта часть, которая следует за маркером.
// Если маркер не находится, то он добавляется.
//
// Параметры:
// пОбъект - Объект, Строка - объект, строковое свойство которого будем обновлять, или само свойство по ссылке;
// *пИмяСвойства - Строка, *"" - имя строкового Свойства объекта, указывается в случае, если свойство не передается по ссылке;
// пНовыйТекст - Строка - новая часть, которая следует за разделителем;
// *пМаркер - Строка, *"," - маркер.
//
Процедура ОбновитьТекстПослеМаркераВСтрокеЛкс(пОбъектИлиСвойство, Знач пИмяСвойства = "", Знач НовыйТекст, Знач пМаркер = ", ", Знач ОбрезатьПосле = 100) Экспорт
Если пИмяСвойства <> "" Тогда
СтараяСтрока = пОбъектИлиСвойство[пИмяСвойства];
Иначе
СтараяСтрока = пОбъектИлиСвойство;
КонецЕсли;
ПозицияРазделителя = Найти(СтараяСтрока, пМаркер);
Если ПозицияРазделителя = 0 Тогда
ПозицияРазделителя = СтрДлина(СтараяСтрока) + 1;
КонецЕсли;
Если ЗначениеЗаполнено(ОбрезатьПосле) Тогда
НовыйТекст = ПредставлениеЗначенияСОграничениемДлиныЛкс(НовыйТекст, ОбрезатьПосле);
КонецЕсли;
НоваяСтрока = Лев(СтараяСтрока, ПозицияРазделителя - 1) + пМаркер + НовыйТекст;
Если пИмяСвойства <> "" Тогда
ПрисвоитьЕслиНеРавноЛкс(пОбъектИлиСвойство[пИмяСвойства], НоваяСтрока);
Иначе
ПрисвоитьЕслиНеРавноЛкс(пОбъектИлиСвойство, НоваяСтрока);
КонецЕсли;
КонецПроцедуры
// Результат - Строка - длинна не более ПорогДлины
Функция ПредставлениеЗначенияСОграничениемДлиныЛкс(Знач Значение, Знач ПорогДлины = 100, МаркерОтрезки = "…") Экспорт
ПредставлениеЗначения = "" + Значение;
Если СтрДлина(ПредставлениеЗначения) > ПорогДлины Тогда
ПредставлениеЗначения = Лев(ПредставлениеЗначения, ПорогДлины - СтрДлина(МаркерОтрезки)) + МаркерОтрезки;
КонецЕсли;
Возврат ПредставлениеЗначения;
КонецФункции
// Взято отсюда http://infostart.ru/public/100845/
// ИсходныеДанные - <примитивное значение>, ДвоичныеДанные, ХранилищеЗначения
//
// Возвращаемое значение
// Число
Функция ВычислитьХэшЛкс(ИсходныеДанные, Хэш=5381, М=33, Разрядность=18446744073709551616) Экспорт
// приведем к строке
Если ТипЗнч(ИсходныеДанные) = Тип("ДвоичныеДанные") Тогда
СтрокаДляКодирования = Base64Строка(ИсходныеДанные);
ИначеЕсли ТипЗнч(ИсходныеДанные) = Тип("ХранилищеЗначения") Тогда
СтрокаДляКодирования = ЗначениеВСтрокуВнутр(ИсходныеДанные);
Иначе
СтрокаДляКодирования = Строка(ИсходныеДанные);
КонецЕсли;
ДлинаБлока = 11;
НачПозиция = 1;
ДлинаСтроки = СтрДлина(СтрокаДляКодирования);
Пока НачПозиция <= ДлинаСтроки Цикл
СтрокаБлока = Сред(СтрокаДляКодирования, НачПозиция, ДлинаБлока);
ДлинаПодстроки = СтрДлина(СтрокаБлока);
Если ДлинаПодстроки = ДлинаБлока Тогда
Хэш = ((((((((((( Хэш*М + КодСимвола(СтрокаБлока, 1))*М + КодСимвола(СтрокаБлока, 2))*М
+ КодСимвола(СтрокаБлока, 3))*М + КодСимвола(СтрокаБлока, 4))*М + КодСимвола(СтрокаБлока, 5))*М
+ КодСимвола(СтрокаБлока, 6))*М + КодСимвола(СтрокаБлока, 7))*М + КодСимвола(СтрокаБлока, 8))*М
+ КодСимвола(СтрокаБлока, 9))*М + КодСимвола(СтрокаБлока, 10))*М + КодСимвола(СтрокаБлока, 11))
Иначе
Для к = 1 По ДлинаПодстроки Цикл
Хэш = М * Хэш + КодСимвола(СтрокаБлока, к)
КонецЦикла
КонецЕсли;
Хэш = Хэш % Разрядность;
НачПозиция = НачПозиция + ДлинаБлока
КонецЦикла;
Возврат Хэш;
КонецФункции
Функция ПолучитьГУИДИнверсныйИзПрямогоЛкс(ПрямойГУИД) Экспорт
С = СтрЗаменить(ПрямойГУИД, "-", "");
Возврат Сред(С,17,16)+Сред(С,13,4)+Сред(С,9,4)+Сред(С,1,4)+Сред(С,5,4);
КонецФункции
Функция ПолучитьГУИДПрямойИзИнверсногоЛкс(ИнверсныйГУИД) Экспорт
С = ИнверсныйГУИД;
Возврат Сред(С,25,8)+"-"+Сред(С,21,4)+"-"+Сред(С,17,4)+"-"+Сред(С,1,4)+"-"+Сред(С,5,12);
КонецФункции
Функция ОписаниеТиповПланОбменаСсылкаЛкс(ВключаяТипыРасширений = Истина) Экспорт
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(
"
";
МаркерКонецПодгруппы = "";
Результат = Новый ЗаписьXML;
Результат.УстановитьСтроку("");
Старт = Истина;
Финиш = 0;
ЗначениеЧередования = Ложь;
МаксРаскашиваемыхВхождений = 1000;
//МассивЦветов = Новый Массив;
//МассивЦветов.Добавить("yellow");
//МассивЦветов.Добавить("cyan");
//МассивЦветов.Добавить("#CCFF66"); // светло-зеленый
//МассивЦветов.Добавить("orange");
РаскрашеноВхождений = 0;
Для каждого Группа Из ВхожденияГруппы Цикл
Если Группа.ПозицияПодгруппы = Неопределено Или РаскрашеноВхождений > МаксРаскашиваемыхВхождений Тогда
Продолжить;
КонецЕсли;
Если ИндексПодгруппы = -1 Тогда
ТекстПодгруппы = Группа.Значение;
Иначе
ТекстПодгруппы = Группа.Подгруппы[ИндексПодгруппы].Значение;
КонецЕсли;
Если ТекстПодгруппы = Неопределено Тогда
Продолжить;
КонецЕсли;
ПозицияПодгруппы = Группа.ПозицияПодгруппы;
ДлинаПодгруппы = Группа.ДлинаПодгруппы;
Если Старт Тогда
Если Группа.ПозицияПодгруппы <> 0 Тогда
Результат.ЗаписатьБезОбработки(ирОбщий.КодироватьТекстВXMLЛкс(Сред(Текст, 1, ПозицияПодгруппы)));
КонецЕсли;
Старт = Ложь;
ИначеЕсли Финиш <> 0 Тогда
Результат.ЗаписатьБезОбработки(ирОбщий.КодироватьТекстВXMLЛкс(Сред(Текст, Финиш, ПозицияПодгруппы - Финиш + 1)));
КонецЕсли;
ЗначениеПодгруппы = ирОбщий.КодироватьТекстВXMLЛкс(ТекстПодгруппы);
Если ЗначениеЧередования Тогда
ИмяЦвета = "cyan";
Иначе
ИмяЦвета = "yellow";
КонецЕсли;
НачальнаяМеткаSPAN = "";
Результат.ЗаписатьБезОбработки(НачальнаяМеткаSPAN + ЗначениеПодгруппы + "");
РаскрашеноВхождений = РаскрашеноВхождений + 1;
Финиш = ПозицияПодгруппы + ДлинаПодгруппы + 1;
ЗначениеЧередования = Не ЗначениеЧередования;
КонецЦикла;
Результат.ЗаписатьБезОбработки(ирОбщий.КодироватьТекстВXMLЛкс(Сред(Текст, Финиш)));
Результат = Результат.Закрыть();
РаскрашенныйТекст = "" + РаскрашенныйТекст + Результат + "";
Возврат РаскрашенныйТекст;
КонецФункции
Функция ИдентификаторПодгруппыВРазмеченномТекстеЛкс(Знач НомерГруппы, Знач ИндексПодгруппы = Неопределено) Экспорт
Если ИндексПодгруппы < 0 Тогда
ИндексПодгруппы = "";
Иначе
ИндексПодгруппы = XMLСтрока(ИндексПодгруппы);
КонецЕсли;
Возврат "Match" + НомерГруппы + "_SubMatch" + ИндексПодгруппы;
КонецФункции
Процедура ВыделитьГруппуВДокументеHTMLЛкс(Знач ПолеДокументаHTML, Знач ВыбраннаяГруппа, Знач ИндексПодгруппы = -1) Экспорт
ДокументHtml = ПолеДокументаHTML.Документ;
ИДНужныйУзел = ИдентификаторПодгруппыВРазмеченномТекстеЛкс(ВыбраннаяГруппа.Номер, ИндексПодгруппы);
ТегГруппы = Неопределено;
//ТегГруппы = ДокументHtml.getElementByID(ИДНужныйУзел); // начиная с 8.3.14 так не работает
ТегГруппы = ДокументHtml.querySelector("[id = " + ИДНужныйУзел + "]");
ТелоДокумента = ДокументHtml.body;
Если ТегГруппы <> Неопределено Тогда
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803014 Тогда
ВыделениеВТексте = Новый Структура;
ВыделениеВТексте.Вставить("Начало", 0);
ВыделениеВТексте.Вставить("НачалоБезПереносов", 0);
ВыделениеВТексте.Вставить("Конец", ВыбраннаяГруппа.Длина);
ВыделениеВТексте.Вставить("КонецБезПереносов", 0);
УстановитьВыделениеВДокументеHTMLЛкс(ПолеДокументаHTML, ВыделениеВТексте, ТегГруппы);
Иначе
Диапазон = ТелоДокумента.createTextRange();
Диапазон.moveToElementText(ТегГруппы);
Диапазон.scrollIntoView();
Диапазон.Select();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьВыделениеВДокументеHTMLЛкс(Знач ПолеДокументаHTML) Экспорт
ВыделениеВТексте = Новый Структура;
ДокументHtml = ПолеДокументаHTML.Документ;
ТелоДокумента = ДокументHtml.body;
Если ирКэш.НомерВерсииПлатформыЛкс() < 803014 Тогда
ТекущееВыделение = ДокументHtml.Selection.createRange();
Диапазон = ТелоДокумента.createTextRange();
Диапазон.setEndPoint("EndToStart", ТекущееВыделение);
ВыделениеВТексте.Вставить("Начало", СтрДлина(Диапазон.Text));
ВыделениеВТексте.Вставить("НачалоБезПереносов", СтрДлина(СтрЗаменить(Диапазон.Text, Символы.ПС, "")));
Диапазон.setEndPoint("EndToEnd", ТекущееВыделение);
ВыделениеВТексте.Вставить("Конец", СтрДлина(Диапазон.Text));
ВыделениеВТексте.Вставить("КонецБезПереносов", СтрДлина(СтрЗаменить(Диапазон.Text, Символы.ПС, "")));
Иначе
//ТекущееВыделение = ДокументHtml.window.getSelection();
ТекущееВыделение = ДокументHtml.getSelection();
Начало = 0;
НачалоБезПереносов = 0;
Конец = 0;
КонецБезПереносов = 0;
Если ТекущееВыделение <> Неопределено Тогда
//ВыделенныйТекст = Диапазон.toString(); // Для отладки
ТекстовыеУзлы = ТекстовыеУзлыHTMLВнутриЛкс(ТелоДокумента);
НачалоНайдено = Ложь;
ОбратныйПорядок = Ложь;
СчетчикСимволов = 0;
СчетчикСимволовБезПереносов = 0;
Для Каждого ТекстовыйУзел из ТекстовыеУзлы Цикл
Если Не НачалоНайдено Тогда
Если ТекстовыйУзел = ТекущееВыделение.anchorNode Тогда
НачалоБезПереносов = СчетчикСимволовБезПереносов + ТекущееВыделение.anchorOffset;
Начало = СчетчикСимволов + ТекущееВыделение.anchorOffset;
НачалоНайдено = Истина;
ИначеЕсли ТекстовыйУзел = ТекущееВыделение.focusNode Тогда
НачалоБезПереносов = СчетчикСимволовБезПереносов + ТекущееВыделение.focusOffset;
Начало = СчетчикСимволов + ТекущееВыделение.focusOffset;
НачалоНайдено = Истина;
ОбратныйПорядок = Истина;
КонецЕсли;
КонецЕсли;
Если НачалоНайдено Тогда
Если ОбратныйПорядок И ТекстовыйУзел = ТекущееВыделение.anchorNode Тогда
КонецБезПереносов = СчетчикСимволовБезПереносов + ТекущееВыделение.anchorOffset;
Конец = СчетчикСимволов + ТекущееВыделение.anchorOffset;
Прервать;
ИначеЕсли Не ОбратныйПорядок И ТекстовыйУзел = ТекущееВыделение.focusNode Тогда
КонецБезПереносов = СчетчикСимволовБезПереносов + ТекущееВыделение.focusOffset;
Конец = СчетчикСимволов + ТекущееВыделение.focusOffset;
Прервать;
КонецЕсли;
КонецЕсли;
СчетчикСимволов = СчетчикСимволов + СтрДлина(ТекстовыйУзел.textContent);
СчетчикСимволовБезПереносов = СчетчикСимволовБезПереносов + СтрДлина(СтрЗаменить(ТекстовыйУзел.data, Символы.ПС, ""));
КонецЦикла;
КонецЕсли;
ВыделениеВТексте.Вставить("Начало", Начало);
ВыделениеВТексте.Вставить("НачалоБезПереносов", НачалоБезПереносов);
ВыделениеВТексте.Вставить("Конец", Конец);
ВыделениеВТексте.Вставить("КонецБезПереносов", КонецБезПереносов);
КонецЕсли;
Возврат ВыделениеВТексте;
КонецФункции
Процедура УстановитьВыделениеВДокументеHTMLЛкс(Знач ПолеДокументаHTML, Знач ВыделениеВТексте, РодительскийУзел = Неопределено) Экспорт
ДокументHtml = ПолеДокументаHTML.Документ;
ТелоДокумента = ДокументHtml.body;
Если РодительскийУзел = Неопределено Тогда
РодительскийУзел = ТелоДокумента;
КонецЕсли;
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803014 Тогда
//ВыделенныйТекст = Диапазон.toString(); // Для отладки
РодительскийУзел.scrollIntoViewIfNeeded();
Диапазон = ДокументHtml.createRange();
Диапазон.selectNodeContents(РодительскийУзел);
ТекстовыеУзлы = ТекстовыеУзлыHTMLВнутриЛкс(РодительскийУзел);
НачалоНайдено = Ложь;
СчетчикСимволов = 0;
СчетчикУзлов = 0;
Для Каждого ТекстовыйУзел Из ТекстовыеУзлы Цикл
endCharCount = СчетчикСимволов + СтрДлина(ТекстовыйУзел.data);
Если Истина
И Не НачалоНайдено
И ВыделениеВТексте.Начало >= СчетчикСимволов
И (Ложь
Или ВыделениеВТексте.Начало < endCharCount
Или (ВыделениеВТексте.Начало = endCharCount И СчетчикУзлов <= ТекстовыеУзлы.Количество()))
Тогда
Диапазон.setStart(ТекстовыйУзел, ВыделениеВТексте.Начало - СчетчикСимволов);
НачалоНайдено = Истина;
КонецЕсли;
Если НачалоНайдено И ВыделениеВТексте.Конец <= endCharCount Тогда
Диапазон.setEnd(ТекстовыйУзел, ВыделениеВТексте.Конец - СчетчикСимволов);
Прервать;
КонецЕсли;
СчетчикСимволов = endCharCount;
СчетчикУзлов = СчетчикУзлов + 1;
КонецЦикла;
ТекущееВыделение = ДокументHtml.getSelection();
ТекущееВыделение.removeAllRanges();
ТекущееВыделение.addRange(Диапазон);
Иначе
Диапазон = РодительскийУзел.createTextRange();
Диапазон.Collapse();
Диапазон.moveStart("character", ВыделениеВТексте.НачалоБезПереносов);
Диапазон.moveEnd("character", ВыделениеВТексте.КонецБезПереносов - ВыделениеВТексте.НачалоБезПереносов);
Диапазон.select();
КонецЕсли;
КонецПроцедуры
Функция ТекстовыеУзлыHTMLВнутриЛкс(Узел, ТекстовыеУзлы = Неопределено) Экспорт
Если ТекстовыеУзлы = Неопределено Тогда
ТекстовыеУзлы = Новый Массив;
КонецЕсли;
Если Узел.nodeType = 3 Тогда
ТекстовыеУзлы.Добавить(Узел);
Иначе
Потомки = Узел.childNodes;
Для Каждого Потомок Из Потомки Цикл
ТекстовыеУзлыHTMLВнутриЛкс(Потомок, ТекстовыеУзлы);
КонецЦикла;
КонецЕсли;
Возврат ТекстовыеУзлы;
КонецФункции
Функция ТекстИзПоляДокументаHTMLЛкс(Знач ПолеДокументаHTML) Экспорт
Если ирКэш.НомерВерсииПлатформыЛкс() < 803014 Тогда
Текст = ПолеДокументаHTML.ПолучитьТекст();
ДокументHtml = ПолучитьHtmlFileИзТекстаHtmlЛкс(Текст); // Тут переносы строк другое количество символов дают. Скорее всего из-за Символы.ВК
Иначе
ДокументHtml = ПолеДокументаHTML.Документ;
КонецЕсли;
Текст = ДокументHtml.body.textContent;
Возврат Текст;
КонецФункции
Процедура ПолеТекстаУстановитьВставитьТекстИПереносСтрокиЛкс(Знач ПолеТекста, Знач НовыйТекст) Экспорт
ПолеТекста = ОболочкаПоляТекстаЛкс(ПолеТекста);
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
НачальнаяПозиция = 0;
КонечнаяПозиция = 0;
ПолеТекста.ПолучитьГраницыВыделения(НачальнаяПозиция, КонечнаяПозиция, НачальнаяПозиция, КонечнаяПозиция);
ПолеТекста.ВыделенныйТекст(НовыйТекст);
// Антибаг 8.3.12 https://partners.v8.1c.ru/forum/t/1719342/m/1719342, http://www.hostedredmine.com/issues/882423
ПолеТекста.ВыделенныйТекст(Символы.ПС);
ПолеТекста.УстановитьГраницыВыделения(НачальнаяПозиция, КонечнаяПозиция, НачальнаяПозиция, КонечнаяПозиция);
КонецПроцедуры
Функция ШаблонПоискаСловаЛкс(Знач СтрокаПоиска, СловоЦеликом = Истина) Экспорт
Шаблон = ПреобразоватьТекстДляРегулярныхВыраженийЛкс(СтрокаПоиска);
Если СловоЦеликом Тогда
Шаблон = "(^|[^_a-zа-яё0-9])(" + Шаблон + ")($|[^_a-zа-яё0-9])";
КонецЕсли;
Возврат Шаблон;
КонецФункции
// Параметры:
// Элемент - ПолеТабличногоДокумента
//
Функция ПолеТабличногоДокумента_ПолучитьПредставлениеСуммыВыделенныхЯчеекЛкс(Знач Элемент) Экспорт
Сумма = 0;
СчетчикЯчеекСуммы = 0;
СчетчикЯчеекОбщий = 0;
ВыделенныеОбласти = Элемент.ВыделенныеОбласти;
ЕстьИгнорированныеОбласти = Ложь;
НачальноеКоличество = ВыделенныеОбласти.Количество();
Для СчетчикВыделенныеОбласти = 1 По НачальноеКоличество Цикл
Область = ВыделенныеОбласти[НачальноеКоличество - СчетчикВыделенныеОбласти];
Если ТипЗнч(Область) = Тип("РисунокТабличногоДокумента") Тогда
Продолжить;
КонецЕсли;
ПлощадьОбласти = (Область.Право - Область.Лево + 1) * (Область.Низ - Область.Верх + 1);
СчетчикЯчеекОбщий = СчетчикЯчеекОбщий + ПлощадьОбласти;
Если ПлощадьОбласти < 10000 Тогда
Для НомерКолонки = Область.Лево по Область.Право Цикл
Для НомерСтроки = Область.Верх по Область.Низ Цикл
ОбластьЯчейки = Элемент.Область(НомерСтроки, НомерКолонки);
Если ОбластьЯчейки.Лево <> НомерКолонки Или ОбластьЯчейки.Верх <> НомерСтроки Тогда
// Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой
Продолжить;
КонецЕсли;
Попытка
Число = Число(ОбластьЯчейки.Текст);
Исключение
Продолжить;
КонецПопытки;
Сумма = Сумма + Число;
СчетчикЯчеекСуммы = СчетчикЯчеекСуммы + 1;
КонецЦикла;
КонецЦикла;
Иначе
ЕстьИгнорированныеОбласти = Истина;
КонецЕсли;
КонецЦикла;
СчетчикЯчеекСуммы = "" + СчетчикЯчеекСуммы;
Сумма = "" + Сумма;
Если ЕстьИгнорированныеОбласти Тогда
СчетчикЯчеекСуммы = СчетчикЯчеекСуммы + "+?";
Сумма = Сумма + "+?";
КонецЕсли;
Текст = "" + СчетчикЯчеекСуммы + " из " + СчетчикЯчеекОбщий + " яч. = " + Сумма + "";
Возврат Текст;
КонецФункции
//
// Параметры:
// Таблица - ТаблицаЗначений - может быть модифицирована здесь, поэтому нужно передавать копию, если нужна неизменность
Функция ВывестиТаблицуВТабличныйДокументИлиТаблицуЗначенийЛкс(ТаблицаЗначений, Знач Приемник = Неопределено, ДанныеРасшифровки = Неопределено, ИтогиЧисловыхКолонок = Истина,
АвтофиксацияШапки = Истина, ВстроитьЗначенияВРасшифровки = Истина, ОтображатьПустые = Ложь, ДобавлятьКолонкиИдентификаторов = Ложь, ДобавлятьКолонкиТипов = Ложь,
ДобавлятьКолонкиПредставлений = Истина, Знач ВыбранныеКолонки = Неопределено, ИмяТекущейКолонки = "", ВыводВТаблицуЗначений = Ложь, Отладка = Ложь, ДобавлятьКолонкиРазмеров = Ложь,
СузитьТипы = Ложь, Иерархия = Ложь) Экспорт
ТребоватьТипЛкс(ТаблицаЗначений,, Тип("ТаблицаЗначений"));
ирПлатформа = ирКэш.Получить();
Если ДобавлятьКолонкиТипов Или ДобавлятьКолонкиИдентификаторов Тогда
//ТаблицаЗначений = ТаблицаСКолонкамиБезТипаNullЛкс(ТаблицаЗначений);
ТаблицаЗначений = СузитьТипыКолонокТаблицыБезПотериДанныхЛкс(ТаблицаЗначений);
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ирПлатформа = Обработки.ирПлатформа.Создать();
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
ВнешниеНаборыДанных = Новый Структура("Основной", ТаблицаЗначений);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
КолонкиИдентификаторов = Новый Массив;
КолонкиТипов = Новый Массив;
КолонкиРазмеров = Новый Массив;
Если ВыбранныеКолонки = Неопределено Тогда
ВыбранныеКолонки = Новый Массив;
Для Каждого Колонка Из КолонкиИсточникаДанныхЛкс(ТаблицаЗначений) Цикл
ВыбранныеКолонки.Добавить(Колонка.Имя);
КонецЦикла;
КонецЕсли;
ИменаТипов = Новый Структура;
ПозицииКолонок = Новый Структура;
ИндексТекущейКолонки = 0;
ОформлениеКолонокИдентификаторов = НастройкаКомпоновки.УсловноеОформление.Элементы.Добавить();
ОформлениеКолонокИдентификаторов.Оформление.УстановитьЗначениеПараметра("МаксимальнаяШирина", 2);
ОформлениеКолонокИдентификаторов.Оформление.УстановитьЗначениеПараметра("Размещение", ТипРазмещенияТекстаКомпоновкиДанных.Обрезать);
Для Каждого ВыбраннаяКолонка Из ВыбранныеКолонки Цикл
Если Не ЗначениеЗаполнено(ВыбраннаяКолонка) Тогда
Продолжить;
КонецЕсли;
ИмяКолонки = СтрЗаменить(ВыбраннаяКолонка, ".", "_");
Колонка = ТаблицаЗначений.Колонки.Найти(ИмяКолонки);
Если Колонка = Неопределено Тогда
// Например "ИдентификаторСсылкиЛкс" в таблице формы
Продолжить;
КонецЕсли;
ТипЗначения = Колонка.ТипЗначения;
ТипыКолонки = ТипЗначения.Типы();
ЛиТипПростойСтроковый = ЛиОписаниеТиповПростогоСтроковогоТипаЛкс(ТипЗначения);
ПозицииКолонок.Вставить(Колонка.Имя, НастройкаКомпоновки.Выбор.Элементы.Количество());
Если ДобавлятьКолонкиПредставлений Или ЛиТипПростойСтроковый Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ВыбраннаяКолонка);
КонецЕсли;
Если Ложь
Или ОтображатьПустые
Или (Истина
И ДобавлятьКолонкиТипов
И ТипыКолонки.Количество() > 1)
Тогда
КолонкиТипов.Добавить(Колонка.Имя);
ТаблицаЗначений.Колонки.Вставить(ТаблицаЗначений.Колонки.Индекс(Колонка) + 1, ИмяКолонки + "_ИмяТипаЗначения_", Новый ОписаниеТипов("Строка"),
Колонка.Заголовок + " (тип)");
Если ДобавлятьКолонкиТипов Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ИмяКолонки + "_ИмяТипаЗначения_");
КонецЕсли;
ИменаТиповКолонки = Новый Соответствие;
Для Каждого Тип Из ТипыКолонки Цикл
ИменаТиповКолонки.Вставить(Тип, ПредставлениеТипаЛкс(Тип, ТипЗначения, Истина));
КонецЦикла;
ИменаТипов.Вставить(Колонка.Имя, ИменаТиповКолонки);
КонецЕсли;
Если ДобавлятьКолонкиИдентификаторов Тогда
//ЕстьСсылочныйТип = ТипыКолонки.Количество() = 0;
//Если Не ЕстьСсылочныйТип Тогда
// Для Каждого Тип Из ТипыКолонки Цикл
// Если ЛиТипСсылкиБДЛкс(Тип, Ложь) Тогда
// ЕстьСсылочныйТип = Истина;
// Прервать;
// КонецЕсли;
// КонецЦикла;
//КонецЕсли;
Если Ложь
//Или ЕстьСсылочныйТип
Или Не (ЛиТипПростойСтроковый)
Тогда
Если ИндексТекущейКолонки = 0 И ЗначениеЗаполнено(ИмяТекущейКолонки) И СтрокиРавныЛкс(ВыбраннаяКолонка, ИмяТекущейКолонки) Тогда
ИндексТекущейКолонки = НастройкаКомпоновки.Выбор.Элементы.Количество();
КонецЕсли;
КолонкиИдентификаторов.Добавить(Колонка.Имя);
ИмяКолонкиИдентификатора = ИмяКолонки + "_ИдентификаторЗначения_";
ТаблицаЗначений.Колонки.Вставить(ТаблицаЗначений.Колонки.Индекс(Колонка) + 1, ИмяКолонкиИдентификатора, Новый ОписаниеТипов("Строка"),
Колонка.Заголовок + " (идентификатор)");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ИмяКолонкиИдентификатора);
Если ДобавлятьКолонкиПредставлений Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ОформлениеКолонокИдентификаторов.Поля, ИмяКолонкиИдентификатора);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ДобавлятьКолонкиРазмеров Тогда
Если Ложь
Или ТипЗначения.СодержитТип(Тип("ХранилищеЗначения"))
Или (Истина
И ТипЗначения.СодержитТип(Тип("Строка"))
И ТипЗначения.КвалификаторыСтроки.ДопустимаяДлина = 0)
Тогда
Если ИндексТекущейКолонки = 0 И ЗначениеЗаполнено(ИмяТекущейКолонки) И СтрокиРавныЛкс(ВыбраннаяКолонка, ИмяТекущейКолонки) Тогда
ИндексТекущейКолонки = НастройкаКомпоновки.Выбор.Элементы.Количество();
КонецЕсли;
КолонкиРазмеров.Добавить(Колонка.Имя);
ТаблицаЗначений.Колонки.Вставить(ТаблицаЗначений.Колонки.Индекс(Колонка) + 1, ИмяКолонки + "_РазмерЗначения_", Новый ОписаниеТипов("Число"),
Колонка.Заголовок + " (размер)");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ИмяКолонки + "_РазмерЗначения_");
КонецЕсли;
КонецЕсли;
Если ОтображатьПустые Тогда
ПустыеЗначения = Новый Массив;
ПустыеЗначения.Добавить(Неопределено);
ПустыеЗначения.Добавить(0);
ПустыеЗначения.Добавить(Дата(1,1,1));
ПустыеЗначения.Добавить(Ложь);
ПустыеЗначения.Добавить("");
Для Каждого ПустоеЗначение Из ПустыеЗначения Цикл
Если Ложь
Или ТипЗначения.Типы().Количество() = 0
Или ТипЗначения.СодержитТип(ТипЗнч(ПустоеЗначение))
Тогда
ЭлементУсловногоОформления = НастройкаКомпоновки.УсловноеОформление.Элементы.Добавить();
ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("Текст", ирПлатформа.ПредставлениеПустогоЗначенияЛкс(ПустоеЗначение));
//ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", ЦветФонаЯчеекПустыхЗначенийЛкс());
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ВыбраннаяКолонка, , ВидСравненияКомпоновкиДанных.НеЗаполнено);
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ВыбраннаяКолонка, ПустоеЗначение, ВидСравненияКомпоновкиДанных.Равно);
ПолеЭлементаОформления = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
ПолеЭлементаОформления.Поле = Новый ПолеКомпоновкиДанных(ВыбраннаяКолонка);
КонецЕсли;
КонецЦикла;
// Отдельно для особенного Null
ПустоеЗначение = Null;
Если Истина
И ТипЗначения.Типы().Количество() > 0
И ТипЗначения.СодержитТип(ТипЗнч(ПустоеЗначение))
Тогда
ЭлементУсловногоОформления = НастройкаКомпоновки.УсловноеОформление.Элементы.Добавить();
ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("Текст", ирПлатформа.ПредставлениеПустогоЗначенияЛкс(ПустоеЗначение));
//ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", ЦветФонаЯчеекПустыхЗначенийЛкс());
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ИмяКолонки + "_ИмяТипаЗначения_", "Null", ВидСравненияКомпоновкиДанных.Равно);
ПолеЭлементаОформления = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
ПолеЭлементаОформления.Поле = Новый ПолеКомпоновкиДанных(ВыбраннаяКолонка);
КонецЕсли;
КонецЕсли;
КонецЦикла;
ОформлениеКолонокИдентификаторов.Использование = ОформлениеКолонокИдентификаторов.Поля.Элементы.Количество() > 0;
Если Ложь
Или КолонкиТипов.Количество() > 0
Или КолонкиИдентификаторов.Количество() > 0
Или КолонкиРазмеров.Количество() > 0
Тогда
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаЗначений.Количество(), "Заполнение доп. колонок");
Для Каждого СтрокаТаблицы Из ТаблицаЗначений Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор); // добавляет значительную долю длительности цикла
Если ирКэш.РежимОтладкиЛкс() Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого ИмяКолонки Из КолонкиТипов Цикл
Если Ложь
Или ДобавлятьКолонкиТипов
Или СтрокаТаблицы[ИмяКолонки] = Null
Тогда
СтрокаТаблицы[ИмяКолонки + "_ИмяТипаЗначения_"] = ИменаТипов[ИмяКолонки][ТипЗнч(СтрокаТаблицы[ИмяКолонки])];
КонецЕсли;
КонецЦикла;
Если ДобавлятьКолонкиИдентификаторов Тогда
Для Каждого ИмяКолонки Из КолонкиИдентификаторов Цикл
СтрокаТаблицы[ИмяКолонки + "_ИдентификаторЗначения_"] = СтроковыйИдентификаторЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]);
КонецЦикла;
КонецЕсли;
Если ДобавлятьКолонкиРазмеров Тогда
Для Каждого ИмяКолонки Из КолонкиРазмеров Цикл
СтрокаТаблицы[ИмяКолонки + "_РазмерЗначения_"] = РазмерЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]);
КонецЦикла;
КонецЕсли;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Каждого ИмяКолонки Из КолонкиТипов Цикл Если Ложь Или ДобавлятьКолонкиТипов Или СтрокаТаблицы[ИмяКолонки] = Null Тогда СтрокаТаблицы[ИмяКолонки + "_ИмяТипаЗначения_"] = ИменаТипов[ИмяКолонки][ТипЗнч(СтрокаТаблицы[ИмяКолонки])]; КонецЕсли; КонецЦикла; Если ДобавлятьКолонкиИдентификаторов Тогда Для Каждого ИмяКолонки Из КолонкиИдентификаторов Цикл СтрокаТаблицы[ИмяКолонки + "_ИдентификаторЗначения_"] = СтроковыйИдентификаторЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]); КонецЦикла; КонецЕсли; Если ДобавлятьКолонкиРазмеров Тогда Для Каждого ИмяКолонки Из КолонкиРазмеров Цикл СтрокаТаблицы[ИмяКолонки + "_РазмерЗначения_"] = РазмерЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]); КонецЦикла; КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура);
КонецЕсли;
СхемаКомпоновки = СоздатьСхемуПоТаблицамЗначенийЛкс(ВнешниеНаборыДанных, , , ИтогиЧисловыхКолонок);
#Если Сервер И Не Сервер Тогда
СхемаКомпоновки = Новый СхемаКомпоновкиДанных;
#КонецЕсли
Если Иерархия Тогда
СвязьНаборов = СхемаКомпоновки.СвязиНаборовДанных.Добавить();
СвязьНаборов.НаборДанныхИсточник = СхемаКомпоновки.НаборыДанных[0].Имя;
СвязьНаборов.НаборДанныхПриемник = СхемаКомпоновки.НаборыДанных[0].Имя;
СвязьНаборов.ВыражениеИсточник = "_ИДВетки";
СвязьНаборов.ВыражениеПриемник = "_ИДВеткиРодителя";
СвязьНаборов.НачальноеВыражение = "Неопределено"; // вычисляемое значение
КонецЕсли;
Если Отладка Тогда
ОтладитьЛкс(СхемаКомпоновки, , НастройкаКомпоновки, ВнешниеНаборыДанных);
Возврат Неопределено;
КонецЕсли;
Если ВыводВТаблицуЗначений Тогда
Приемник = СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки, Приемник, ВнешниеНаборыДанных,,,,,,, СузитьТипы);
//Приемник = ТаблицаЗначений.Скопировать(, "…");
Иначе
Приемник = СкомпоноватьВТабличныйДокументЛкс(СхемаКомпоновки, НастройкаКомпоновки, Приемник, ВнешниеНаборыДанных, ДанныеРасшифровки, АвтофиксацияШапки,, ВстроитьЗначенияВРасшифровки);
#Если Сервер И Не Сервер Тогда
Приемник = Новый ТабличныйДокумент;
#КонецЕсли
Если ЗначениеЗаполнено(ИмяТекущейКолонки) И ВыбранныеКолонки.Найти(ИмяТекущейКолонки) <> Неопределено Тогда
Приемник.ТекущаяОбласть = Приемник.Область(2, ПозицииКолонок[ИмяТекущейКолонки] + 1);
КонецЕсли;
Для Счетчик = 1 По ВыбранныеКолонки.Количество() Цикл
ИмяКолонки = ВыбранныеКолонки[Счетчик - 1];
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Продолжить;
КонецЕсли;
Колонка = ТаблицаЗначений.Колонки.Найти(ИмяКолонки);
Если Колонка <> Неопределено Тогда
Приемник.Область(1, ПозицииКолонок[ИмяКолонки] + 1).Примечание.Текст = "Типы значений: " + РасширенноеПредставлениеЗначенияЛкс(Колонка.ТипЗначения);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Приемник;
КонецФункции
Функция СкомпоноватьВТабличныйДокументЛкс(СхемаКомпоновки, НастройкаКомпоновки, Знач ТабличныйДокумент = Неопределено, ВнешниеНаборыДанных = Неопределено,
ДанныеРасшифровки = Неопределено, АвтофиксацияШапки = Истина, ПроверятьДоступностьПолей = Ложь, ВстроитьЗначенияПолейВРасшифровки = Ложь, ДобавитьРасшифровкиДляПолейИтогов = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура);
КонецЕсли;
Если ДанныеРасшифровки = Неопределено Тогда
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
КонецЕсли;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = СобратьМакетКомпоновкиЛкс(СхемаКомпоновки, НастройкаКомпоновки, ВнешниеНаборыДанных,,, ПроверятьДоступностьПолей,,, ДанныеРасшифровки,, Тип("ГенераторМакетаКомпоновкиДанных"),
ДобавитьРасшифровкиДляПолейИтогов);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина);
Если ТабличныйДокумент = Неопределено Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
КонецЕсли;
ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(ТабличныйДокумент, ПроцессорКомпоновки, ДанныеРасшифровки.Элементы,,, АвтофиксацияШапки);
Если ВстроитьЗначенияПолейВРасшифровки Тогда
Для НомерСтроки = 1 По ТабличныйДокумент.ВысотаТаблицы Цикл
Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Ячейка = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
ИдентификаторРасшифровки = Ячейка.Расшифровка;
Если ТипЗнч(ИдентификаторРасшифровки) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
ЗначенияПолей = ДанныеРасшифровки.Элементы[ИдентификаторРасшифровки].ПолучитьПоля();
Если Истина
И ЗначенияПолей.Количество() > 0
И ТипЗнч(ЗначенияПолей[0].Значение) <> Тип("Строка")
Тогда
Ячейка.Расшифровка = ЗначенияПолей[0].Значение;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
Возврат ТабличныйДокумент;
КонецФункции
Функция ДополнительныеДействияРасшифровкиКомпоновкиЛкс(Знач ДоступныеДействия, Знач ЭлементРасшифровки, Знач ДополнительныеПунктыМеню = Неопределено, выхКоличествоСсылочныхПолей = 0,
ЗамещатьСтандартные = Ложь, ЗначенияВсехПолей = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ЭлементРасшифровки = Новый ЭлементРасшифровкиКомпоновкиДанныхПоля;
#КонецЕсли
Если ДополнительныеПунктыМеню = Неопределено Тогда
ДополнительныеПунктыМеню = Новый СписокЗначений;
КонецЕсли;
выхКоличествоСсылочныхПолей = 0;
СписокДействийОформить = Новый СписокЗначений;
СписокДействийОтборать = Новый СписокЗначений;
СписокДействийСгруппировать = Новый СписокЗначений;
СписокДействийУпорядочить = Новый СписокЗначений;
СписокДействийГруппировки = Новый СписокЗначений;
ЗначенияПолей = ЭлементРасшифровки.ПолучитьПоля();
Для каждого ЗначениеПоля Из ЗначенияПолей Цикл
ДобавитьДействияРасшифровкиПоПолюЛкс(Истина, ДополнительныеПунктыМеню, ЗначениеПоля, СписокДействийОтборать, СписокДействийОформить, СписокДействийСгруппировать, СписокДействийУпорядочить,
ЭлементРасшифровки, выхКоличествоСсылочныхПолей);
КонецЦикла;
Если ЗначенияВсехПолей = Неопределено Тогда
ЗначенияВсехПолей = Новый Соответствие;
ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(ЭлементРасшифровки,, ЗначенияВсехПолей);
КонецЕсли;
Для Каждого КлючИЗначение Из ЗначенияВсехПолей Цикл
Если ЗначенияПолей.Найти(КлючИЗначение.Ключ) <> Неопределено Тогда
Продолжить;
КонецЕсли;
ЗначениеПоля = Новый Структура("Поле, Значение", КлючИЗначение.Ключ, КлючИЗначение.Значение);
ДобавитьДействияРасшифровкиПоПолюЛкс(Ложь, СписокДействийГруппировки, ЗначениеПоля, СписокДействийОтборать, СписокДействийОформить,, СписокДействийУпорядочить, ЭлементРасшифровки);
КонецЦикла;
Если СписокДействийГруппировки.Количество() > 0 Тогда
ДополнительныеПунктыМеню.Добавить(СписокДействийГруппировки, "Группировки");
КонецЕсли;
Если ЗамещатьСтандартные Тогда
ИндексМассива = ДоступныеДействия.Найти(ДействиеОбработкиРасшифровкиКомпоновкиДанных.Оформить);
Если ИндексМассива <> Неопределено Тогда
ДоступныеДействия.Удалить(ИндексМассива);
ДополнительныеПунктыМеню.Добавить(СписокДействийОформить, "Оформить",, ирКэш.КартинкаПоИмениЛкс("УсловноеОформлениеКомпоновкиДанных"));
КонецЕсли;
ИндексМассива = ДоступныеДействия.Найти(ДействиеОбработкиРасшифровкиКомпоновкиДанных.Отфильтровать);
Если ИндексМассива <> Неопределено Тогда
ДоступныеДействия.Удалить(ИндексМассива);
ДополнительныеПунктыМеню.Добавить(СписокДействийОтборать, "Отфильтровать",, ирКэш.КартинкаПоИмениЛкс("ОтборКомпоновкиДанных"));
КонецЕсли;
//ДополнительныеПунктыМеню.Добавить(СписокДействийСгруппировать, "Сгруппировать"); // Не доделано
ИндексМассива = ДоступныеДействия.Найти(ДействиеОбработкиРасшифровкиКомпоновкиДанных.Упорядочить);
Если ИндексМассива <> Неопределено Тогда
ДоступныеДействия.Удалить(ИндексМассива);
ДополнительныеПунктыМеню.Добавить(СписокДействийУпорядочить, "Упорядочить",, ирКэш.КартинкаПоИмениЛкс("ПорядокКомпоновкиДанных"));
КонецЕсли;
КонецЕсли;
Возврат ДополнительныеПунктыМеню;
КонецФункции
Процедура ДобавитьДействияРасшифровкиПоПолюЛкс(ЛиПрямоеПоле = Истина, Знач СписокДействийОткрыть, Знач ЗначениеПоля, Знач СписокДействийОтборать, Знач СписокДействийОформить,
Знач СписокДействийСгруппировать = Неопределено, Знач СписокДействийУпорядочить = Неопределено, Знач ЭлементРасшифровки, выхКоличествоСсылочныхПолей = 0)
ПорогДлиныПредставления = 100;
ПредставлениеЗначения = ПредставлениеЗначенияСОграничениемДлиныЛкс(РасширенноеПредставлениеЗначенияЛкс(ЗначениеПоля.Значение,,,,, Истина), ПорогДлиныПредставления);
Если ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение) Тогда
СписокДействийОткрыть.Добавить(Новый Структура("Действие, ЗначениеПоля", "ОткрытьЗначение", ЗначениеПоля), "Открыть """ + ЗначениеПоля.Поле + " = " + ПредставлениеЗначения + """",
, ирОбщий.КартинкаТипаЛкс(ТипЗнч(ЗначениеПоля.Значение)));
СписокДействийОткрыть.Добавить(Новый Структура("Действие, ЗначениеПоля", "ОткрытьВРедактореОбъектаБД", ЗначениеПоля), "Открыть """ + ЗначениеПоля.Поле + " = " + ПредставлениеЗначения + """",
, ирКэш.КартинкаПоИмениЛкс("ирРедактироватьОбъектБД"));
выхКоличествоСсылочныхПолей = выхКоличествоСсылочныхПолей + 1;
Иначе
СписокДействийОткрыть.Добавить(Новый Структура("Действие, ЗначениеПоля", "КопироватьВБуферОбмена", ЗначениеПоля), ЗначениеПоля.Поле + " = " + ПредставлениеЗначения,
, ирКэш.КартинкаПоИмениЛкс("ирКопировать"));
КонецЕсли;
Если ЛиПрямоеПоле Тогда
СписокДействийСгруппировать.Добавить(Новый Структура("Действие, ЗначениеПоля, Родители", "Сгруппировать", ЗначениеПоля, ЭлементРасшифровки.ПолучитьРодителей()), "Сгруппировать """ + ЗначениеПоля.Поле + """");
СписокДействийОформить.Добавить(Новый Структура("Действие, ЗначениеПоля", "ОформитьПоле", ЗначениеПоля), "Оформить """ + ЗначениеПоля.Поле + """");
КонецЕсли;
Если ЗначениеПоля.Значение <> Null Тогда
СписокДействийОформить.Добавить(Новый Структура("Действие, ЗначениеПоля", "ОформитьЗначение", ЗначениеПоля), "Оформить """ + ЗначениеПоля.Поле + " = " + ПредставлениеЗначения + """");
СписокДействийОтборать.Добавить(Новый Структура("Действие, ЗначениеПоля", "Отфильтровать", ЗначениеПоля), "Отобрать """ + ЗначениеПоля.Поле + " = " + ПредставлениеЗначения + """");
КонецЕсли;
СписокДействийУпорядочить.Добавить(Новый Структура("Действие, ЗначениеПоля", "Упорядочить", ЗначениеПоля), "Упорядочить """ + ЗначениеПоля.Поле + """");
КонецПроцедуры
Функция ОбработатьДополнительноеДействиеРасшифровкиКомпоновкиЛкс(Знач ВыбранноеДействие, СтандартнаяОбработка, НастройкаКомпоновки = Неопределено) Экспорт
Если ТипЗнч(ВыбранноеДействие) = Тип("Структура") Тогда
ЗначениеПоля = ВыбранноеДействие.ЗначениеПоля;
#Если Сервер И Не Сервер Тогда
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
ЗначениеПоля = ДанныеРасшифровки.Элементы[0].ПолучитьПоля()[0];
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
Если ВыбранноеДействие.Действие = "ОткрытьЗначение" Тогда
ОткрытьЗначениеЛкс(ЗначениеПоля.Значение, Ложь, СтандартнаяОбработка);
ИначеЕсли ВыбранноеДействие.Действие = "ОткрытьВРедактореОбъектаБД" Тогда
СтандартнаяОбработка = Ложь;
ОткрытьСсылкуВРедактореОбъектаБДЛкс(ЗначениеПоля.Значение);
ИначеЕсли ВыбранноеДействие.Действие = "КопироватьВБуферОбмена" Тогда
СтандартнаяОбработка = Ложь;
ТекстВБуферОбменаОСЛкс(ЗначениеПоля.Значение);
ИначеЕсли Ложь
Или ВыбранноеДействие.Действие = "ОформитьПоле"
Или ВыбранноеДействие.Действие = "ОформитьЗначение"
Тогда
СтандартнаяОбработка = Ложь;
Если ВыбранноеДействие.Действие = "ОформитьПоле" Тогда
ЭлементНастроек = ирОбщий.НайтиЭлементУсловногоОформленияПоПолюЛкс(НастройкаКомпоновки.УсловноеОформление, ЗначениеПоля.Поле);
КонецЕсли;
Если ЭлементНастроек = Неопределено Тогда
ЭлементНастроек = НастройкаКомпоновки.УсловноеОформление.Элементы.Добавить();
ОформляемоеПоле = ЭлементНастроек.Поля.Элементы.Добавить();
ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных(ЗначениеПоля.Поле);
ОформляемоеПоле.Использование = Истина;
Если ВыбранноеДействие.Действие = "ОформитьЗначение" Тогда
ирОбщий.НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементНастроек.Отбор, ЗначениеПоля.Поле, ЗначениеПоля.Значение);
КонецЕсли;
КонецЕсли;
ИначеЕсли ВыбранноеДействие.Действие = "Отфильтровать" Тогда
СтандартнаяОбработка = Ложь;
ЭлементНастроек = ирОбщий.НайтиДобавитьЭлементОтбораКомпоновкиЛкс(НастройкаКомпоновки.Отбор, ЗначениеПоля.Поле, ЗначениеПоля.Значение);
ИначеЕсли ВыбранноеДействие.Действие = "Сгруппировать" Тогда
//Родители = ВыбранноеДействие.Родители;
//#Если Сервер И Не Сервер Тогда
// Родители = ДанныеРасшифровки.Элементы[0].ПолучитьРодителей();
//#КонецЕсли
//Если Родители.Количество() > 0 Тогда
// ГруппировкаРодитель = Родители[0];
//КонецЕсли;
//СтандартнаяОбработка = Ложь;
//// TODO придумать. Сейчас ошибка
//ЭлементСтруктурыРодитель = ирОбщий.НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура, ГруппировкаРодитель.Группировка, Ложь);
//Если ЭлементСтруктурыРодитель = Неопределено Тогда
// ЭлементСтруктурыРодитель = НастройкаКомпоновки.Структура;
//КонецЕсли;
//ЭлементНастроек = ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПредставлениюЛкс(ЭлементСтруктурыРодитель.ПоляГруппировки, ЗначениеПоля.Поле);
ИначеЕсли ВыбранноеДействие.Действие = "Упорядочить" Тогда
СтандартнаяОбработка = Ложь;
ЭлементНастроек = ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Порядок, ЗначениеПоля.Поле, ЗначениеПоля.Значение);
КонецЕсли;
КонецЕсли;
Возврат ЭлементНастроек;
КонецФункции
// Параметры:
// ОтчетОбъект - Форма, ОтчетОбъект
Процедура ОтчетКомпоновкиОбработкаРасшифровкиЛкс(Знач ОтчетОбъект, Знач Расшифровка, СтандартнаяОбработка, ДополнительныеПараметры, ПолеТабличногоДокумента, ДанныеРасшифровки,
Авторасшифровка = Ложь) Экспорт
#Если _ Тогда
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
ЭлементРасшифровки = ДанныеРасшифровки.Элементы[0];
ТабличныйДокумент = Новый ТабличныйДокумент;
ОтчетОбъект = Отчеты.ирАнализПравДоступа.Создать();
#КонецЕсли
Если ТипЗнч(Расшифровка) <> Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
//Возврат;
КонецЕсли;
ЭлементРасшифровки = ДанныеРасшифровки.Элементы[Расшифровка];
ДоступныеДействия = Новый Массив;
РазрешитьАвтовыборДействия = Истина;
ПараметрВыбранногоДействия = Неопределено;
КоличествоСсылочныхПолей = 0;
ЗначенияВсехПолей = Новый Соответствие;
ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(ЭлементРасшифровки,, ЗначенияВсехПолей);
Для Каждого ЭлементОтбора Из ДанныеРасшифровки.Настройки.Отбор.Элементы Цикл
Если Ложь
Или Не ЭлементОтбора.Использование
Или ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
Или ЭлементОтбора.ВидСравнения <> ВидСравненияКомпоновкиДанных.Равно
Или ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("ПолеКомпоновкиДанных")
Тогда
Продолжить;
КонецЕсли;
ЗначенияВсехПолей["" + ЭлементОтбора.ЛевоеЗначение] = ЭлементОтбора.ПравоеЗначение;
КонецЦикла;
СписокДополнительныхДействий = Новый СписокЗначений;
Если ирОбщий.МетодРеализованЛкс(ОтчетОбъект, "ОбработкаРасшифровки") Тогда
ОтчетОбъект.ОбработкаРасшифровки(ДанныеРасшифровки, ЭлементРасшифровки, ПолеТабличногоДокумента, ДоступныеДействия, СписокДополнительныхДействий, РазрешитьАвтовыборДействия, ЗначенияВсехПолей);
КонецЕсли;
ДополнительныеДействияРасшифровкиКомпоновкиЛкс(ДоступныеДействия, ЭлементРасшифровки, СписокДополнительныхДействий, КоличествоСсылочныхПолей,, ЗначенияВсехПолей);
КоличествоОбщихДействий = СписокДополнительныхДействий.Количество();
Если Истина
И РазрешитьАвтовыборДействия
И Авторасшифровка
И (ЛОжь
ИЛи СписокДополнительныхДействий.Количество() - КоличествоОбщихДействий = 1
Или СписокДополнительныхДействий.Количество() - КоличествоОбщихДействий = 0 И КоличествоСсылочныхПолей = 1)
Тогда
ВыбранноеДействие = СписокДополнительныхДействий[0].Значение;
КонецЕсли;
Если ВыбранноеДействие = Неопределено Тогда
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(ОтчетОбъект.СхемаКомпоновкиДанных);
ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, ИсточникДоступныхНастроек);
ОбработкаРасшифровки.ВыбратьДействие(Расшифровка, ВыбранноеДействие, ПараметрВыбранногоДействия, ДоступныеДействия, СписокДополнительныхДействий, Авторасшифровка);
КонецЕсли;
Если ВыбранноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.Нет Тогда
СтандартнаяОбработка = Ложь;
//Возврат;
КонецЕсли;
Если ПараметрВыбранногоДействия = Неопределено Тогда
ПараметрВыбранногоДействия = ЗначенияВсехПолей;
КонецЕсли;
ЭлементНастроек = ОбработатьДополнительноеДействиеРасшифровкиКомпоновкиЛкс(ВыбранноеДействие, СтандартнаяОбработка, ОтчетОбъект.КомпоновщикНастроек.Настройки);
Если ирОбщий.МетодРеализованЛкс(ОтчетОбъект, "ДействиеРасшифровки") Тогда
ОтчетОбъект.ДействиеРасшифровки(ВыбранноеДействие, ПараметрВыбранногоДействия, СтандартнаяОбработка);
КонецЕсли;
Если СтандартнаяОбработка Тогда
Если ВыбранноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение Тогда
ОткрытьЗначение(ПараметрВыбранногоДействия);
ИначеЕсли ТипЗнч(ВыбранноеДействие) = Тип("ДействиеОбработкиРасшифровкиКомпоновкиДанных") Тогда
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(ОтчетОбъект.СхемаКомпоновкиДанных);
ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, ИсточникДоступныхНастроек);
НовыеНастройки = ОбработкаРасшифровки.ПрименитьНастройки(Расшифровка, ПараметрВыбранногоДействия);
ОтчетОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(НовыеНастройки);
ОтчетОбъект.СкомпоноватьРезультат(ПолеТабличногоДокумента, ДанныеРасшифровки);
КонецЕсли;
КонецЕсли;
СтандартнаяОбработка = Ложь;
КонецПроцедуры
Функция ВыбратьТипСсылкиВПолеВводаЛкс(Элемент, СтандартнаяОбработка, ОткрытьФормуВыбораСсылкиПослеВыбораТипа = Ложь) Экспорт
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", Элемент, Элемент);
ТекущееЗначение = ДанныеЭлементаФормыЛкс(Элемент);
Если ЛиСсылкаНаОбъектБДЛкс(ТекущееЗначение, Ложь) Тогда
НачальноеЗначениеВыбора = ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ТекущееЗначение));
КонецЕсли;
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина);
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
ЗначениеВыбора = Форма.ОткрытьМодально();
Если ТипЗнч(ЗначениеВыбора) = Тип("Структура") Тогда
лПолноеИмяОбъекта = Неопределено;
Если ЗначениеВыбора.Свойство("ПолноеИмяОбъекта", лПолноеИмяОбъекта) Тогда
ИмяТипаСсылки = ИмяТипаИзПолногоИмениМДЛкс(лПолноеИмяОбъекта, "Ссылка");
ОписаниеТипов = Новый ОписаниеТипов(ИмяТипаСсылки);
НовоеЗначение = ОписаниеТипов.ПривестиЗначение(Неопределено);
ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, НовоеЗначение);
// // http://www.hostedredmine.com/issues/884276
//Если ОткрытьФормуВыбораСсылкиПослеВыбораТипа Тогда
// //Если ЛиСсылкаНаОбъектБДЛкс(НовоеЗначение, Ложь) Тогда
// ОткрытьФормуСпискаЛкс(лПолноеИмяОбъекта,,, Элемент, Истина);
// //КонецЕсли;
//КонецЕсли;
КонецЕсли;
КонецЕсли;
СтандартнаяОбработка = Ложь;
Возврат НовоеЗначение;
КонецФункции
// Результат - значение выбранного типа, но не обязательно выбранное (выбор типа выполняется синхронно, а значения - асинхронно)
//
// Параметры:
// Элемент - -
// СтандартнаяОбработка - -
// ИгнорироватьОписаниеТипов - -
// Отбор - Структура -
//
// Возвращаемое значение:
// -
//
Функция ПолеВвода_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка, ИгнорироватьОписаниеТипов = Ложь, Знач Отбор = Неопределено) Экспорт
РезультатВыбора = ДанныеЭлементаФормыЛкс(Элемент);
Если Истина
И ИгнорироватьОписаниеТипов
И (Ложь
Или ТипЗнч(РезультатВыбора) = Тип("Строка")
Или РезультатВыбора = Неопределено)
Тогда
Типы = Элемент.ОграничениеТипа.Типы();
Если Типы.Количество() = 1 Тогда
// Ссылка внешнего источника данных
СтандартнаяОбработка = Ложь;
ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(Типы[0]),,, Элемент, Истина,, РезультатВыбора);
Иначе
РезультатВыбора = ВыбратьТипСсылкиВПолеВводаЛкс(Элемент, СтандартнаяОбработка);
КонецЕсли;
ИначеЕсли ЛиСсылкаНаОбъектБДЛкс(РезультатВыбора, Ложь) Тогда
СтандартнаяОбработка = Ложь;
Если Отбор = Неопределено Тогда
Отбор = Новый Структура;
КонецЕсли;
Если ТипЗнч(Элемент) = Тип("ПолеВвода") И Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(РезультатВыбора)) Тогда
Если ЗначениеЗаполнено(Элемент.ВыборПоВладельцу) Тогда
Отбор.Вставить("Владелец", Элемент.ВыборПоВладельцу);
КонецЕсли;
КонецЕсли;
ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РезультатВыбора)), Отбор,, Элемент, Истина,, РезультатВыбора);
Иначе
// Тут надо делать выбор из диалога плоского списка типов
КонецЕсли;
Возврат РезультатВыбора;
КонецФункции
Процедура ПолеВводаРегулированиеЛкс(Знач Элемент, Знач Направление, СтандартнаяОбработка) Экспорт
ОболочкаПоляТекста = ОболочкаПоляТекстаЛкс(Элемент);
#Если Сервер И Не Сервер Тогда
ОболочкаПоляТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
СтруктураВыделения = ОболочкаПоляТекста.СтруктураДвумерногоВыделения();
Если ТипЗнч(Элемент.Значение) = Тип("Дата") Тогда
// Антибаг платформы 8.3.0-20 Каретка меняет положение https://www.hostedredmine.com/issues/936754
// Повторяем штатное поведение
СтандартнаяОбработка = Ложь;
Позиция = СтруктураВыделения.НачальнаяКолонка;
МножительСекунд = 0;
МножительМесяцев = 0;
Если Позиция > 17 Тогда
МножительСекунд = 1;
ИначеЕсли Позиция > 14 Тогда
МножительСекунд = 60;
ИначеЕсли Позиция > 11 Тогда
МножительСекунд = 60*60;
ИначеЕсли Позиция > 6 Тогда
МножительМесяцев = 12;
ИначеЕсли Позиция > 3 Тогда
МножительМесяцев = 1;
Иначе
МножительСекунд = 24*60*60;
КонецЕсли;
НовоеЗначение = Элемент.Значение;
НовоеЗначение = НовоеЗначение + МножительСекунд * Направление;
НовоеЗначение = ДобавитьМесяц(НовоеЗначение, МножительМесяцев * Направление);
//Элемент.Значение = НовоеЗначение; // Так каретка меняет положение
ОболочкаПоляТекста.УстановитьГраницыВыделения(1, 1);
ОболочкаПоляТекста.ВыделенныйТекст(НовоеЗначение);
УстановитьФокусВводаФормеЛкс();
ОболочкаПоляТекста.УстановитьДвумерноеВыделениеСтруктурой(СтруктураВыделения);
КонецЕсли;
КонецПроцедуры
Функция ДобавитьМногострочнуюСтрокуВТекстЛкс(ТекстПриемник, СтрокаДляВставки, Смещение, СНовойСтроки = Ложь, ОбрезатьЛевыеПустые = Ложь) Экспорт
Если Не ЗначениеЗаполнено(ТекстПриемник) Тогда
ТекстПриемник = "";
КонецЕсли;
ЗаписьТекста = Новый ЗаписьXML;
ЗаписьТекста.УстановитьСтроку();
Если СНовойСтроки Тогда
ЗаписьТекста.ЗаписатьБезОбработки(Символы.ПС + Смещение);
КонецЕсли;
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(СтрокаДляВставки);
ЗаписьТекста.ЗаписатьБезОбработки(ТекстовыйДокумент.ПолучитьСтроку(1));
Для Счетчик = 2 По ТекстовыйДокумент.КоличествоСтрок() Цикл
ТекущаяСтрока = ТекстовыйДокумент.ПолучитьСтроку(Счетчик);
Если ОбрезатьЛевыеПустые Тогда
ТекущаяСтрока = СокрЛ(ТекущаяСтрока);
КонецЕсли;
ЗаписьТекста.ЗаписатьБезОбработки(Символы.ПС + Смещение + ТекущаяСтрока);
КонецЦикла;
ТекстПриемник = ТекстПриемник + ЗаписьТекста.Закрыть();
Возврат ТекстПриемник;
КонецФункции
Функция ИндексКартинкиТипаЗначенияБДЛкс(Знач ОписаниеТипов) Экспорт
Если ОписаниеТипов = Неопределено Тогда
Возврат 14;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОписаниеТипов = Новый ОписаниеТипов;
#КонецЕсли
Если ОписаниеТипов.СодержитТип(Тип("Null")) Тогда
ОписаниеТипов = Новый ОписаниеТипов(ОписаниеТипов,, "Null");
КонецЕсли;
Типы = ОписаниеТипов.Типы();
Если Типы.Количество() = 1 Тогда
КорневойТип = КорневойТипКонфигурацииЛкс(Типы[0]);
Если Типы[0] = Тип("Число") Тогда
ИндексКартинки = 0;
ИначеЕсли Типы[0] = Тип("Строка") Тогда
ИндексКартинки = 1;
ИначеЕсли Типы[0] = Тип("Дата") Тогда
ИндексКартинки = 2;
ИначеЕсли Типы[0] = Тип("Булево") Тогда
ИндексКартинки = 3;
ИначеЕсли Типы[0] = Тип("ТаблицаЗначений") Тогда
ИндексКартинки = 19;
ИначеЕсли Типы[0] = Тип("Тип") Тогда
ИндексКартинки = 20;
ИначеЕсли Типы[0] = Тип("УникальныйИдентификатор") Тогда
ИндексКартинки = 21;
ИначеЕсли Типы[0] = Тип("ХранилищеЗначения") Тогда
ИндексКартинки = 22;
ИначеЕсли КорневойТип = "Справочник" Тогда
ИндексКартинки = 7;
ИначеЕсли КорневойТип = "Документ" Тогда
ИндексКартинки = 8;
ИначеЕсли КорневойТип = "Перечисление" Тогда
ИндексКартинки = 9;
ИначеЕсли КорневойТип = "ПланВидовХарактеристик" Тогда
ИндексКартинки = 10;
ИначеЕсли КорневойТип = "ПланСчетов" Тогда
ИндексКартинки = 11;
ИначеЕсли КорневойТип = "ПланВидовРасчета" Тогда
ИндексКартинки = 12;
ИначеЕсли КорневойТип = "БизнесПроцесс" Тогда
ИндексКартинки = 13;
ИначеЕсли КорневойТип = "ТочкаМаршрута" Тогда
ИндексКартинки = 14;
ИначеЕсли КорневойТип = "Задача" Тогда
ИндексКартинки = 13;
ИначеЕсли КорневойТип = "ПланОбмена" Тогда
ИндексКартинки = 15;
Иначе
ИндексКартинки = 16;
КонецЕсли;
Иначе
ИндексКартинки = 16;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции
Функция ПроверитьПодпискиЛкс() Экспорт
Результат = Истина;
// Проверка компиляции общих модулей с обработчиками событий
СписокМодулейВызоваСервера = Неопределено;
ИмяКлиента = Неопределено;
СписокМодулей = ПроблемныеОбщиеМодулиЛкс(СписокМодулейВызоваСервера, ИмяКлиента);
Если СписокМодулей.Количество() > 0 Тогда
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ТипыОбъектовПодписок = "";
Иначе
ТипыОбъектовПодписок = " менеджеров";
КонецЕсли;
СообщитьЛкс("В конфигурации обнаружены недоступные на клиенте (" + ИмяКлиента + " приложение) общие модули с обработчиками подписок на события" + ТипыОбъектовПодписок + ".", СтатусСообщения.Внимание);
СообщитьЛкс("Поэтому в работе некоторых инструментов возможны ошибки ""При подписке * на событие * произошла ошибка. Обработчик события не найден.""");
Если ИмяКлиента = "Обычное" Тогда
СообщитьЛкс("Необходимо в конфигураторе установить ""Сервис""/""Параметры""/""Редактирование конфигурации для режимов запуска""=""Управляемое приложение и обычное приложение"".");
КонецЕсли;
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
ТекстСообщения = "Рекомендуется установить флажок ""Вызова сервера"" или ""Клиент (" + ИмяКлиента + " приложение)"" и обеспечить компиляцию у этих общих модулей:";
Иначе
ТекстСообщения = "Рекомендуется установить флажок ""Клиент (" + ИмяКлиента + " приложение)"" и обеспечить компиляцию у этих общих модулей:";
КонецЕсли;
МассивИменМодулей = Новый Массив;
Для Каждого КлючИЗначение Из СписокМодулей Цикл
МассивИменМодулей.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
ТекстСообщения = ТекстСообщения + " " + СтрСоединитьЛкс(МассивИменМодулей, ", ");
СообщитьЛкс(ТекстСообщения);
Результат = Ложь;
КонецЕсли;
Если СписокМодулейВызоваСервера.Количество() > 0 Тогда
СообщитьЛкс("В конфигурации обнаружены недоступные на клиенте (" + ИмяКлиента + " приложение) общие модули с обработчиками подписок на событие ""ОбработкаПолученияПредставления"".", СтатусСообщения.Внимание);
СообщитьЛкс("Это может приводить к сильному замеделению получения представлений таких ссылок. Рекомендуется перенести эти обработчики в модуль, компилируемый на толстых клиентах");
Для Каждого КлючИЗначение Из СписокМодулей Цикл
ТекстСообщения = ТекстСообщения + " " + КлючИЗначение.Ключ + ",";
КонецЦикла;
СообщитьЛкс(ТекстСообщения);
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПроблемныеОбщиеМодулиЛкс(СписокМодулейВызоваСервера = Неопределено, ИмяКлиента = "") Экспорт
СписокМодулей = Новый Структура;
СписокМодулейВызоваСервера = Новый Структура;
ОбщиеМодули = Метаданные.ОбщиеМодули;
Если ирКэш.ЛиСеансТолстогоКлиентаУПЛкс() Тогда
ИмяКлиента = "Управляемое";
Иначе
ИмяКлиента = "Обычное";
КонецЕсли;
ИмяСвойства = "Клиент" + ИмяКлиента + "Приложение";
Для Каждого Подписка Из Метаданные.ПодпискиНаСобытия Цикл
#Если Сервер И Не Сервер Тогда
Подписка = Метаданные.ПодпискиНаСобытия.ВерсионированиеОбъектов_ПриЗаписиОбъекта;
#КонецЕсли
МетаМодуль = ОбщиеМодули.Найти(ирОбщий.ПервыйФрагментЛкс(Подписка.Обработчик));
Если МетаМодуль = Неопределено Тогда
// Некорректная подписка
Продолжить;
КонецЕсли;
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
// Проверяем только подписки менеджеров
Если Не МетаМодуль[ИмяСвойства] И Не МетаМодуль.ВызовСервера Тогда
ТипыИсточников = Подписка.Источник.Типы(); // Долго!
Если ТипыИсточников.Количество() > 0 И Не ирОбщий.ЛиТипОбъектаБДЛкс(ТипыИсточников[0]) Тогда // Это подписка менеджера
СписокМодулей.Вставить(МетаМодуль.Имя);
КонецЕсли;
КонецЕсли;
Иначе
// Проверяем все подписки в портативном режиме обычном приложении
Если Не МетаМодуль[ИмяСвойства] Тогда
СписокМодулей.Вставить(МетаМодуль.Имя);
КонецЕсли;
КонецЕсли;
Если Подписка.Событие = "ОбработкаПолученияПредставления" И МетаМодуль.ВызовСервера Тогда
СписокМодулейВызоваСервера.Вставить(МетаМодуль.Имя);
КонецЕсли;
КонецЦикла;
Возврат СписокМодулей;
КонецФункции
// Тяжелый метод. Попытка-Исключение в 5-10 раз быстрее.
Функция ЕстьСвойствоОбъектаЛкс(Объект, Свойство) Экспорт
УникальноеЗначение = "м86ыщшру5аа7шлв9823454";
Структура = Новый Структура(Свойство, УникальноеЗначение);
ЗаполнитьЗначенияСвойств(Структура, Объект);
Результат = Структура[Свойство] <> УникальноеЗначение;
Возврат Результат;
КонецФункции
////////////////////////////////
// ФОРМЫ
Процедура ИнициироватьФормуЛкс(ЭтаФорма, ПолноеИмяФормы, РазрешитьОткрытиеДополнительныхФорм = Истина) Экспорт
// Проверяем режим модальности
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ОткрыватьФормуПерезапуска = Ложь;
ЛиМодальностьЗапрещена = ирКэш.ЛиМодальностьЗапрещенаЛкс();
Если Ложь
Или ирКэш.НомерИзданияПлатформыЛкс() = "82"
Или мПлатформа.мВопросОтключенияПроверкиМодальностиЗадавался = Истина
Или Метаданные.РежимИспользованияМодальности = Метаданные.СвойстваОбъектов.РежимИспользованияМодальности.Использовать
Тогда
//
ИначеЕсли РазрешитьОткрытиеДополнительныхФорм Тогда
КоманднаяСтрокаПроцесса = ирКэш.КоманднаяСтрокаТекущегоПроцессаОСЛкс();
мПлатформа.мВопросОтключенияПроверкиМодальностиЗадавался = Истина;
Если Ложь
Или Найти(НРег(КоманднаяСтрокаПроцесса), НРег("/EnableCheckModal")) > 0
//Или Найти(КоманднаяСтрокаПроцесса, "/EnableCheckExtensionsAndAddInsSyncCalls") > 0
Тогда
ТекстСообщения = "При запуске сеанса из конфигуратора с текущим свойством конфигурации ""Режим использования модальности"" включается контроль модальности. Для его отключения рекомендуется перезапустить сеанс командой подсистемы.";
СообщитьЛкс(ТекстСообщения,,, Истина, Ложь);
ОткрыватьФормуПерезапуска = Истина;
КонецЕсли;
КонецЕсли;
// Проверяем защиту от опасных действий
// Здесь это делать мало полезно, т.к. она срабатывает раньше
Если Истина
И РазрешитьОткрытиеДополнительныхФорм
И ирКэш.ЛиПортативныйРежимЛкс()
И мПлатформа.мПроверкаЗащитыОтОпасныхДействийВыполнялась <> Истина
//И ирКэш.НомерВерсииПлатформыЛкс() < 803010 // Когда в платформе исправят проблему, тогда и отключим
Тогда
ТекущийПользовательБазы = ПользователиИнформационнойБазы.ТекущийПользователь();
Попытка
ЗащитаОтОпасныхДействий = ТекущийПользовательБазы.ЗащитаОтОпасныхДействий;
Исключение
ЗащитаОтОпасныхДействий = Неопределено;
КонецПопытки;
Если Истина
И ЗначениеЗаполнено(ТекущийПользовательБазы.Имя)
И ЗащитаОтОпасныхДействий <> Неопределено
И ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Истина
Тогда
ТекстСообщения = "У текущего пользователя базы включена защита от опасных действий. Для корректной работы инструментов ее рекомендуется отключить перезапуском сеанса через открывшуюся форму.";
СообщитьЛкс(ТекстСообщения, СтатусСообщения.Внимание,, Истина, Ложь);
ОткрыватьФормуПерезапуска = Истина;
КонецЕсли;
мПлатформа.мПроверкаЗащитыОтОпасныхДействийВыполнялась = Истина;
КонецЕсли;
Если ОткрыватьФормуПерезапуска Тогда
// TODO Надо заблокировать открытие формы в модальной группе
#Если ТолстыйКлиентОбычноеПриложение Тогда
ОткрытьФормуЛкс("Обработка.ирПортативный.Форма.ЗапускСеансаОбычная");
#Иначе
//ОткрытьФормуЛкс("Обработка.ирПортативный.Форма.ЗапускСеансаУправляемая");
#КонецЕсли
КонецЕсли;
Если ЛиМодальностьЗапрещена И Найти(ПолноеИмяФормы, "ирПортативный") = 0 Тогда
ВызватьИсключение "При запуске сеанса из конфигуратора с текущим свойством конфигурации ""Режим использования модальности"" включается контроль модальности.
|Рекомендуется изменить это свойство конфигурации либо запустить сеанс другим способом.";
КонецЕсли;
мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
мСвойстваФормы.Вставить("МенеджерСохраненияНастроек");
мСвойстваФормы.Вставить("ИмяФормы", ПолноеИмяФормы);
мСвойстваФормы.Вставить("НеготовыеСтраницы", Новый СписокЗначений);
мСвойстваФормы.Вставить("Задания", Новый Структура);
мСвойстваФормы.Вставить("ОригинальныйЗаголовок", ЭтаФорма.Заголовок);
ПодготовитьЭлементыФормыЛкс(ЭтаФорма);
Форма_ВставитьСкрытуюКоманднуюПанельГлобальныхКомандЛкс(ЭтаФорма);
ПерехватКлавиатуры = мПлатформа.ПодключитьПерехватКлавиатуры();
СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
СлужебныеДанныеФормы.Вставить("ПерехватКлавиатуры", ПерехватКлавиатуры);
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
Контейнер = Новый Структура();
ирОбщий.ОповеститьФормыПодсистемыЛкс("ирПолучитьБазовуюФорму", Контейнер); // Скорость https://www.hostedredmine.com/issues/891484
Если Не Контейнер.Свойство("ирПортативный") Тогда
БазоваяФорма = ирПортативный.ПолучитьФорму();
БазоваяФорма.Открыть();
КонецЕсли;
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтрокаВызова = "ирПортативный.ИнициализироватьФорму_" + ИдентификаторИзПредставленияЛкс(ПолноеИмяФормы) + "(ЭтаФорма)";
Выполнить(СтрокаВызова);
Иначе
МетаФорма = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяФормы);
Если МетаФорма = Неопределено Тогда
СообщитьЛкс(СтрШаблонИменЛкс("Метаформа не найдена по полному имени %1",, ПолноеИмяФормы), СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
ФлажокОбъектыНаСервере = ЭтаФорма.ЭлементыФормы.Найти("ОбъектыНаСервере");
Если ФлажокОбъектыНаСервере <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ирПортативный = Обработки.ирПортативный.Создать();
#КонецЕсли
ФлажокОбъектыНаСервере.Доступность = Не ирКэш.ЛиПортативныйРежимЛкс() Или ирПортативный.ЛиСерверныйМодульДоступенЛкс();
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ФлажокОбъектыНаСервере.Подсказка = "Запись и удаление объектов данных выполнять на сервере. Это снижает скорость, но повышает совместимость с конфигурациями под управляемое приложение.";
Иначе
ФлажокОбъектыНаСервере.Подсказка = "При выполнении кода на клиенте работать с объектами данных на сервере. Это снижает скорость, но повышает совместимость с конфигурациями под управляемое приложение. При выполнении кода на сервере этот параметр не используется.";
КонецЕсли;
КонецЕсли;
Если мПлатформа.мПроверкаСовместимостиКонфигурацииВыполнялась <> Истина Тогда
// Однократно выполняем в сеансе проверку совместимости
Если Метаданные.ХранилищеОбщихНастроек <> Неопределено Тогда
ИмяПроверочнойНастройки = "Тест";
СохранитьЗначениеЛкс(ИмяПроверочнойНастройки, 1);
Если ВосстановитьЗначениеЛкс(ИмяПроверочнойНастройки) = Неопределено Тогда
СообщитьЛкс("В конфигурации переопределено хранилище общих настроек и оно не восстанавливает сохраненные значения. Корректная работа подсистемы ""Инструменты разработчика"" невозможна", СтатусСообщения.Важное);
КонецЕсли;
КонецЕсли;
Если Не ЛиСовместимыйЯзыкСистемыЛкс() Тогда
СообщитьЛкс("Язык системы сеанса 1С (параметр /L) не является русским или английским. Корректная работа подсистемы ""Инструменты разработчика"" невозможна", СтатусСообщения.Важное);
КонецЕсли;
мПлатформа.мПроверкаСовместимостиКонфигурацииВыполнялась = Истина;
#Если Сервер И Не Сервер Тогда
ВыполнитьПроверкуСовместимостиКонфигурацииЛкс();
#КонецЕсли
ПодключитьГлобальныйОбработчикОжиданияЛкс("ВыполнитьПроверкуСовместимостиКонфигурацииЛкс", 1, Истина);
Если Не ирКэш.ЛиФайловаяБазаЛкс() Тогда
// Запускаем асинхронную подготовку объекта, иначе он при первом выполнении запроса будет подбирать протокол и в случае недоступности TCP будет 6 секунд ждать
// https://forum.mista.ru/topic.php?id=870813
ПроверитьСоединениеADOЭтойБДЛкс(,,,,, Ложь, Истина, мПлатформа.ПроверочноеСоединениеАДО);
КонецЕсли;
КонецЕсли;
ирКэш.СостояниеПодготовкиКэшМДСеансаЛкс();
КонецПроцедуры
Функция ЛиПровайдерАДОДляЭтойБазыГотовЛкс() Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Результат = Истина
И мПлатформа.ПроверочноеСоединениеАДО <> Неопределено
И (Ложь
Или мПлатформа.ПроверочноеСоединениеАДО = "Готов"
Или мПлатформа.ПроверочноеСоединениеАДО.State = 1);
Если Результат Тогда
мПлатформа.ПроверочноеСоединениеАДО = "Готов";
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиСовместимыйЯзыкСистемыЛкс() Экспорт
ТекущийЯзыкСистемы = НРег(ПервыйФрагментЛкс(ТекущийЯзыкСистемы(), "_"));
ЛиСовместимыйЯзыкСистемы = Ложь
Или ТекущийЯзыкСистемы = "ru"
Или ТекущийЯзыкСистемы = "en";
Возврат ЛиСовместимыйЯзыкСистемы;
КонецФункции
Процедура ПодготовитьЭлементыФормыЛкс(ЭтаФорма) Экспорт
СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
//ОбработчикиПриВыводеСтроки = Новый Соответствие;
//СлужебныеДанныеФормы.Вставить("ОбработчикиПриВыводеСтроки", ОбработчикиПриВыводеСтроки);
КнопкиВсехДействийКомандныхПанелей = Новый Соответствие;
КомандныеПанелиКнопок = Новый Соответствие;
ИмяКнопки = "СтруктураКоманднойПанели";
ВозможныеИменаРеквизита = Новый Массив;
ВозможныеИменаРеквизита.Добавить("ОбработкаОбъект");
ВозможныеИменаРеквизита.Добавить("ОсновнойОбъект");
ОсновнойРеквизит = Неопределено;
ЕстьОбщийОбработчикПриПолученииДанных = Неопределено;
Для Каждого ИмяОсновногоРеквизита Из ВозможныеИменаРеквизита Цикл
Если ЕстьСвойствоОбъектаЛкс(ЭтаФорма, ИмяОсновногоРеквизита) Тогда
ОсновнойРеквизит = ЭтаФорма[ИмяОсновногоРеквизита];
Прервать;
КонецЕсли;
КонецЦикла;
Для Каждого ЭлементФормы Из ЭтаФорма.ЭлементыФормы Цикл
Если ОсновнойРеквизит <> Неопределено Тогда
Попытка
Данные = ЭлементФормы.Данные;
Подсказка = ЭлементФормы.Подсказка; // У ActiveX этого свойства нет
Исключение
Данные = "";
КонецПопытки;
Если Не ПустаяСтрока(Данные) И Найти(Данные, ".") = 0 Тогда
Если Не ЗначениеЗаполнено(ЭлементФормы.Подсказка) Тогда
РеквизитОбъекта = ОсновнойРеквизит.Метаданные().Реквизиты.Найти(Данные);
Если РеквизитОбъекта <> Неопределено Тогда
ЭлементФормы.Подсказка = РеквизитОбъекта.Подсказка;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Встраиваем кнопки структуры командной панели
КоманднаяПанель = Неопределено;
ВстроитьВНачало = Истина;
Если ТипЗнч(ЭлементФормы) = Тип("КоманднаяПанель") Тогда
КоманднаяПанель = ЭлементФормы;
ВсеКнопки = ВсеКнопкиКоманднойПанелиЛкс(КоманднаяПанель);
Для Каждого Кнопка Из ВсеКнопки Цикл
КомандныеПанелиКнопок[Кнопка] = КоманднаяПанель;
КонецЦикла;
Если Не КоманднаяПанель.Видимость Тогда
Продолжить;
КонецЕсли;
ВстроитьВНачало = КоманднаяПанель.Ширина > 100;
//ИначеЕсли ТипЗнч(ЭлементФормы) = Тип("ТабличноеПоле") Тогда
// КоманднаяПанель = ЭлементФормы.КонтекстноеМеню;
Иначе
Попытка
// В контекстных меню функция мало востребована, т.к. они имеют обычно более простую структуру и там сразу виден текст всех кнопок
КоманднаяПанель = ЭлементФормы.КонтекстноеМеню;
ВстроитьВНачало = Ложь;
Исключение
КонецПопытки;
КонецЕсли;
Если Истина
И КоманднаяПанель <> Неопределено
И КоманднаяПанель.Кнопки.Найти(ИмяКнопки) = Неопределено
Тогда
НужноВстроить = Ложь;
КоличествоКнопок = 0;
Для Каждого Кнопка Из КоманднаяПанель.Кнопки Цикл
Если Кнопка.ТипКнопки <> ТипКнопкиКоманднойПанели.Разделитель Тогда
КоличествоКнопок = КоличествоКнопок + 1;
Если КоличествоКнопок > 4 Тогда
НужноВстроить = Истина;
Прервать;
КонецЕсли;
КонецЕсли;
Если Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда
НужноВстроить = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НужноВстроить Тогда
Если ВстроитьВНачало Тогда
КнопкаСтруктураКоманднойПанели = КоманднаяПанель.Кнопки.Вставить(0);
Иначе
КнопкаСтруктураКоманднойПанели = КоманднаяПанель.Кнопки.Добавить();
КонецЕсли;
КнопкаСтруктураКоманднойПанели.Имя = ИмяКнопки;
КнопкаСтруктураКоманднойПанели.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
КнопкаСтруктураКоманднойПанели.Картинка = ирКэш.КартинкаПоИмениЛкс("ирКоманднаяПанель");
КнопкаСтруктураКоманднойПанели.Отображение = ОтображениеКнопкиКоманднойПанели.Авто;
КнопкаСтруктураКоманднойПанели.Текст = "Структура командной панели";
КнопкаСтруктураКоманднойПанели.Подсказка = "Открыть структуру командной панели. Позволяет искать кнопки по ключевым словам.";
Попытка
КнопкаСтруктураКоманднойПанели.Действие = Новый Действие("СтруктураКоманднойПанелиНажатие");
Исключение
// В этой форме нет обработчика
КоманднаяПанель.Кнопки.Удалить(КнопкаСтруктураКоманднойПанели);
КонецПопытки;
КнопкиВсехДействийКомандныхПанелей.Вставить(КнопкаСтруктураКоманднойПанели, КоманднаяПанель);
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ЭлементФормы) = Тип("ТабличноеПоле") Тогда
ТабличноеПолеВключитьСтаруюЦветовуюСхемуЛкс(ЭлементФормы);
КонецЕсли;
КонецЦикла;
СлужебныеДанныеФормы.Вставить("КнопкиВсехДействийКомандныхПанелей", КнопкиВсехДействийКомандныхПанелей);
СлужебныеДанныеФормы.Вставить("КомандныеПанелиКнопок", КомандныеПанелиКнопок);
КонецПроцедуры
Процедура Форма_ВставитьСкрытуюКоманднуюПанельГлобальныхКомандЛкс(ЭтаФорма) Экспорт
ЭлементыФормы = ЭтаФорма.ЭлементыФормы;
//ИмяКоманднойПанели = "КП_ПолеВвода";
//КонтекстноеМенюФормы = ЭлементыФормы.Найти(ИмяКоманднойПанели);
//Если КонтекстноеМенюФормы = Неопределено Тогда
// КонтекстноеМенюФормы = ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), ИмяКоманднойПанели);
// КонтекстноеМенюФормы.Видимость = Ложь;
//КонецЕсли;
////лПлатформа = ирКэш.Получить();
////МакетФормы = лПлатформа.ПолучитьФорму("УниверсальныеКоманды");
////КонтекстноеМенюМакета = МакетФормы.ЭлементыФормы.КоманднаяПанель.Кнопки.ПолеВвода;
////ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(МакетФормы, КонтекстноеМенюМакета.Кнопки, КонтекстноеМенюФормы);
//КоманднаяПанельВставитьКнопкиГлобальныхКомандЛкс(КонтекстноеМенюФормы);
//Для Каждого ЭлементФормы Из ЭлементыФормы Цикл
// Если ТипЗнч(ЭлементФормы) = Тип("ПолеВвода") Тогда
// Попытка
// КонтекстноеМеню = ЭлементФормы.КонтекстноеМеню;
// Исключение
// // Поле ввода принадлежит не панели, поэтому у него нет свойства
// Продолжить;
// КонецПопытки;
// Если КонтекстноеМеню = Неопределено Тогда
// //ЭлементФормы.АвтоКонтекстноеМеню = Ложь;
// ЭлементФормы.КонтекстноеМеню = КонтекстноеМенюФормы;
// КонецЕсли;
// КонецЕсли;
//КонецЦикла;
ДействияФормы = ЭлементыФормы.Найти("ДействияФормы");
Если ТипЗнч(ДействияФормы) <> Тип("КоманднаяПанель") Тогда
ПанельФормы = ЭтаФорма.Панель;
Если ПанельФормы.КонтекстноеМеню = Неопределено Тогда
ДействияФормы = ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), "ДействияФормыАвто", Ложь);
ДействияФормы.ИсточникДействий = ЭтаФорма;
ПанельФормы.КонтекстноеМеню = ДействияФормы;
Иначе
ДействияФормы = ПанельФормы.КонтекстноеМеню;
КонецЕсли;
КоманднаяПанельВставитьКнопкиГлобальныхКомандЛкс(ДействияФормы);
КонецЕсли;
КонецПроцедуры
Функция ВсеКнопкиКоманднойПанелиЛкс(КоманднаяПанель, РезультатРекурсия = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
КоманднаяПанель = Новый КоманднаяПанель;
#КонецЕсли
Если РезультатРекурсия = Неопределено Тогда
РезультатРекурсия = Новый Массив;
КонецЕсли;
ФормаКоманд = ирКэш.ФормаОбщихКомандЛкс();
ОбщиеКоманды = ФормаКоманд.ЭлементыФормы.Команды.Кнопки;
Для Каждого Кнопка Из КоманднаяПанель.Кнопки Цикл
Если Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда
Если Кнопка.Кнопки.Количество() = 0 Тогда
// Динамическое подменю
РезультатРекурсия.Добавить(Кнопка);
КонецЕсли;
ВсеКнопкиКоманднойПанелиЛкс(Кнопка, РезультатРекурсия);
ИначеЕсли Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Действие Тогда
Если Найти(Кнопка.Действие, "КлсКомандаНажатие") = 1 Тогда
РезультатРекурсия.Добавить(Кнопка);
КонецЕсли;
Если Ложь
Или Найти(Кнопка.Действие, "КлсКомандаНажатие") = 1
Или Найти(Кнопка.Действие, "КлсКомандаТаблицаНажатие") = 1
Тогда
ОбщаяКоманда = ОбщиеКоманды.Найти(Кнопка.Имя);
Если ОбщаяКоманда = Неопределено Тогда
ВызватьИсключение СтрШаблонЛкс("Неизвестное имя общей команды ""%1""", Кнопка.Имя);
КонецЕсли;
ЗаполнитьЗначенияСвойств(Кнопка, ОбщаяКоманда, "СочетаниеКлавиш, Подсказка, Пояснение");
КонецЕсли;
//Если Истина
// И "" + Кнопка.Действие = "Отбор по значению в текущей колонке"
//Тогда
// Кнопка.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.W, Истина); // ALT+W
////ИначеЕсли Истина
//// И Кнопка.Имя = "РазличныеЗначенияКолонки"
////Тогда
//// Кнопка.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.F, Истина); // ALT+F
//КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат РезультатРекурсия;
КонецФункции
// Только для кнопок с обработчиком "КлсКомандаНажатие"
Функция КоманднаяПанельКнопкиЛкс(Знач ЭтаФорма, Знач Кнопка)
мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
Пока ТипЗнч(Кнопка) = Тип("КнопкаКоманднойПанели") Цикл
Кнопка = мСвойстваФормы.КомандныеПанелиКнопок[Кнопка];
КонецЦикла;
Возврат Кнопка;
КонецФункции
Процедура ОткрытьСтруктуруКоманднойПанелиЛкс(ЭтаФорма, Знач Кнопка = Неопределено) Экспорт
Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда
мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
КоманднаяПанель = мСвойстваФормы.КнопкиВсехДействийКомандныхПанелей[Кнопка];
Если Кнопка <> Неопределено Тогда
Если КоманднаяПанель.Кнопки.Индекс(Кнопка) = -1 Тогда
// Для контекстных меню
КоманднаяПанель = КоманднаяПанель.Кнопки[0];
КонецЕсли;
КонецЕсли;
Иначе
КоманднаяПанель = РодительЭлементаУправляемойФормыЛкс(Кнопка, Тип("ГруппаФормы"));
КонецЕсли;
ФормаСтруктуры = ирКэш.Получить().ПолучитьФорму("СтруктураФормы");
ФормаСтруктуры.ПараметрЭлементФормы = КоманднаяПанель;
ФормаСтруктуры.Форма = ЭтаФорма;
ФормаСтруктуры.ОткрытьМодально();
КонецПроцедуры
Процедура ОткрытьСтруктуруФормыЛкс(ЭтаФорма, КлючУникальности = Неопределено) Экспорт
ФормаСтруктуры = ирКэш.Получить().ПолучитьФорму("СтруктураФормы",, КлючУникальности);
ФормаСтруктуры.Форма = ЭтаФорма;
ФормаСтруктуры.ОткрытьМодально();
КонецПроцедуры
Функция ОткрытьФормуСоединенияСУБДЛкс(Автоподключение = Ложь) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ПроверкаСоединенияADOЭтойБДВыполнялась = мПлатформа.мПроверкаСоединенияADOЭтойБДВыполнялась = Истина;
ФормаПодключения = ирКэш.Получить().ПолучитьФорму("ПараметрыСоединенияСУБД");
ФормаПодключения.Автоподключение = Автоподключение И ПроверкаСоединенияADOЭтойБДВыполнялась;
Если Истина
И (Ложь
Или Не ПроверкаСоединенияADOЭтойБДВыполнялась
Или Не Автоподключение)
И Не ирКэш.ЛиФайловаяБазаЛкс()
Тогда
ФормаЗащиты = Неопределено;
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если ирКэш.НомерИзданияПлатформыЛкс() > "82" Тогда
// Антибаг платформы https://www.hostedredmine.com/issues/901181
ФормаЗащиты = ОткрытьФорму("Обработка.ирПлатформа.Форма.Пустышка");
КонецЕсли;
#КонецЕсли
РезультатФормы = ФормаПодключения.ОткрытьМодально();
Если ФормаЗащиты <> Неопределено Тогда
ФормаЗащиты.Закрыть();
КонецЕсли;
Если РезультатФормы <> Истина Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Возврат ФормаПодключения;
КонецФункции
Функция ОткрытьОбщиеПараметрыЗаписиЛкс(ТолькоОбъектыНаСервере = Ложь) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Форма = мПлатформа.ПолучитьФорму("ПараметрыЗаписиОбъектов");
Форма.ПараметрТолькоОбъектыНаСервере = ТолькоОбъектыНаСервере;
Форма.ОткрытьМодально();
КонецФункции
Функция ОткрытьСсылкуИТСЛкс(СтрокаЗапуска) Экспорт
Маркер = "v?doc";
Если Найти(СтрокаЗапуска, Маркер) > 0 Тогда
ФрагментыМаркера = ирОбщий.СтрРазделитьЛкс(Маркер, "?");
СисИнфо = Новый СистемнаяИнформация;
ФрагментыВерсии = ирОбщий.СтрРазделитьЛкс(СисИнфо.ВерсияПриложения);
ТекущаяВерсия = ФрагментыВерсии[0] + "." + ФрагментыВерсии[1] + "." + ФрагментыВерсии[2];
ВыбраннаяВерсия = СтрЗаменить(ТекущаяВерсия, ".", "");
СтрокаЗапуска = ирОбщий.СтрЗаменитьЛкс(СтрокаЗапуска, Маркер, ФрагментыМаркера[0] + ВыбраннаяВерсия + ФрагментыМаркера[1]);
КонецЕсли;
ЗапуститьПриложение(СтрокаЗапуска);
КонецФункции
Процедура УстановитьДоступностьВыполненияНаСервереЛкс(ЭтаФорма, ИмяФлага = "ВыполнятьНаСервере") Экспорт
ДоступностьРежима = ЛиАсинхронностьДоступнаЛкс();
Если ЭтаФорма.ЭлементыФормы.Найти(ИмяФлага) <> Неопределено Тогда
Флажок = ЭтаФорма.ЭлементыФормы[ИмяФлага];
Флажок.Доступность = ДоступностьРежима;
Флажок.Заголовок = "Выполнять на сервере";
Флажок.Подсказка = "Недоступно в портативном варианте. " + Флажок.Подсказка;
КонецЕсли;
Если Не ДоступностьРежима Тогда
ЭтаФорма.ЭтотОбъект[ИмяФлага] = Ложь;
КонецЕсли;
КонецПроцедуры
#КонецЕсли
Функция ПредставлениеСочетанияКлавишЛкс(СочетаниеКлавиш) Экспорт
Представление = "";
Если СочетаниеКлавиш.Alt Тогда
Представление = Представление + "Alt+";
КонецЕсли;
Если СочетаниеКлавиш.Ctrl Тогда
Представление = Представление + "Ctrl+";
КонецЕсли;
Если СочетаниеКлавиш.Shift Тогда
Представление = Представление + "Shift+";
КонецЕсли;
Если Не ЗначениеЗаполнено("" + СочетаниеКлавиш.Клавиша) Тогда
Строка = ирОбщий.ОбъектВСтрокуXMLЛкс(СочетаниеКлавиш, Истина);
ОбъектXDTO = ирОбщий.ОбъектXDTOИзСтрокиXMLЛкс(Строка);
ПредставлениеКлавиши = ОбъектXDTO.Key;
Иначе
ПредставлениеКлавиши = "" + СочетаниеКлавиш.Клавиша;
КонецЕсли;
Представление = Представление + ПредставлениеКлавиши;
Возврат Представление;
КонецФункции
Функция ЦветФонаЯчеекПустыхЗначенийЛкс() Экспорт
Цвет = Новый Цвет(248, 248, 255);
Возврат Цвет;
КонецФункции
Функция ЦветФонаЯчеекТекущегоЗначенияЛкс() Экспорт
Цвет = Новый Цвет(255, 255, 210);
Возврат Цвет;
КонецФункции
// Функция - Восстановить значение лкс
//
// Параметры:
// КлючНастроек - -
// ДляВсехПользователей - -
// ХранитьНаКлиенте - Булево - при "Истина" в толстом клиенте хранить настройку на текущем компьютере, иначе - в БД
//
// Возвращаемое значение:
// -
//
Функция ВосстановитьЗначениеЛкс(КлючНастроек, ДляВсехПользователей = Ложь, Знач ХранитьНаКомпьютере = Ложь) Экспорт
#Если ТонкийКлиент Или ВебКлиент Или МобильныйКлиент Тогда
Возврат ВосстановитьЗначениеЛкс(КлючНастроек);
#Иначе
Если ХранитьНаКомпьютере Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
НастройкиКомпьютера = мПлатформа.НастройкиКомпьютера();
Результат = НастройкиКомпьютера[КлючНастроек];
Иначе
УстановитьПривилегированныйРежим(Истина);
Если Истина
И ДляВсехПользователей
И (Ложь
Или ирКэш.НомерВерсииПлатформыЛкс() < 803001
Или ПривилегированныйРежим()
Или ПравоДоступа("АдминистрированиеДанных", Метаданные))
Тогда
ИмяПользователя = ирКэш.ИмяПродукта();
Иначе
//ИмяПользователя = Неопределено; // Такое значение вызывает ошибки у нестандартных хранилищ
ИмяПользователя = ИмяПользователя();
КонецЕсли;
Результат = ХранилищеОбщихНастроек.Загрузить(ирКэш.ИмяПродукта(), КлючНастроек,, ИмяПользователя);
#Если Клиент Тогда
Если Результат = Неопределено Тогда
// Импорт из старого хранилища настроек
Результат = ВосстановитьЗначение(КлючНастроек);
Если Результат <> Неопределено Тогда
СохранитьЗначениеЛкс(КлючНастроек, Результат);
СохранитьЗначение(КлючНастроек, Неопределено);
КонецЕсли;
КонецЕсли;
#КонецЕсли
КонецЕсли;
Возврат Результат;
#КонецЕсли
КонецФункции
// Функция - Сохранить значение лкс
//
// Параметры:
// КлючНастроек - -
// Значение - -
// ДляВсехПользователей - -
// ХранитьНаКлиенте - Булево - при "Истина" в толстом клиенте хранить настройку на текущем компьютере, иначе - в БД
//
// Возвращаемое значение:
// -
//
Функция СохранитьЗначениеЛкс(КлючНастроек, Значение, ДляВсехПользователей = Ложь, Знач ХранитьНаКомпьютере = Ложь) Экспорт
#Если ТонкийКлиент Или ВебКлиент Или МобильныйКлиент Тогда
ирСервер.СохранитьЗначениеЛкс(КлючНастроек, Значение);
#Иначе
Если ХранитьНаКомпьютере Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
НастройкиКомпьютера = мПлатформа.НастройкиКомпьютера();
НастройкиКомпьютера.Вставить(КлючНастроек, Значение);
мПлатформа.СохранитьНастройкиКомпьтера();
Иначе
УстановитьПривилегированныйРежим(Истина);
Если Истина
И ДляВсехПользователей
И (Ложь
Или ирКэш.НомерВерсииПлатформыЛкс() < 803001
Или ПривилегированныйРежим()
Или ПравоДоступа("АдминистрированиеДанных", Метаданные))
Тогда
ИмяПользователя = ирКэш.ИмяПродукта();
Иначе
//ИмяПользователя = Неопределено; // Такое значение вызывает ошибки у нестандартных хранилищ
ИмяПользователя = ИмяПользователя();
КонецЕсли;
ХранилищеОбщихНастроек.Сохранить(ирКэш.ИмяПродукта(), КлючНастроек, Значение,, ИмяПользователя);
КонецЕсли;
#КонецЕсли
КонецФункции
Функция УдалитьХранимуюНастройкуЛкс(КлючНастроек, ДляВсехПользователей = Ложь) Экспорт
#Если ТонкийКлиент Или ВебКлиент Или МобильныйКлиент Тогда
ирСервер.УдалитьХранимуюНастройкуЛкс(КлючНастроек);
#Иначе
Если ДляВсехПользователей И ПравоДоступа("АдминистрированиеДанных", Метаданные) Тогда
ИмяПользователя = ирКэш.ИмяПродукта();
Иначе
//ИмяПользователя = Неопределено; // Такое значение вызывает ошибки у нестандартных хранилищ
ИмяПользователя = ИмяПользователя();
КонецЕсли;
ХранилищеОбщихНастроек.Удалить(ирКэш.ИмяПродукта(), КлючНастроек, ИмяПользователя);
#КонецЕсли
КонецФункции
Процедура ДобавитьИндексВТаблицуЛкс(ТаблицаЗначений, Знач СтрокаИлиСтруктура) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
Если ТипЗнч(СтрокаИлиСтруктура) = Тип("Структура") Тогда
// Из-за негарантированного порядка элементов можно получать разные имена одного по содержанию индекса. Поэтому могут создаваться дубли индексов
СтрокаИндекса = "";
Разделитель = ", ";
Для Каждого КлючИЗначение Из СтрокаИлиСтруктура Цикл
СтрокаИндекса = СтрокаИндекса + Разделитель + КлючИЗначение.Ключ;
КонецЦикла;
СтрокаИндекса = Сред(СтрокаИндекса, СтрДлина(Разделитель) + 1);
Иначе
СтрокаИндекса = СтрокаИлиСтруктура;
КонецЕсли;
ИндексНайден = Ложь;
Для Каждого Индекс Из ТаблицаЗначений.Индексы Цикл
Если СтрокиРавныЛкс("" + Индекс, СтрокаИндекса) Тогда
ИндексНайден = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ИндексНайден Тогда
НовыйИндекс = ТаблицаЗначений.Индексы.Добавить(СтрокаИндекса);
Если "" + НовыйИндекс <> СтрокаИндекса Тогда
ВызватьИсключение "Поля в составе индекса должны быть разделены запятой и пробелом";
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Можно ради скорости отказываться от использования этой функции
Функция ЛиПустаяПодгруппаRegExpЛкс(Подгруппа) Экспорт
Результат = Ложь
Или Подгруппа = Неопределено // наш случай
Или Подгруппа = ""; // RegExV8
Возврат Результат;
КонецФункции
Процедура ОбновитьКопиюСвойстваВНижнемРегистреЛкс(Объект, ИмяСвойства = "Имя") Экспорт
Объект["Н" + ИмяСвойства] = НРег(Объект[ИмяСвойства]);
КонецПроцедуры
Функция ПолучитьСхемуКолонокМакетаКомпоновкиДанныхЛкс(МакетКомпоновки) Экспорт
#Если Сервер И Не Сервер Тогда
МакетКомпоновки = Новый МакетКомпоновкиДанных;
#КонецЕсли
СхемаКолонок = Новый Структура;
// Схема колонок строится негарантировано, т.к. платформа не предоставляет нужных данных
ОписанияМакетовОбластей = МакетКомпоновки.Макеты;
Если ОписанияМакетовОбластей.Количество() > 0 Тогда
ЯчейкиЗаголовка = ОписанияМакетовОбластей[0].Макет.Ячейки;
Если ЯчейкиЗаголовка <> Неопределено Тогда
КоличествоЯчеекЗаголовка = ЯчейкиЗаголовка.Количество();
Для Индекс = 0 По КоличествоЯчеекЗаголовка - 1 Цикл
Для Каждого ОписаниеМакетаОбласти Из ОписанияМакетовОбластей Цикл
// Здесь подсказка криво работает из-за кривого синтакс-помощника 8.2.13.205
// http://partners.v8.1c.ru/forum/thread.jsp?id=898023#898023
ЯчейкаМакетаОбласти = ОписаниеМакетаОбласти.Макет.Ячейки[Индекс];
Если ТипЗнч(ЯчейкаМакетаОбласти) <> Тип("ЯчейкаМакетаКоллекцииЗначенийОбластиКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
ПараметрЯчейки = ЯчейкаМакетаОбласти.Значение;
Если ПараметрЯчейки = Неопределено Тогда
Продолжить;
КонецЕсли;
Выражение = ОписаниеМакетаОбласти.Параметры["" + ПараметрЯчейки].Выражение;
ПозицияТочки = Найти(Выражение, ".");
Если Ложь
Или ПозицияТочки = 0
Или Найти(Выражение, " ") > 0
Или Найти(Выражение, "(") > 0
Тогда
//ИмяПоля = "";
Продолжить;
Иначе
ИмяПоля = Сред(Выражение, ПозицияТочки + 1);
КонецЕсли;
СхемаКолонок.Вставить(ЯчейкиЗаголовка[Индекс].Имя, ИмяПоля);
Прервать;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат СхемаКолонок;
КонецФункции
Функция ТекущаяДатаЛкс(НаСервере = Ложь, КэшироватьРазницуКлиентСервера = Ложь) Экспорт
Если НаСервере Тогда
Если КэшироватьРазницуКлиентСервера Тогда
Результат = ТекущаяДата() - ирКэш.РазницаВремениКлиентСерверЛкс();
Иначе
Результат = ирСервер.ТекущаяДатаЛкс();
КонецЕсли;
Иначе
Результат = ТекущаяДата();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция РазницаВремениКлиентСерверЛкс() Экспорт
Возврат ТекущаяДатаЛкс() - ТекущаяДатаЛкс(Истина);
КонецФункции
Функция СтрокиРавныЛкс(Знач Строка1, Знач Строка2, СУчетомРегистра = Ложь, БезПравыхНепечатныхСимволов = Ложь) Экспорт
Если Ложь
//Или ирКэш.РежимОтладкиЛкс() // Закомментировано для ускорения
Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Если Не СУчетомРегистра Тогда
Строка1 = НРег(Строка1);
Строка2 = НРег(Строка2);
КонецЕсли;
Если БезПравыхНепечатныхСимволов Тогда
Строка1 = СокрП(Строка1);
Строка2 = СокрП(Строка2);
КонецЕсли;
Результат = Строка1 = Строка2;
Возврат Результат;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Если Не СУчетомРегистра Тогда Строка1 = НРег(Строка1); Строка2 = НРег(Строка2); КонецЕсли; Если БезПравыхНепечатныхСимволов Тогда Строка1 = СокрП(Строка1); Строка2 = СокрП(Строка2); КонецЕсли; Результат = Строка1 = Строка2; Возврат Результат;
КонецЕсли;
КонецФункции
// Вставляет параметры в строку, учитывая, что в параметрах могут использоваться подстановочные слова %1, %2 и т.д.
Функция ПодставитьПараметрыСПроцентомЛкс(Знач СтрокаПодстановки,
Знач Параметр1, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено,
Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено)
Результат = "";
Позиция = СтрНайтиЛкс(СтрокаПодстановки, "%");
Пока Позиция > 0 Цикл
Результат = Результат + Лев(СтрокаПодстановки, Позиция - 1);
СимволПослеПроцента = Сред(СтрокаПодстановки, Позиция + 1, 1);
ПодставляемыйПараметр = Неопределено;
Если СимволПослеПроцента = "1" Тогда
ПодставляемыйПараметр = Параметр1;
ИначеЕсли СимволПослеПроцента = "2" Тогда
ПодставляемыйПараметр = Параметр2;
ИначеЕсли СимволПослеПроцента = "3" Тогда
ПодставляемыйПараметр = Параметр3;
ИначеЕсли СимволПослеПроцента = "4" Тогда
ПодставляемыйПараметр = Параметр4;
ИначеЕсли СимволПослеПроцента = "5" Тогда
ПодставляемыйПараметр = Параметр5;
ИначеЕсли СимволПослеПроцента = "6" Тогда
ПодставляемыйПараметр = Параметр6;
КонецЕсли;
Если ПодставляемыйПараметр = Неопределено Тогда
Результат = Результат + "%";
СтрокаПодстановки = Сред(СтрокаПодстановки, Позиция + 1);
Иначе
Результат = Результат + ПодставляемыйПараметр;
СтрокаПодстановки = Сред(СтрокаПодстановки, Позиция + 2);
КонецЕсли;
Позиция = СтрНайтиЛкс(СтрокаПодстановки, "%");
КонецЦикла;
Результат = Результат + СтрокаПодстановки;
Возврат Результат;
КонецФункции
// Подставляет параметры в строку. Максимально возможное число параметров - 6.
// Параметры в строке задаются как %<номер параметра>. Нумерация параметров начинается с единицы.
//
// Параметры:
// ШаблонСтроки - Строка - шаблон строки с параметрами (вхождениями вида "%<номер параметра>",
// например "%1 пошел в %2");
// Параметр - Строка - значение подставляемого параметра.
//
// Возвращаемое значение:
// Строка - текстовая строка с подставленными параметрами.
//
// Пример:
// СтрШаблонЛкс(НСтр("ru='%1 пошел в %2'"), "Вася", "Зоопарк") = "Вася пошел в Зоопарк".
//
Функция СтрШаблонЛкс(Знач ШаблонСтроки,
Знач Параметр1, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено,
Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено) Экспорт
ЕстьПараметрыСПроцентом = СтрНайтиЛкс(Параметр1, "%")
Или СтрНайтиЛкс(Параметр2, "%")
Или СтрНайтиЛкс(Параметр3, "%")
Или СтрНайтиЛкс(Параметр4, "%")
Или СтрНайтиЛкс(Параметр5, "%")
Или СтрНайтиЛкс(Параметр6, "%");
Если ЕстьПараметрыСПроцентом Тогда
Возврат ПодставитьПараметрыСПроцентомЛкс(ШаблонСтроки, Параметр1, Параметр2, Параметр3, Параметр4, Параметр5, Параметр6);
КонецЕсли;
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%1", Параметр1);
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%2", Параметр2);
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%3", Параметр3);
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%4", Параметр4);
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%5", Параметр5);
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%6", Параметр6);
Возврат ШаблонСтроки;
КонецФункции
// Подставляет именованные параметры в строку. Максимально возможное число параметров - 6.
// Располагать поглощаемые имена следует после поглощающих, например "ЧислоБольшое, Число".
//
// Параметры:
// ШаблонСтроки - Строка - шаблон строки с параметрами (вхождениями вида "%<имя параметра>")
// Имя - Строка - имя подставляемого параметра, может начинаться с цифры
// Значение - Произвольное - значение подставляемого параметра, оно автоматчиески обрамляется кавычками, если Истина
// И не является числом или датой
// И пустое или содержит пробел или имя начинается с заглавной буквы или не буквы, кроме "0"
//
// Возвращаемое значение:
// Строка - текстовая строка с подставленными параметрами.
//
// Пример:
// СтрШаблонИменЛкс("У номенклатуры ""%Ном"" нет остатка на складке ""%Склад""", "Ном", "Ручка шариковая", "Склад", "Москва")
// = "У номенклатуры "Ручка шариковая" нет остатка на складке "Москва""
// СтрШаблонИменЛкс("У номенклатуры ""%1"" нет остатка на складке ""%2""", 1, "Ручка шариковая", 2, "Москва")
// = "У номенклатуры "Ручка шариковая" нет остатка на складке "Москва""
//
Функция СтрШаблонИменЛкс(Знач ШаблонСтроки,
Знач Имя1 = "1", Знач Значение1, Знач Имя2 = "", Знач Значение2 = Неопределено, Знач Имя3 = "", Знач Значение3 = Неопределено,
Знач Имя4 = "", Знач Значение4 = Неопределено, Знач Имя5 = "", Знач Значение5 = Неопределено, Знач Имя6 = "", Знач Значение6 = Неопределено) Экспорт
Если ЗначениеЗаполнено(Имя1) Тогда ШаблонСтроки = СтрЗаменитьЛкс(ШаблонСтроки, "%" + Имя1, ПредставлениеДляПодстановки(Значение1)) КонецЕсли;
Если ЗначениеЗаполнено(Имя2) Тогда ШаблонСтроки = СтрЗаменитьЛкс(ШаблонСтроки, "%" + Имя2, ПредставлениеДляПодстановки(Значение2)) КонецЕсли;
Если ЗначениеЗаполнено(Имя3) Тогда ШаблонСтроки = СтрЗаменитьЛкс(ШаблонСтроки, "%" + Имя3, ПредставлениеДляПодстановки(Значение3)) КонецЕсли;
Если ЗначениеЗаполнено(Имя4) Тогда ШаблонСтроки = СтрЗаменитьЛкс(ШаблонСтроки, "%" + Имя4, ПредставлениеДляПодстановки(Значение4)) КонецЕсли;
Если ЗначениеЗаполнено(Имя5) Тогда ШаблонСтроки = СтрЗаменитьЛкс(ШаблонСтроки, "%" + Имя5, ПредставлениеДляПодстановки(Значение5)) КонецЕсли;
Если ЗначениеЗаполнено(Имя6) Тогда ШаблонСтроки = СтрЗаменитьЛкс(ШаблонСтроки, "%" + Имя6, ПредставлениеДляПодстановки(Значение6)) КонецЕсли;
Возврат ШаблонСтроки;
КонецФункции
Функция ПредставлениеДляПодстановки(Знач Значение)
Если ТипЗнч(Значение) = Тип("Число") Тогда
#Если ВебКлиент Тогда
Результат = "" + Значение;
#Иначе
Результат = XMLСтрока(Значение);
#КонецЕсли
Иначе
Результат = "" + Значение;
Если Истина
И ТипЗнч(Значение) <> Тип("Дата")
И Лев(Результат, 1) <> """"
И (Ложь
Или (Истина
// Первый символ - заглавная буква или не буква, кроме "0"
И Лев(Результат, 1) <> "0"
И Лев(Результат, 1) = ВРег(Лев(Результат, 1)))
Или ПустаяСтрока(Результат)
Или Найти(Результат, " ") > 0)
Тогда
Результат = """" + Результат + """";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Функция собирает строку из элементов массива с разделителем.
//
// Параметры:
// пМассив - Массив - из которого формируем строку;
// *пРазделитель - Строка - символ-разделитель;
// КоличествоЭлементов - Число -
// НачальныйНомер - Число - с какого элемента начинать сборку
//
// Возвращаемое значение:
// Строка.
//
Функция СтрСоединитьЛкс(Знач МассивИлиСписок, пРазделитель = ", ", Знач КоличествоЭлементов = 0, НачальныйНомер = 1) Экспорт
_РежимОтладки = Ложь;
Если _РежимОтладки Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Если ТипЗнч(МассивИлиСписок) = Тип("СписокЗначений") Тогда
МассивИлиСписок = МассивИлиСписок.ВыгрузитьЗначения();
КонецЕсли;
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
Пустая = Истина;
Если КоличествоЭлементов < 0 Тогда
КоличествоЭлементов = МассивИлиСписок.Количество() + КоличествоЭлементов;
КонецЕсли;
Счетчик = 0;
Для Каждого Элемент Из МассивИлиСписок Цикл
Счетчик = Счетчик + 1;
Если Счетчик < НачальныйНомер Тогда
Продолжить;
КонецЕсли;
Если Не Пустая Тогда
ЗаписьXML.ЗаписатьБезОбработки(пРазделитель);
Иначе
Пустая = Ложь;
КонецЕсли;
ЗаписьXML.ЗаписатьБезОбработки(Строка(Элемент));
Если КоличествоЭлементов = Счетчик Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Результат = ЗаписьXML.Закрыть();
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Если ТипЗнч(МассивИлиСписок) = Тип("СписокЗначений") Тогда МассивИлиСписок = МассивИлиСписок.ВыгрузитьЗначения(); КонецЕсли; ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); Пустая = Истина; Если КоличествоЭлементов < 0 Тогда КоличествоЭлементов = МассивИлиСписок.Количество() + КоличествоЭлементов; КонецЕсли; Счетчик = 0; Для Каждого Элемент Из МассивИлиСписок Цикл Счетчик = Счетчик + 1; Если Счетчик < НачальныйНомер Тогда Продолжить; КонецЕсли; Если Не Пустая Тогда ЗаписьXML.ЗаписатьБезОбработки(пРазделитель); Иначе Пустая = Ложь; КонецЕсли; ЗаписьXML.ЗаписатьБезОбработки(Строка(Элемент)); Если КоличествоЭлементов = Счетчик Тогда Прервать; КонецЕсли; КонецЦикла; Результат = ЗаписьXML.Закрыть();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СтрокаИзВыраженияВстроенногоЯзыкаЛкс(Знач Текст) Экспорт
Текст = СтрЗаменить(Текст, """""", """");
Если Лев(Текст, 1) = """" Тогда
Текст = Сред(Текст, 2);
КонецЕсли;
Если Прав(Текст, 1) = """" Тогда
Текст = Лев(Текст, СтрДлина(Текст) - 1);
КонецЕсли;
Возврат Текст;
КонецФункции
Функция СтрокаВВыражениеВстроенногоЯзыкаЛкс(Строка) Экспорт
Результат = """" + СтрЗаменить(Строка, """", """""") + """";
Возврат Результат;
КонецФункции
Функция УдалитьВнешниеСкобкиВыраженияЛкс(Знач ОпределениеПоля, Знач ОткрывающаяСкобка = "(", Знач ЗакрывающаяСкобка = ")") Экспорт
ДлинаОткрытия = СтрДлина(ОткрывающаяСкобка);
ДлинаЗакрытия = СтрДлина(ЗакрывающаяСкобка);
Пока Истина
И Лев(ОпределениеПоля, ДлинаОткрытия) = ОткрывающаяСкобка
И Прав(ОпределениеПоля, ДлинаЗакрытия) = ЗакрывающаяСкобка
Цикл
ОпределениеПоля = Сред(ОпределениеПоля, 1 + ДлинаОткрытия, СтрДлина(ОпределениеПоля) - ДлинаОткрытия - ДлинаЗакрытия);
КонецЦикла;
Возврат ОпределениеПоля;
КонецФункции
// Поиск числа в строке
//
// Параметры:
// ИсходнаяСтрока - Строка, строка в которой ищется число
// ПозицияЧисла - Число, позиция начала числа
// КоличествоСимволов - Число, количество символов числа
//
// Возвращаемое значение:
// Булево - Истина, число найдено
//
Функция НайтиЧислоВСтрокеЛкс(ИсходнаяСтрока, выхПозицияЧисла = 0, выхКоличествоСимволов = 0) Экспорт
выхПозицияЧисла = 0;
выхКоличествоСимволов = 0;
ДлинаСтроки = СтрДлина(ИсходнаяСтрока);
Если Ложь
//Или ирКэш.РежимОтладкиЛкс() // Закомментировано для ускорения
Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
// 300000 повторов при заполнении общей таблицы полей в структуре хранения БД
Для Сч = 1 По ДлинаСтроки Цикл
ТекущийСимвол = КодСимвола(Сред(ИсходнаяСтрока, Сч, 1));
Если 48 <= ТекущийСимвол И ТекущийСимвол <= 57 Тогда
Если выхПозицияЧисла = 0 Тогда
выхПозицияЧисла = Сч;
выхКоличествоСимволов = 1;
Иначе
выхКоличествоСимволов = выхКоличествоСимволов + 1;
КонецЕсли;
Иначе
Если выхПозицияЧисла <> 0 Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Сч = 1 По ДлинаСтроки Цикл ТекущийСимвол = КодСимвола(Сред(ИсходнаяСтрока, Сч, 1)); Если 48 <= ТекущийСимвол И ТекущийСимвол <= 57 Тогда Если выхПозицияЧисла = 0 Тогда выхПозицияЧисла = Сч; выхКоличествоСимволов = 1; Иначе выхКоличествоСимволов = выхКоличествоСимволов + 1; КонецЕсли; Иначе Если выхПозицияЧисла <> 0 Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла;
КонецЕсли;
Возврат выхПозицияЧисла > 0;
КонецФункции
Функция ЭтоКорректныйСимволИмениПеременнойЛкс(Символ, Вычислитель = Неопределено) Экспорт
Если Вычислитель = Неопределено Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Вычислитель = ирКэш.ВычислительРегВыраженийЛкс();
Вычислитель.Pattern = "[" + мПлатформа.шБуква + "\d]";
КонецЕсли;
Результат = Вычислитель.Проверить(Символ);
//Код = КодСимвола(Символ, 1);
//Результат = (Код <= 57 И Код >= 48) ИЛИ (Код <= 90 И Код >= 65) ИЛИ (Код <= 122 И Код >= 97) ИЛИ (Код <= 1103 И Код >= 1040) ИЛИ Код = 95;
Возврат Результат;
КонецФункции
Функция ОписаниеОСЛкс() Экспорт
Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда
ПространствоИмен = ирКэш.ПолучитьCOMОбъектWMIЛкс();
ВыборкаОС = ПространствоИмен.ExecQuery("Select * from Win32_OperatingSystem");
Для Каждого ОперационнаяСистема Из ВыборкаОС Цикл
Прервать;
КонецЦикла;
Результат = ОперационнаяСистема.Caption;
Результат = Результат + " " + ОперационнаяСистема.OSArchitecture;
Если ОперационнаяСистема.Locale = "0419" Тогда
ОписаниеЯзыка = "Русский";
Иначе
ОписаниеЯзыка = "НеРусский-" + ОперационнаяСистема.Locale;
КонецЕсли;
Результат = Результат + " " + ОписаниеЯзыка;
Иначе
СистемнаяИнфо = Новый СистемнаяИнформация;
Результат = "" + СистемнаяИнфо.ТипПлатформы;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПроверитьКодЯзыкаОСЛкс() Экспорт
ПространствоИмен1 = ирКэш.ПолучитьCOMОбъектWMIЛкс();
ВыборкаОС = ПространствоИмен1.ExecQuery("Select * from Win32_OperatingSystem");
Для Каждого ОперационнаяСистема Из ВыборкаОС Цикл
Прервать;
КонецЦикла;
Если ОперационнаяСистема.Locale <> "0419" Тогда
ВызватьИсключение "Russian system locale (0419) in OS required for this function";
КонецЕсли;
КонецФункции
Процедура ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, НаСервере = Ложь, ВыводитьПредупрежденияИСообщения = Истина) Экспорт
#Если Клиент Тогда
Если ВыводитьПредупрежденияИСообщения Тогда
Ответ = КодВозвратаДиалога.ОК;
Если НаСервере Тогда
ОбщийРазмер = ирСервер.ВычислитьРазмерКаталогаЛкс(КаталогЖурнала);
Иначе
ОбщийРазмер = ВычислитьРазмерКаталогаЛкс(КаталогЖурнала);
КонецЕсли;
Если ОбщийРазмер > 0 Тогда
Ответ = Вопрос(СтрШаблонИменЛкс("Действительно удалить рекурсивно все файлы (%1МБ) в каталоге журнала?",, Цел(ОбщийРазмер/1000000)), РежимДиалогаВопрос.ОКОтмена);
КонецЕсли;
Если Ответ <> КодВозвратаДиалога.ОК Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Если НаСервере Тогда
ирСервер.ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, ВыводитьПредупрежденияИСообщения);
Возврат;
КонецЕсли;
#КонецЕсли
ФайлыЖурнала = НайтиФайлы(КаталогЖурнала, "*.*", Истина);
Если ФайлыЖурнала.Количество() > 0 Тогда
СчетчикНеудаленных = 0;
Для Каждого ФайлЖурнала Из ФайлыЖурнала Цикл
Попытка
УдалитьФайлы(ФайлЖурнала.ПолноеИмя);
Исключение
СчетчикНеудаленных = СчетчикНеудаленных + 1;
КонецПопытки;
КонецЦикла;
Если ВыводитьПредупрежденияИСообщения Тогда
Если СчетчикНеудаленных > 0 Тогда
СообщитьЛкс(СтрШаблонИменЛкс("%1 файлов техножурнала удалить не удалось",, СчетчикНеудаленных));
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры // ОчиститьКаталогТехножурналаЛкс()
Функция ВычислитьРазмерКаталогаЛкс(Каталог, ВключаяПодкаталоги = Истина) Экспорт
Файлы = НайтиФайлы(Каталог, "*.*", ВключаяПодкаталоги);
ОбщийРазмер = 0;
Для Каждого Файл Из Файлы Цикл
// Долго
//Если Файл.ЭтоКаталог() Тогда
// Продолжить;
//КонецЕсли;
Попытка
РазмерФайла = Файл.Размер();
Исключение
// Это каталог или нет доступа к файлу
РазмерФайла = 0;
КонецПопытки;
ОбщийРазмер = ОбщийРазмер + РазмерФайла;
КонецЦикла;
Возврат ОбщийРазмер;
КонецФункции
// Выполняет копирование файлов рекурсивно
Процедура СкопироватьФайлыЛкс(КаталогИсточник, КаталогПриемник) Экспорт
Файлы = НайтиФайлы(КаталогИсточник, "*.*");
Разделитель = РазделительПутиКФайлуЛкс();
Для Каждого Файл Из Файлы Цикл
ФайлПриемник = Новый Файл(КаталогПриемник + Разделитель + Файл.Имя);
Если Файл.ЭтоКаталог() Тогда
СоздатьКаталог(ФайлПриемник.ПолноеИмя);
СкопироватьФайлыЛкс(Файл.ПолноеИмя, ФайлПриемник.ПолноеИмя);
Продолжить;
КонецЕсли;
КопироватьФайл(Файл.ПолноеИмя, ФайлПриемник.ПолноеИмя);
КонецЦикла;
КонецПроцедуры
Функция РазделительПутиКФайлуЛкс() Экспорт
Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда
Разделитель = "\";
Иначе
Разделитель = "/";
КонецЕсли;
Возврат Разделитель;
КонецФункции
Процедура УстановитьПометкиРодителейЛкс(Знач Родитель, Знач ИмяДанныхФлажка = "Пометка", НезависимыйРодитель = Ложь) Экспорт
Если Родитель = Неопределено Тогда
Возврат;
КонецЕсли;
ТекСостояние = Родитель[ИмяДанныхФлажка];
НайденыВключенные = Ложь;
НайденыВыключенные = Ложь;
Для каждого Строка из Родитель.Строки Цикл
ЗначениеФлажка = Строка[ИмяДанныхФлажка];
Если ЗначениеФлажка = 0 Тогда
НайденыВыключенные = Истина;
ИначеЕсли ЗначениеФлажка = 1 Тогда
НайденыВключенные = Истина;
ИначеЕсли ЗначениеФлажка = 2 Тогда
НайденыВключенные = Истина;
НайденыВыключенные = Истина;
Прервать;
КонецЕсли;
Если НайденыВключенные И НайденыВыключенные Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если НезависимыйРодитель Тогда
Если НайденыВключенные Тогда
Включить = 2;
КонецЕсли;
Иначе
Если НайденыВключенные И НайденыВыключенные Тогда
Включить = 2;
ИначеЕсли НайденыВключенные И Не НайденыВыключенные Тогда
Включить = 1;
ИначеЕсли Не НайденыВключенные И НайденыВыключенные Тогда
Включить = 0;
ИначеЕсли Не НайденыВключенные И Не НайденыВыключенные Тогда
Включить = 2;
КонецЕсли;
КонецЕсли;
Если Включить = ТекСостояние Тогда
Возврат;
Иначе
Если Родитель[ИмяДанныхФлажка] <> 1 Или Не НезависимыйРодитель Тогда
Родитель[ИмяДанныхФлажка] = Включить;
УстановитьПометкиРодителейЛкс(Родитель.Родитель, ИмяДанныхФлажка);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура УстановитьПометкиПодчиненныхЛкс(Знач ТекСтрока, Знач ИмяДанныхФлажка = "Пометка") Экспорт
ТекСостояние = ТекСтрока[ИмяДанныхФлажка];
Подчиненные = ТекСтрока.Строки;
Если ТекСостояние = 2 Тогда
ТекСтрока[ИмяДанныхФлажка] = 0;
КонецЕсли;
Если Подчиненные.Количество() > 0 Тогда
Для каждого Строка из Подчиненные Цикл
Строка[ИмяДанныхФлажка] = ТекСостояние;
УстановитьПометкиПодчиненныхЛкс(Строка, ИмяДанныхФлажка);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция ЛиСпискиПодсистемПересекаютсяЛкс(ФильтрПодсистем, СписокПодсистем) Экспорт
Если ТипЗнч(ФильтрПодсистем) = Тип("Строка") Тогда
СписокФильтра = Новый СписокЗначений;
СписокФильтра.Добавить(ФильтрПодсистем);
КонецЕсли;
Если Ложь
Или СписокФильтра.Количество() = 0
Или СписокФильтра[0] = ""
Тогда
Возврат Истина;
КонецЕсли;
Для Каждого Подсистема Из СписокПодсистем Цикл
Если ТипЗнч(Подсистема) = Тип("ОбъектМетаданных") Тогда
ИмяПодсистемы = Подсистема.ПолноеИмя();
Иначе
ИмяПодсистемы = Подсистема.Значение;
КонецЕсли;
Если СписокФильтра.НайтиПоЗначению(ИмяПодсистемы) <> Неопределено Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
// Разбирает строку на две части: до подстроки разделителя и после
//
// Параметры:
// Стр - разбираемая строка
// Разделитель - подстрока-разделитель
// Режим - 0 - разделитель в возвращаемые подстроки не включается
// 1 - разделитель включается в левую подстроку
// 2 - разделитель включается в правую подстроку
//
// Возвращаемое значение:
// Правая часть строки - до символа-разделителя
//
Функция ОтделитьРазделителемЛкс(Знач Стр, Знач Разделитель = ".", Режим = 0) Экспорт
ПраваяЧасть = "";
ПозРазделителя = Найти(Стр, Разделитель);
ДлинаРазделителя = СтрДлина(Разделитель);
Если ПозРазделителя > 0 Тогда
ПраваяЧасть = Сред(Стр, ПозРазделителя + ?(Режим=2, 0, ДлинаРазделителя));
Стр = СокрЛП(Лев(Стр, ПозРазделителя - ?(Режим=1, -ДлинаРазделителя+1, 1)));
КонецЕсли;
Возврат(ПраваяЧасть);
КонецФункции // вОтделитьРазделителем()
// Проверяет попадание даты внутрь интервала всключая границы
Функция ЛиДатаВИнтервалеСГраницамиЛкс(ПроверяемаяДата, НачалоПериода, КонецПериода) Экспорт
ЛиДатаВНеИнтервале = Ложь
Или (Истина
И ЗначениеЗаполнено(НачалоПериода)
И ПроверяемаяДата < НачалоПериода)
Или (Истина
И ЗначениеЗаполнено(КонецПериода)
И ПроверяемаяДата > КонецПериода);
Возврат Не ЛиДатаВНеИнтервале;
КонецФункции
// Проверяет попадание даты внутрь интервала исключая границы
Функция ЛиДатаВИнтервалеБезГраницЛкс(ПроверяемаяДата, НачалоПериода, КонецПериода) Экспорт
ПустаяДата = Дата("00010101");
ЛиДатаВНеИнтервале = Ложь
Или (Истина
И НачалоПериода <> ПустаяДата
И ПроверяемаяДата <= НачалоПериода)
Или (Истина
И КонецПериода <> ПустаяДата
И ПроверяемаяДата >= КонецПериода);
Возврат Не ЛиДатаВНеИнтервале;
КонецФункции
Функция ЛиСобытиеОшибкиФоновогоЗаданияЛкс(ИмяСобытияЖурнала) Экспорт
Результат = Ложь
Или ИмяСобытияЖурнала = "_$Job$_.Fail"
Или ИмяСобытияЖурнала = "_$Job$_.Error";
Возврат Результат;
КонецФункции
Функция ЛиСобытиеУспехаФоновогоЗаданияЛкс(ИмяСобытияЖурнала) Экспорт
Результат = Ложь
Или ИмяСобытияЖурнала = "_$Job$_.Finish"
Или ИмяСобытияЖурнала = "_$Job$_.Succeed";
Возврат Результат;
КонецФункции
Функция ЛиКаталогДоступенЛкс(Каталог, ВыводитьСообщения = Истина) Экспорт
ПроверочныйФайл = Новый Файл(Каталог);
Попытка
ЭтоКаталог = ПроверочныйФайл.ЭтоКаталог();
Исключение
Если ВыводитьСообщения Тогда
СообщитьЛкс(СтрШаблонИменЛкс("Указанный путь %1 не доступен: " + ОписаниеОшибки(),, Каталог));
КонецЕсли;
Возврат Ложь;
КонецПопытки;
Если Не ЭтоКаталог Тогда
Если ВыводитьСообщения Тогда
СообщитьЛкс(СтрШаблонИменЛкс("Указанный путь %1 не является каталогом",, Каталог));
КонецЕсли;
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции
// http://www.hostedredmine.com/issues/882395
// Параметры:
// ПоказатьОповещениеВУП - Булево - показать оповещение в управляемом приложении - применяется при отказе от открытия формы
// ВывестиОперативноВУП - Булево - сообщение в управляемом приложении будет сначала отображено в спец. окне для отображения в реальном времени. Может приводиться к исчезновению сообщений сразу после закрытия формы
Процедура СообщитьЛкс(Знач ТекстСообщения, Знач Статус = Неопределено, Знач ТолькоВоВременноеОкно = Ложь, Знач ПоказатьОповещениеВУП = Ложь, Знач ВывестиОперативноВУП = Истина) Экспорт
Если Не ЗначениеЗаполнено(ТекстСообщения) Тогда
Возврат;
КонецЕсли;
ВывестиСообщениеВСпецОкно = Ложь;
#Если Не ВебКлиент И Не ТонкийКлиент Тогда
МодальныеГруппы = МодальныеГруппыЛкс();
Если ирКэш.ЛиСеансТолстогоКлиентаУПЛкс() Тогда
Если ПоказатьОповещениеВУП Тогда
#Если Клиент Тогда
ПоказатьОповещениеПользователя(,, ТекстСообщения);
#КонецЕсли
КонецЕсли;
Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда
ВывестиСообщениеВСпецОкно = ВывестиОперативноВУП;
Иначе
// https://www.hostedredmine.com/issues/927508
КонецЕсли;
Иначе
ВывестиСообщениеВСпецОкно = МодальныеГруппы.Количество() > 0;
КонецЕсли;
Если ВывестиСообщениеВСпецОкно Тогда
ПрефиксВажности = "";
Если Статус = СтатусСообщения.Внимание Тогда
ПрефиксВажности = "! ";
ИначеЕсли Статус = СтатусСообщения.Важное Тогда
ПрефиксВажности = "!! ";
ИначеЕсли Статус = СтатусСообщения.ОченьВажное Тогда
ПрефиксВажности = "!!! ";
КонецЕсли;
МодальнаяГруппа = МодальныеГруппы.Количество();
#Если ТолстыйКлиентУправляемоеПриложение Тогда
АктивноеОтдельноеОкноОС = АктивноеОтдельноеОкноОСЛкс();
Если АктивноеОтдельноеОкноОС <> Неопределено Тогда
// Без этого сообщение попадет в никуда https://www.hostedredmine.com/issues/947572
МодальнаяГруппа = Макс(1, МодальнаяГруппа);
КонецЕсли;
#КонецЕсли
Форма = ирКэш.ОкноСообщенийЛкс(МодальнаяГруппа);
Форма.ВывестиСообщениеЛкс(ПрефиксВажности + ТекстСообщения);
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если АктивноеОтдельноеОкноОС <> Неопределено И АктивноеОтдельноеОкноОСЛкс() = Неопределено Тогда
АктивноеОтдельноеОкноОС.Активизировать();
КонецЕсли;
#КонецЕсли
КонецЕсли;
#КонецЕсли
Если Не ТолькоВоВременноеОкно Тогда
Сообщить(ТекстСообщения, Статус);
КонецЕсли;
КонецПроцедуры
Функция МодальныеГруппыЛкс() Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
МодальныеГруппы = мПлатформа.МодальныеГруппы;
Возврат МодальныеГруппы;
КонецФункции
Функция ЛиЕстьМодальныеГруппыЛкс() Экспорт
Результат = ирОбщий.МодальныеГруппыЛкс().Количество() > 0;
Возврат Результат;
КонецФункции
Функция АктивноеОтдельноеОкноОСЛкс()
Результат = Неопределено;
#Если ТолстыйКлиентУправляемоеПриложение Тогда
АктивноеОкно = АктивноеОкно();
Если АктивноеОкно <> Неопределено И АктивноеОкно.Содержимое.Количество() = 0 Тогда
Результат = АктивноеОкно;
КонецЕсли;
#КонецЕсли
Возврат Результат;
КонецФункции
Процедура СостояниеЛкс(Знач СтрокаСостояния = "", РазрешитьПрерывание = Ложь, ЭтоСостояниеИндикатора = Ложь) Экспорт
Если Не ЭтоСостояниеИндикатора Тогда
ирПлатформа = ирКэш.Получить();
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
Если ТаблицаИндикаторов.Количество() > 0 Тогда
Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1];
Если ЗначениеЗаполнено(СтрокаСостояния) Тогда
СтрокаСостояния = Символы.ПС + СтрокаСостояния;
КонецЕсли;
СтрокаСостояния = Индикатор.ТекстСостояния + ". " + СтрокаСостояния;
КонецЕсли;
КонецЕсли;
Если РазрешитьПрерывание Тогда
СтрокаСостояния = СтрокаСостояния + ". Прервать Ctrl+Break";
КонецЕсли;
#Если Клиент Тогда
ИспользуемПояснение = Ложь;
Если ирКэш.ЛиСеансТолстогоКлиентаУПЛкс() Тогда
Если Не ЗначениеЗаполнено(СтрокаСостояния) Тогда
Возврат;
КонецЕсли;
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803017 Тогда
// http://www.hostedredmine.com/issues/875446
ИспользуемПояснение = Истина;
КонецЕсли;
КонецЕсли;
Если ИспользуемПояснение Тогда
Состояние(,, СтрокаСостояния);
Иначе
Состояние(СтрокаСостояния);
КонецЕсли;
#КонецЕсли
КонецПроцедуры
Функция ФильтрДляВыбораФайлаЛкс(Знач СписокРасширений, ОписаниеФормата = "", РазрешитьВсеФайлы = Истина) Экспорт
ТребоватьТипЛкс(СписокРасширений, "СписокРасширений", Тип("Строка"), Тип("СписокЗначений"));
Если ТипЗнч(СписокРасширений) = Тип("Строка") Тогда
МассивРасширений = СтрРазделитьЛкс(СписокРасширений, ",", Истина);
СписокРасширений = Новый СписокЗначений;
СписокРасширений.ЗагрузитьЗначения(МассивРасширений);
КонецЕсли;
Результат = "";
ВсеПоддерживаемые1 = "";
Для Каждого ЭлементСписка Из СписокРасширений Цикл
Расширение = ЭлементСписка.Значение;
Если ЗначениеЗаполнено(ЭлементСписка.Представление) Тогда
ОписаниеФорматаЦикл = ЭлементСписка.Представление;
Иначе
ОписаниеФорматаЦикл = ОписаниеФормата;
КонецЕсли;
Если Результат <> "" Тогда
Результат = Результат + "|";
ВсеПоддерживаемые1 = ВсеПоддерживаемые1 + ";";
КонецЕсли;
ВсеПоддерживаемые1 = ВсеПоддерживаемые1 + "*." + Расширение;
ОписаниеРасширения = "(*." + Расширение + ")|*." + Расширение;
Если ЗначениеЗаполнено(ОписаниеФорматаЦикл) Тогда
ОписаниеРасширения = ОписаниеФорматаЦикл + " " + ОписаниеРасширения;
КонецЕсли;
Результат = Результат + ОписаниеРасширения;
КонецЦикла;
Если СписокРасширений.Количество() > 1 Тогда
ОписаниеРасширения = "Все поддерживаемые (" + ВсеПоддерживаемые1 + ")|" + ВсеПоддерживаемые1;
Результат = ОписаниеРасширения + "|" + Результат;
КонецЕсли;
Если РазрешитьВсеФайлы Тогда
Результат = Результат + "|Все файлы (*.*)|*.*";
КонецЕсли;
Возврат Результат;
КонецФункции
// Копирует все элементы переданного массива, структуры, соответствия, списка значений или коллекции объектов метаданных
// в однотипную коллекцию приемник (для метаданных в массив). Если коллекция приемник не указана, она будет создана.
// Фиксированные коллекции превращаются в нефиксированные.
//
// Параметры:
// КоллекцияИсходная - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - исходная коллекция;
// КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных, *Неопределено - коллекция приемник.
//
// Возвращаемое значение:
// КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - коллекция приемник.
//
Функция СкопироватьУниверсальнуюКоллекциюЛкс(КоллекцияИсточник, КоллекцияПриемник = Неопределено) Экспорт
Если КоллекцияИсточник <> Неопределено И КоллекцияИсточник = КоллекцияПриемник Тогда
ВызватьИсключение "Нельзя загружать коллекцию в саму себя";
КонецЕсли;
ТипКоллекции = ТипЗнч(КоллекцияИсточник);
Если Ложь
Или ТипКоллекции = Тип("Массив")
Или ТипКоллекции = Тип("ФиксированныйМассив")
#Если Не ТонкийКлиент И Не ВебКлиент Тогда
Или ТипКоллекции = Тип("КоллекцияОбъектовМетаданных")
#КонецЕсли
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Массив;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Добавить(Элемент);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли Ложь
Или ТипКоллекции = Тип("Структура")
Или ТипКоллекции = Тип("ФиксированнаяСтруктура")
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Структура;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли Ложь
Или ТипКоллекции = Тип("Соответствие")
Или ТипКоллекции = Тип("ФиксированноеСоответствие")
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Соответствие;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли ТипКоллекции = Тип("СписокЗначений") Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый СписокЗначений;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
ЗаполнитьЗначенияСвойств(КоллекцияПриемник.Добавить(), Элемент);
КонецЦикла;
Возврат КоллекцияПриемник;
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
ИначеЕсли ТипКоллекции = Тип("ТаблицаЗначений") Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = КоллекцияИсточник.СкопироватьКолонки();
КонецЕсли;
ЗагрузитьВТаблицуЗначенийЛкс(КоллекцияИсточник, КоллекцияПриемник);
Возврат КоллекцияПриемник;
#КонецЕсли
Иначе
СообщитьЛкс(СтрШаблонИменЛкс("Неверный тип универсальной коллекции для копирования %1",, ТипКоллекции));
Возврат Неопределено;
КонецЕсли;
КонецФункции
Функция ЛиОтборУстановленЛкс(Отбор) Экспорт
Если ТипЗнч(Отбор) = Тип("Отбор") Тогда
ЭлементыОтбора = Отбор;
Иначе
ЭлементыОтбора = Отбор.Элементы;
КонецЕсли;
Для Каждого ЭлементОтбора Из ЭлементыОтбора Цикл
Если ЭлементОтбора.Использование Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
Функция ЛиЗначениеПроходитЭлементОтбораЛкс(Знач ЭлементОтбора, Знач Значение) Экспорт
#Если Сервер И Не Сервер Тогда
ЭлементОтбора = Новый НастройкиКомпоновкиДанных;
ЭлементОтбора = ЭлементОтбора.Отбор.Элементы.Добавить();
#КонецЕсли
Если ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно Тогда
Результат = Значение = ЭлементОтбора.ПравоеЗначение;
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно Тогда
Результат = Значение <> ЭлементОтбора.ПравоеЗначение;
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке Тогда
Результат = ЭлементОтбора.ПравоеЗначение.НайтиПоЗначению(Значение) <> Неопределено;
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит Тогда
Результат = Найти(Значение, ЭлементОтбора.ПравоеЗначение) > 0;
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеВСписке Тогда
Результат = ЭлементОтбора.ПравоеЗначение.НайтиПоЗначению(Значение) = Неопределено;
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НачинаетсяС Тогда
Результат = Найти(Значение, ЭлементОтбора.ПравоеЗначение) = 1;
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеНачинаетсяС Тогда
Результат = Найти(Значение, ЭлементОтбора.ПравоеЗначение) <> 1;
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Заполнено Тогда
Результат = ЗначениеЗаполнено(Значение)
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено Тогда
Результат = Не ЗначениеЗаполнено(Значение);
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Больше Тогда
Результат = Значение > ЭлементОтбора.ПравоеЗначение;
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.БольшеИлиРавно Тогда
Результат = Значение >= ЭлементОтбора.ПравоеЗначение;
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Меньше Тогда
Результат = Значение < ЭлементОтбора.ПравоеЗначение;
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.МеньшеИлиРавно Тогда
Результат = Значение <= ЭлементОтбора.ПравоеЗначение;
Иначе
ВызватьИсключение "Не поддерживаемый вид сравнения - " + ЭлементОтбора.ВидСравнения;
КонецЕсли;
Возврат Результат;
КонецФункции
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
////////////////////////////////////
// Задания форм
Функция НайтиПоСсылкамЛкс(СсылкиНа, МоментНачала = Неопределено, АдресРезультата = Неопределено, ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = Неопределено, РазрешитьАсинхронно = Ложь,
Перезапустить = Ложь, БлокируемыеЭлементыФормы = Неопределено) Экспорт
Если Ложь
Или Кнопка = Неопределено
Или ЭтаФорма = Неопределено
Или РазрешитьАсинхронно = Ложь
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
СостояниеЛкс("Поиск ссылок…");
ТаблицаСсылок = ирПривилегированный.НайтиПоСсылкамЛкс(СсылкиНа);
СостояниеЛкс("");
Результат = Новый Структура;
Результат.Вставить("ТаблицаСсылок", ТаблицаСсылок);
Результат.Вставить("МоментНачала", МоментНачала);
Результат.Вставить("СсылкиНа", СсылкиНа);
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
Иначе
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(СсылкиНа);
ПараметрыЗадания.Добавить(МоментНачала);
ПараметрыЗадания.Добавить(АдресРезультата);
Для Счетчик = 1 По 6 Цикл
ПараметрыЗадания.Добавить(Неопределено); // Необязательные параметры
КонецЦикла;
Представление = "Ссылки на " + РасширенноеПредставлениеЗначенияЛкс(СсылкиНа);
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс("СсылкиНа", "ирОбщий.НайтиПоСсылкамЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения, АдресРезультата,, БлокируемыеЭлементыФормы);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания, Перезапустить);
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ИмяКлючевойКолонки - Строка - содержит имя таблицы
//
Функция ВычислитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоИлиТаблицаМетаданных = Неопределено, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок",
ЛиТаблицыИзменений = Ложь, СтруктураОтбора = Неопределено, ТолькоРазрешенные = Ложь, Конфигурация = Неопределено, ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = "",
Знач РазрешитьАсинхронно = Истина, Знач Перезапустить = Ложь) Экспорт
БазыДанных = Новый Структура;
БазыДанных.Вставить("ЭтаБД", Новый Массив);
Если Истина
И ирКэш.ДоступныВнешниеИсточникДанныхЛкс()
И Не ЛиТаблицыИзменений
И СтруктураОтбора = Неопределено
Тогда
Для Каждого ВнешнийИсточникДанных Из Метаданные.ВнешниеИсточникиДанных Цикл
БазыДанных.Вставить(ВнешнийИсточникДанных.Имя, Новый Массив);
КонецЦикла;
КонецЕсли;
КлючамиЗаданыИменаТаблиц = Истина; // Иначе ключами заданы имена метаданных
Если ТипЗнч(Конфигурация) = Тип("COMОбъект") Тогда
#Если Сервер И Не Сервер Тогда
ДеревоИлиТаблицаМетаданных = Обработки.ирКлсПолеТекстаПрограммы.Создать().ДоступныеТаблицы;
#КонецЕсли
БазыДанных["ЭтаБД"] = ДеревоИлиТаблицаМетаданных.ВыгрузитьКолонку("ПолноеИмя");
РазрешитьАсинхронно = Ложь;
ИначеЕсли ТипЗнч(ДеревоИлиТаблицаМетаданных) = Тип("ДеревоЗначений") Тогда
#Если Сервер И Не Сервер Тогда
ДеревоИлиТаблицаМетаданных = Новый ДеревоЗначений;
#КонецЕсли
ЕстьКолонкаЕстьДоступ = ДеревоИлиТаблицаМетаданных.Колонки.Найти("ЕстьДоступ") <> Неопределено;
Для Каждого СтрокаДерева1 Из ДеревоИлиТаблицаМетаданных.Строки Цикл
Для Каждого СтрокаДерева2 Из СтрокаДерева1.Строки Цикл
КорневойТип = ПервыйФрагментЛкс(СтрокаДерева2[ИмяКлючевойКолонки]);
Если Ложь
//Или КорневойТип = "ВнешнийИсточникДанных"
Или КорневойТип = "РегламентноеЗадание"
Или КорневойТип = "ОбщаяФорма"
Или КорневойТип = "Интерфейс"
Или КорневойТип = "Отчет"
Или КорневойТип = "Обработка"
Или КорневойТип = "КритерийОтбора"
Или (ЕстьКолонкаЕстьДоступ И СтрокаДерева2.ЕстьДоступ = Ложь)
Тогда
Продолжить;
КонецЕсли;
ИмяТаблицы = СтрокаДерева2[ИмяКлючевойКолонки];
Если Не ЗначениеЗаполнено(ИмяТаблицы) Тогда
// Например нет доступа к таблице
Продолжить;
КонецЕсли;
Если Не ЕстьКолонкаЕстьДоступ Тогда
ОписаниеТаблицы = ОписаниеТаблицыБДЛкс(ИмяТаблицы);
Если ОписаниеТаблицы.ЕстьДоступ = Ложь Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
//ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ИмяТаблицы);
//Если ОбъектМД = Неопределено Тогда
// Продолжить;
//КонецЕсли;
Если КорневойТип = "ВнешнийИсточникДанных" Тогда
ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ИмяТаблицы);
Если ОбъектМД = Неопределено Тогда
Продолжить;
КонецЕсли;
МассивКлючей = БазыДанных[ОбъектМД.Родитель().Имя];
Иначе
МассивКлючей = БазыДанных.ЭтаБД;
КонецЕсли;
МассивКлючей.Добавить(ИмяТаблицы);
Для Каждого СтрокаДерева3 Из СтрокаДерева2.Строки Цикл
Если ЕстьКолонкаЕстьДоступ И СтрокаДерева3.ЕстьДоступ = Ложь Тогда
Продолжить;
КонецЕсли;
ИмяДочернейТаблицы = СтрокаДерева3[ИмяКлючевойКолонки];
Если Не ЕстьКолонкаЕстьДоступ Тогда
ОписаниеТаблицы = ОписаниеТаблицыБДЛкс(ИмяДочернейТаблицы);
Если ОписаниеТаблицы.ЕстьДоступ = Ложь Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
МассивКлючей.Добавить(ИмяДочернейТаблицы);
КонецЦикла;
КонецЦикла;
КонецЦикла;
КлючамиЗаданыИменаТаблиц = Ложь;
Иначе
ТаблицаВсехТаблицБД = ирКэш.ТаблицаВсехТаблицБДЛкс();
#Если Сервер И Не Сервер Тогда
ТаблицаВсехТаблицБД = Новый ТаблицаЗначений;
#КонецЕсли
Для Каждого КлючИЗначение Из БазыДанных Цикл
Если КлючИЗначение.Ключ = "ЭтаБД" Тогда
ИмяСхемы = "";
Иначе
ИмяСхемы = КлючИЗначение.Ключ;
КонецЕсли;
Если ИмяКлючевойКолонки = "ПолноеИмяКолонки" Тогда // Грязно
ЛокальныеКолонки = Новый Массив;
Для Каждого СтрокаКолонкиБД Из ДеревоИлиТаблицаМетаданных Цикл
Если Ложь
Или СтрокаКолонкиБД.ТипТаблицы = "Внешняя"
Тогда
Продолжить;
КонецЕсли;
ЛокальныеКолонки.Добавить(СтрокаКолонкиБД[ИмяКлючевойКолонки]);
КонецЦикла;
БазыДанных[КлючИЗначение.Ключ] = ЛокальныеКолонки;
Иначе
ЛокальныеТаблицы = ТаблицаВсехТаблицБД.Скопировать(Новый Структура("Схема", ИмяСхемы), "ПолноеИмя, Тип, ЕстьДоступ");
НачальноеКоличество = ЛокальныеТаблицы.Количество();
Для СчетчикЛокальныеТаблицы = 1 По НачальноеКоличество Цикл
ОписаниеТаблицы = ЛокальныеТаблицы[НачальноеКоличество - СчетчикЛокальныеТаблицы];
Если Ложь
Или ОписаниеТаблицы.Тип = "ВиртуальнаяТаблица"
Или ОписаниеТаблицы.Тип = "КритерийОтбора"
Или ОписаниеТаблицы.ЕстьДоступ = Ложь
Тогда
ЛокальныеТаблицы.Удалить(ОписаниеТаблицы);
КонецЕсли;
КонецЦикла;
БазыДанных[КлючИЗначение.Ключ] = ЛокальныеТаблицы.ВыгрузитьКолонку("ПолноеИмя"); // Опасно
КонецЕсли;
КонецЦикла;
КонецЕсли;
ЕстьНепустыеЗапросы = Ложь;
Для Каждого КлючИЗначение Из БазыДанных Цикл
ТекстПакета = Новый ЗаписьXML;
ТекстПакета.УстановитьСтроку();
ЛиТекстПакетаПустой = Истина;
ТекстЗапроса = Неопределено;
СчетчикТаблиц = 0;
Для Каждого ПолноеИмяМД Из КлючИЗначение.Значение Цикл
Если ИмяКлючевойКолонки = "ПолноеИмяКолонки" Тогда // Грязно
СтруктураОтбораЛ = Новый Структура;
СтруктураОтбораЛ.Вставить("ИмяПоля", ПоследнийФрагментЛкс(ПолноеИмяМД));
СтруктураОтбораЛ.Вставить("ИмяПараметра", "ЗначениеОтбора");
СтруктураОтбораЛ.Вставить("ВидСравнения", СтруктураОтбора.ВидСравнения);
ПолноеИмяМД = СтрокаБезПоследнегоФрагментаЛкс(ПолноеИмяМД);
Иначе
СтруктураОтбораЛ = СтруктураОтбора;
КонецЕсли;
ТекстЧастиОбъединения = ПолучитьТекстЗапросаСтатистикиПоТаблицеЛкс(ПолноеИмяМД, ИмяКлючевойКолонки, ИмяКолонкиКоличества, ЛиТаблицыИзменений, СтруктураОтбораЛ, ТолькоРазрешенные,
КлючамиЗаданыИменаТаблиц);
Если ТекстЧастиОбъединения = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ТекстЗапроса <> Неопределено Тогда
ТекстЗапроса.ЗаписатьБезОбработки("
|UNION ALL");
Иначе
ТекстЗапроса = Новый ЗаписьXML;
ТекстЗапроса.УстановитьСтроку();
КонецЕсли;
ТекстЗапроса.ЗаписатьБезОбработки(ТекстЧастиОбъединения);
СчетчикТаблиц = СчетчикТаблиц + 1;
Если СчетчикТаблиц = 255 Тогда
СчетчикТаблиц = 0;
Если Не ЛиТекстПакетаПустой Тогда
ТекстПакета.ЗаписатьБезОбработки("
|;");
Иначе
ЛиТекстПакетаПустой = Ложь;
КонецЕсли;
ТекстПакета.ЗаписатьБезОбработки(ТекстЗапроса.Закрыть());
ТекстЗапроса = Неопределено;
КонецЕсли;
КонецЦикла;
Если ТекстЗапроса <> Неопределено Тогда
Если Не ЛиТекстПакетаПустой Тогда
ТекстПакета.ЗаписатьБезОбработки("
|;");
КонецЕсли;
ТекстПакета.ЗаписатьБезОбработки(ТекстЗапроса.Закрыть());
КонецЕсли;
БазыДанных[КлючИЗначение.Ключ] = ТекстПакета.Закрыть(); // Опасно
Если Не ЛиТекстПакетаПустой Тогда
ЕстьНепустыеЗапросы = Истина;
КонецЕсли;
КонецЦикла;
Если ЗначениеЗаполнено(ЕстьНепустыеЗапросы) Тогда
Если Ложь
Или РазрешитьАсинхронно = Ложь
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
Результат = ВыполнитьЗапросСтатистикиПоТаблицамЛкс(БазыДанных, СтруктураОтбора, ИмяКолонкиКоличества, Конфигурация);
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
КонецЕсли;
Иначе
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(БазыДанных);
ПараметрыЗадания.Добавить(СтруктураОтбора);
ПараметрыЗадания.Добавить(ИмяКолонкиКоличества);
ПараметрыЗадания.Добавить(АдресРезультата);
Представление = "Сбор статистики таблиц";
#Если Сервер И Не Сервер Тогда
ирСервер.ВыполнитьЗапросСтатистикиПоТаблицамЛкс();
#КонецЕсли
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс("Выгрузка", "ирСервер.ВыполнитьЗапросСтатистикиПоТаблицамЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения,
АдресРезультата);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания, Перезапустить);
КонецЕсли;
Иначе
Результат = Новый Массив();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ВыполнитьЗапросСтатистикиПоТаблицамЛкс(Знач БазыДанных, Знач СтруктураОтбора = Неопределено, Знач ИмяКолонкиКоличества = "КоличествоСтрок", Знач Конфигурация = Неопределено) Экспорт
КонсольЗапросов = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
БазыДанных = Новый Структура;
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
#Если Клиент Тогда
СостояниеЛкс("Сбор статистики таблиц…");
#КонецЕсли
Результат = Новый Массив();
Для Каждого КлючИЗначение Из БазыДанных Цикл
Если Не ЗначениеЗаполнено(КлючИЗначение.Значение) Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(Конфигурация) = Тип("COMОбъект") Тогда
Запрос = Новый COMОбъект("ADODB.Command");
Запрос.ActiveConnection = Конфигурация;
Запрос.CommandText = СтрЗаменить(КлючИЗначение.Значение, """", "'");
Попытка
РезультатЗапроса = Запрос.Execute();
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
Продолжить;
КонецПопытки;
Пока Истина Цикл
Результат.Добавить(ирОбщий.РезультатЗапросаADOВТаблицуЗначенийОбщийЛкс(РезультатЗапроса));
лРезультат = РезультатЗапроса.NextRecordset();
Если лРезультат = Неопределено Тогда
Прервать;
КонецЕсли;
РезультатЗапроса = лРезультат;
КонецЦикла;
Иначе
Запрос = Новый Запрос;
Если СтруктураОтбора <> Неопределено Тогда
СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураОтбора, Запрос.Параметры);
КонецЕсли;
Запрос.Текст = КлючИЗначение.Значение;
Попытка
РезультатПакета = Запрос.ВыполнитьПакет();
Исключение
Если КлючИЗначение.Ключ = "ЭтаБД" Тогда
ВызватьИсключение;
КонецЕсли;
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
// Это внешняя БД
Продолжить;
КонецПопытки;
Для Каждого РезультатЗапроса Из РезультатПакета Цикл
Результат.Добавить(РезультатЗапроса.Выгрузить());
КонецЦикла;
Если Истина
И Не ирКэш.ЭтоФоновоеЗаданиеЛкс()
И СтруктураОтбора = Неопределено
И КлючИЗначение.Ключ = "ЭтаБД"
Тогда
ЗаполнитьКоличестваСтрокВТаблицеВсехТаблицЛкс(Результат, ИмяКолонкиКоличества);
КонецЕсли;
КонецЕсли;
КонецЦикла;
#Если Клиент Тогда
СостояниеЛкс("");
#КонецЕсли
Возврат Результат;
КонецФункции
Процедура ЗаполнитьКоличестваСтрокВТаблицеВсехТаблицЛкс(Знач РезультатыЗапросов, Знач ИмяКолонкиКоличества = "КоличествоСтрок") Экспорт
СписокТаблиц = ирКэш.ТаблицаВсехТаблицБДЛкс();
Для Каждого ТаблицаРезультата Из РезультатыЗапросов Цикл
Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл
ОписаниеТаблицы = СписокТаблиц.Найти(НРег(СтрокаРезультата.ИмяТаблицы), "НПолноеИмя");
ОписаниеТаблицы.КоличествоСтрок = СтрокаРезультата[ИмяКолонкиКоличества];
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция ВыполнитьЗапросЛкс(ТекстЗапроса, Параметры = Неопределено, МоментНачала = Неопределено, ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = Неопределено, Перезапустить = Ложь,
БлокируемыеЭлементыФормы = Неопределено) Экспорт
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ТекстЗапроса);
ПараметрыЗадания.Добавить(Параметры);
Если Ложь
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
#Если Клиент Тогда
СостояниеЛкс("Выполнение запроса…");
#КонецЕсли
Запрос = Новый Запрос(ТекстЗапроса);
Если Параметры <> Неопределено Тогда
ирОбщий.СкопироватьУниверсальнуюКоллекциюЛкс(Параметры, Запрос.Параметры);
КонецЕсли;
РезультатПакета = Запрос.ВыполнитьПакет();
#Если Клиент Тогда
СостояниеЛкс("");
#КонецЕсли
РезультатЗадания = Новый Структура;
РезультатЗадания.Вставить("МоментНачала", МоментНачала);
РезультатЗадания.Вставить("РезультатПакета", РезультатПакета);
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, РезультатЗадания)");
РезультатЗадания = Неопределено;
КонецЕсли;
Иначе
МоментНачала = ТекущаяДата();
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания.Добавить(АдресРезультата);
ПараметрыЗадания.Добавить(МоментНачала);
Для Счетчик = 1 По 1 Цикл
ПараметрыЗадания.Добавить(Неопределено); // Необязательные параметры
КонецЦикла;
Представление = "Выполнение запроса";
#Если Сервер И Не Сервер Тогда
ирСервер.ВыполнитьЗапросЛкс();
#КонецЕсли
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс("ВыполнениеЗапроса", "ирСервер.ВыполнитьЗапросЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения, АдресРезультата,,
БлокируемыеЭлементыФормы);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания, Перезапустить);
КонецЕсли;
Возврат РезультатЗадания;
КонецФункции
Функция УправлениеИтогамиРегистров_ВыполнитьКомандуЛкс(Знач ОбщиеПараметрыОбработки, Знач МоментНачала, Знач РегистрыДляОбработки, Знач Команда, Знач ПериодИтогов, Знач АдресРезультата = Неопределено,
ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = "", БлокируемыеЭлементы = Неопределено) Экспорт
Если Ложь
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
Если ЭтаФорма <> Неопределено Тогда
Обработка = ЭтаФорма.ЭтотОбъект;
Иначе
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = Обработки.ирУправлениеИтогамиРегистров.Создать();
ЗагрузитьРеквизитыОбработкиЛкс(Обработка, ОбщиеПараметрыОбработки);
КонецЕсли;
Обработка.ВыполнитьКомандуПользователя(РегистрыДляОбработки, Команда, ПериодИтогов);
Результат = Новый Структура();
Результат.Вставить("МоментНачала", МоментНачала);
Результат.Вставить("Команда", Команда);
Результат.Вставить("РегистрыДляОбработки", РегистрыДляОбработки);
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
Иначе
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
Представление = Команда;
ИмяЗадания = "ОбработкаРегистров";
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки);
ПараметрыЗадания.Добавить(МоментНачала);
ПараметрыЗадания.Добавить(РегистрыДляОбработки);
ПараметрыЗадания.Добавить(Команда);
ПараметрыЗадания.Добавить(ПериодИтогов);
ПараметрыЗадания.Добавить(АдресРезультата);
Для Счетчик = 1 По 4 Цикл
ПараметрыЗадания.Добавить(Неопределено); // Необязательные параметры
КонецЦикла;
//ДобавитьПереданныйКэшВСтруктуруЛкс(ОбщиеПараметрыОбработки);
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс(ИмяЗадания, "ирОбщий.УправлениеИтогамиРегистров_ВыполнитьКомандуЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения, АдресРезультата,,
БлокируемыеЭлементы);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания);
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
// Функция - Выполнить задание формы лкс
//
// Параметры:
// ИмяМетодаОбработки - -
// ПараметрыЗадания - -
// ЭтаФормаИлиОбработка - -
// ИмяЗадания - -
// ПредставлениеЗадания - -
// Кнопка - -
// ОбработчикЗавершения - -
// РазрешитьАсинхронно - Булево, "ВЭтомСеансе" - при Истина выполняем фоново и не ждем завершения, при Ложь выполняем фоново и ждем завершения, при "ВЭтомСеансе" выполняем в текущем сеансе
// БлокируемыеЭлементыФормы - -
// ПередаватьКэш - -
// Перезапустить - -
// Многопоточное - -
// ПрефиксыОповещений - -
//
// Возвращаемое значение:
// -
//
Функция ВыполнитьЗаданиеФормыЛкс(Знач ИмяМетодаОбработки, Знач ПараметрыЗадания = Неопределено, Знач ЭтаФормаИлиОбработка = Неопределено, Знач ИмяЗадания = "", Знач ПредставлениеЗадания = "",
Знач Кнопка = Неопределено, Знач ОбработчикЗавершения = Неопределено, РазрешитьАсинхронно = Истина, БлокируемыеЭлементыФормы = Неопределено, ПередаватьКэш = Ложь, Перезапустить = Ложь,
Знач Многопоточное = Ложь, Знач ПрефиксыОповещений = Неопределено) Экспорт // Мультиметка49144183
Если ПараметрыЗадания = Неопределено Тогда
ПараметрыЗадания = Новый Структура;
КонецЕсли;
ИмяСвойстваРеквизитыДляСервера = "_РеквизитыДляСервера";
ИмяСвойстваАдресРезультата = "_АдресРезультата";
ИмяСвойстваПолноеИмяОбработки = "_ПолноеИмяОбработки";
ИмяСвойстваКэш = "_Кэш";
ИмяСвойстваНачалоЗадания = "_НачалоЗадания";
НачалоЗадания = ТекущаяДата();
ВыполнятьНаСервере = Неопределено;
Если ПараметрыЗадания.Свойство("ВыполнятьНаСервере") Тогда
ВыполнятьНаСервере = ПараметрыЗадания.ВыполнятьНаСервере;
Иначе
Попытка
ВыполнятьНаСервере = ЭтаФормаИлиОбработка.ВыполнятьНаСервере;
Исключение
КонецПопытки;
КонецЕсли;
ТипФорма = Неопределено;
#Если Клиент Тогда
ТипФорма = Тип("Форма");
#КонецЕсли
Если Ложь
Или РазрешитьАсинхронно = "ВЭтомСеансе"
Или ВыполнятьНаСервере = Ложь
Или Не ЛиАсинхронностьДоступнаЛкс()
Или ТипЗнч(ЭтаФормаИлиОбработка) <> ТипФорма
Тогда
ПараметрыЗадания.Вставить("ЭтаФорма", ЭтаФормаИлиОбработка);
Если ЭтаФормаИлиОбработка <> Неопределено Тогда
Обработка = ЭтаФормаИлиОбработка;
Иначе
Если ПараметрыЗадания.Свойство(ИмяСвойстваКэш) Тогда
ирКэш.ПараметрыСеансаЛкс().ПереданныйКэш = ПоместитьВоВременноеХранилище(ПараметрыЗадания[ИмяСвойстваКэш], Новый УникальныйИдентификатор);
КонецЕсли;
ПолноеИмяОбработки = ПараметрыЗадания[ИмяСвойстваПолноеИмяОбработки];
РеквизитыОбработки = ПараметрыЗадания[ИмяСвойстваРеквизитыДляСервера];
Обработка = СоздатьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяОбработки);
Если РеквизитыОбработки <> Неопределено Тогда
ЗагрузитьРеквизитыОбработкиЛкс(Обработка, РеквизитыОбработки);
КонецЕсли;
НачалоЗадания = ПараметрыЗадания[ИмяСвойстваНачалоЗадания];
КонецЕсли;
Результат = Вычислить("Обработка." + ИмяМетодаОбработки + "(ПараметрыЗадания)");
Если ТипЗнч(Результат) = Тип("Структура") Тогда
Результат.Вставить("НачалоЗадания", НачалоЗадания);
КонецЕсли;
Если ТипЗнч(ЭтаФормаИлиОбработка) = ТипФорма Тогда
Выполнить("ЭтаФормаИлиОбработка." + ОбработчикЗавершения + "(, Результат)");
//Результат = Неопределено; // Если раскомментировать, то сломается ирПоискДублейИЗаменаСсылок.Форма.АвтозаменаЭлементов()
ИначеЕсли ЭтаФормаИлиОбработка = Неопределено Тогда
АдресРезультата = ПараметрыЗадания[ИмяСвойстваАдресРезультата];
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
//Если МетодРеализованЛкс(ЭтаФорма, "РеквизитыОбработки") Тогда
РеквизитыДляСервера = ЭтаФормаИлиОбработка.РеквизитыДляСервера(ПараметрыЗадания);
//КонецЕсли;
Если РазрешитьАсинхронно = Ложь Тогда
Кнопка = Неопределено;
КонецЕсли;
СлужебныеИменаСвойств = Новый Массив;
СлужебныеИменаСвойств.Добавить(ИмяСвойстваРеквизитыДляСервера);
СлужебныеИменаСвойств.Добавить(ИмяСвойстваАдресРезультата);
СлужебныеИменаСвойств.Добавить(ИмяСвойстваПолноеИмяОбработки);
СлужебныеИменаСвойств.Добавить(ИмяСвойстваНачалоЗадания);
СлужебныеИменаСвойств.Добавить(ИмяСвойстваКэш);
Для Каждого СлужебноеИмя Из СлужебныеИменаСвойств Цикл
Если ПараметрыЗадания.Свойство(СлужебноеИмя) Тогда
ВызватьИсключение "В параметрах задания присутствует запрещенное свойство """ + СлужебноеИмя + """";
КонецЕсли;
КонецЦикла;
Если ПередаватьКэш Тогда
ТаблицаВсехТаблицБД = ирОбщий.ТаблицаВсехТаблицБДБезОжиданияЛкс();
Если ТаблицаВсехТаблицБД <> Неопределено Тогда
ПараметрыЗадания.Вставить(ИмяСвойстваКэш, Новый Структура("ТаблицаВсехТаблицБД", ТаблицаВсехТаблицБД));
КонецЕсли;
КонецЕсли;
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФормаИлиОбработка);
ПолноеИмяОбъекта = ЭтаФормаИлиОбработка.Метаданные().ПолноеИмя();
ПараметрыЗадания.Вставить(ИмяСвойстваРеквизитыДляСервера, РеквизитыДляСервера);
ПараметрыЗадания.Вставить(ИмяСвойстваАдресРезультата, АдресРезультата);
ПараметрыЗадания.Вставить(ИмяСвойстваПолноеИмяОбработки, ПолноеИмяОбъекта);
ПараметрыЗадания.Вставить(ИмяСвойстваНачалоЗадания, НачалоЗадания);
#Если Сервер И Не Сервер Тогда
ирОбщий.ВыполнитьЗаданиеФормыЛкс();
#КонецЕсли
ПолноеИмяЭтогоМетода = "ирОбщий.ВыполнитьЗаданиеФормыЛкс";
ПараметрыФоновогоЗадания = Новый Массив;
ПараметрыФоновогоЗадания.Добавить(ИмяМетодаОбработки);
ПараметрыФоновогоЗадания.Добавить(ПараметрыЗадания);
// Мультиметка49144183
Для Счетчик = 1 По 11 Цикл
ПараметрыФоновогоЗадания.Добавить(Неопределено); // Необязательные параметры
КонецЦикла;
Если Не ЗначениеЗаполнено(ИмяЗадания) Тогда
ИмяЗадания = ИмяМетодаОбработки;
КонецЕсли;
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс(ИмяЗадания, ПолноеИмяЭтогоМетода, ПараметрыФоновогоЗадания, ПредставлениеЗадания, Кнопка, ОбработчикЗавершения, АдресРезультата,,
БлокируемыеЭлементыФормы, Многопоточное, ПрефиксыОповещений);
Результат = ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФормаИлиОбработка, ОписаниеЗадания, Перезапустить);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция РеквизитыОбработкиЛкс(Обработка, ДляСериализации = Истина, ИгнорироватьЗапрещенныеТипы = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирАнализЖурналаРегистрации.Создать();
#КонецЕсли
Результат = Новый Структура;
Для Каждого МетаРеквизит Из Обработка.Метаданные().Реквизиты Цикл
ЗначениеРеквизита = Обработка[МетаРеквизит.Имя];
Если ДляСериализации Тогда
Если Ложь
Или ТипЗнч(ЗначениеРеквизита) = Тип("КомпоновщикНастроекКомпоновкиДанных")
Тогда
Если Не ИгнорироватьЗапрещенныеТипы Тогда
ВызватьИсключение "Запрещенный тип """ + ТипЗнч(ЗначениеРеквизита) + """ реквизита """ + МетаРеквизит.Имя + """ для сериализации";
Иначе
Продолжить;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Результат.Вставить(МетаРеквизит.Имя, ЗначениеРеквизита);
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура ЗагрузитьРеквизитыОбработкиЛкс(Обработка, Реквизиты)
#Если Сервер И Не Сервер Тогда
Обработка = Отчеты.ирАнализПравДоступа.Создать();
#КонецЕсли
ЗаполнитьЗначенияСвойств(Обработка, Реквизиты);
Для Каждого МетаТЧ Из Обработка.Метаданные().ТабличныеЧасти Цикл
Если Реквизиты.Свойство(МетаТЧ.Имя) Тогда
Обработка[МетаТЧ.Имя].Загрузить(Реквизиты[МетаТЧ.Имя]);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
/////////////////////////////////////
Процедура НастроитьЗаголовкиАвтоТабличногоПоляДинамическогоСпискаЛкс(Знач ОсновнойЭУ, Знач РежимИмяСиноним) Экспорт
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ОсновнойЭУ.Значение));
ПоляТаблицы = ПоляТаблицыМДЛкс(ОбъектМД.ПолноеИмя());
Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл
КолонкаТП = ОсновнойЭУ.Колонки.Найти(ПолеТаблицы.Имя);
// Мультиметка92934781664
Если КолонкаТП = Неопределено Тогда
Продолжить;
КонецЕсли;
Если РежимИмяСиноним Тогда
Заголовок = ПолеТаблицы.Имя;
Иначе
Заголовок = ПолеТаблицы.Заголовок;
КонецЕсли;
Попытка
Подсказка = ПолеТаблицы.Метаданные.Подсказка;
Исключение
Подсказка = "";
КонецПопытки;
КолонкаТП.ТекстШапки = Заголовок;
КолонкаТП.ПодсказкаВШапке = Подсказка;
ДобавитьОписаниеТиповВПодсказкуШапкиКолонкиЛкс(КолонкаТП, ПолеТаблицы.ТипЗначения);
Если ЛиОписаниеТиповБулевоЛкс(ПолеТаблицы.ТипЗначения) Тогда
КолонкаТП.ДанныеФлажка = "";
КолонкаТП.КартинкиСтрок = ирКэш.КартинкаПоИмениЛкс("ирСостоянияФлажка");
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура НастроитьЗаголовкиАвтоТаблицыФормыДинамическогоСпискаЛкс(Знач ОсновнойЭУ, Знач ПолноеИмяТаблицы, Знач РежимИмяСиноним) Экспорт
ПоляТаблицы = ирОбщий.ПоляТаблицыМДЛкс(ПолноеИмяТаблицы);
ПоляТаблицы = ПоляТаблицы.Скопировать();
СтрокаПоляИденитификатора = ПоляТаблицы.Добавить();
СтрокаПоляИденитификатора.Имя = "ИдентификаторСсылкиЛкс";
СтрокаПоляИденитификатора.Заголовок = "Идентификатор ссылки";
СтрокаПоляИденитификатора.ТипЗначения = Новый ОписаниеТипов;
Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл
КолонкаТП = ОсновнойЭУ.ПодчиненныеЭлементы.Найти(ОсновнойЭУ.Имя + ПолеТаблицы.Имя);
// Мультиметка92934781664
Если КолонкаТП = Неопределено Тогда
Продолжить;
КонецЕсли;
Если РежимИмяСиноним Тогда
Заголовок = ПолеТаблицы.Имя;
Иначе
Заголовок = ПолеТаблицы.Заголовок;
КонецЕсли;
Попытка
Подсказка = ПолеТаблицы.Метаданные.Подсказка;
Исключение
Подсказка = "";
КонецПопытки;
КолонкаТП.Заголовок = Заголовок;
КолонкаТП.Подсказка = Подсказка;
ДобавитьОписаниеТиповВПодсказкуШапкиКолонкиЛкс(КолонкаТП, ПолеТаблицы.ТипЗначения);
Если ЛиОписаниеТиповБулевоЛкс(ПолеТаблицы.ТипЗначения) Тогда
КолонкаТП.Вид = ВидПоляФормы.ПолеКартинки;
КолонкаТП.КартинкаЗначений = ирКэш.КартинкаПоИмениЛкс("ирСостоянияФлажка");
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Функция - Колонки таблицы БДСПроверками лкс
//
// Параметры:
// ПолноеИмяТаблицы - Строка -
// ИменаКолонок - Массив, Строка - белый список имен колонок
//
// Возвращаемое значение:
// -
//
Функция КолонкиТаблицыБДСПроверкамиЛкс(Знач ПолноеИмяТаблицы, Знач ИменаКолонок = Неопределено) Экспорт
Если ТипЗнч(ИменаКолонок) = Тип("Строка") И ЗначениеЗаполнено(ИменаКолонок) Тогда
ИменаКолонок = СтрРазделитьЛкс(ИменаКолонок);
КонецЕсли;
КолонкиСПроверками = Новый Структура;
Для Каждого ПолеТаблицыБД Из ирКэш.ПоляТаблицыБДЛкс(ПолноеИмяТаблицы) Цикл
ИмяКолонки = ПолеТаблицыБД.Имя;
Если Ложь
Или ПолеТаблицыБД.Метаданные = Неопределено
Или (Истина
И ТипЗнч(ИменаКолонок) = Тип("Массив")
И ИменаКолонок.Найти(ИмяКолонки) = Неопределено)
Тогда
Продолжить;
КонецЕсли;
МетаданныеКолонки = ПолеТаблицыБД.Метаданные;
КолонкаСПроверками = Новый Структура("Имя, СвязиПараметровВыбора, ПараметрыВыбора");
КолонкаСПроверками.Имя = ИмяКолонки;
ЗаполнитьЗначенияСвойств(КолонкаСПроверками, МетаданныеКолонки, "СвязиПараметровВыбора, ПараметрыВыбора");
КолонкиСПроверками.Вставить(ИмяКолонки, КолонкаСПроверками);
КонецЦикла;
Возврат КолонкиСПроверками;
КонецФункции
Функция ПроверитьТаблицуЗначенийНаСогласованностьЛкс(ТаблицаДляЗагрузки, Знач КолонкиСПроверками, Знач КолонкиСНарушениями = Неопределено, Знач ТабличноеПоле = Неопределено,
выхПропускатьНесогласованные = Ложь, выхПоляСУсловиями = Неопределено, Знач ЛиТЧ = Ложь, Знач РеквизитыВладельца = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаДляЗагрузки = Новый ТаблицаЗначений;
КолонкиСПроверками = Новый Структура;
#КонецЕсли
ПараметрыЗапроса = Новый Структура;
КомпоновщикТаблицы = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикТаблицы.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СоздатьСхемуПоТаблицеЗначенийЛкс(ТаблицаДляЗагрузки)));
СформироватьПоляЗапросаПроверкиСогласованностиЛкс(КомпоновщикТаблицы, КолонкиСПроверками, ПараметрыЗапроса, ТабличноеПоле, выхПоляСУсловиями, ЛиТЧ, РеквизитыВладельца);
выхПропускатьНесогласованные = Истина;
Если выхПоляСУсловиями.Количество() > 0 Тогда
ТекстЗапроса = "ВЫБРАТЬ * ПОМЕСТИТЬ Т ИЗ &Т КАК Т;
|ВЫБРАТЬ *,
| " + СтрСоединитьЛкс(выхПоляСУсловиями.ВыгрузитьКолонку("ВыражениеЗапроса"), "," + Символы.ПС + Символы.Таб) + "
|ИЗ Т";
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
СкопироватьУниверсальнуюКоллекциюЛкс(ПараметрыЗапроса, Запрос.Параметры);
Запрос.УстановитьПараметр("Т", ТаблицаДляЗагрузки);
Попытка
ТаблицаДляЗагрузки = Запрос.Выполнить().Выгрузить();
Исключение
// Есть запрещенные для запроса типы
ОписаниеОшибки = ОписаниеОшибки();
СообщитьЛкс("Ошибка проверки согласованности данных: " + ОписаниеОшибки);
Запрос = Неопределено;
КонецПопытки;
Если Запрос <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ТаблицаДляЗагрузки = Новый ТаблицаЗначений;
#КонецЕсли
ТаблицаДляЗагрузки = ТаблицаСКолонкамиБезТипаNullЛкс(ТаблицаДляЗагрузки); // Иначе Итог по колонке Булево не будет считаться
БылиНеуспехи = Ложь;
Для Каждого ПолеСоСвязями Из выхПоляСУсловиями Цикл
КоличествоНеуспехов = ТаблицаДляЗагрузки.Итог("Несогласовано_" + ПолеСоСвязями.ИмяКолонки);
Если КоличествоНеуспехов > 0 Тогда
СообщитьЛкс(СтрШаблонЛкс("В колонке ""%1"" %2 ячеек не удовлетворяют текущим связям и параметрам выбора выбора.%3 Эти ячейки будут пропущены.",
ПолеСоСвязями.ИмяКолонки, КоличествоНеуспехов, ?(ТабличноеПоле = Неопределено, "", " Если эти условия статичны, то")));
Если КолонкиСНарушениями <> Неопределено Тогда
КолонкиСНарушениями.Вставить(ПолеСоСвязями.ИмяКолонки);
КонецЕсли;
БылиНеуспехи = Истина;
Иначе
ТаблицаДляЗагрузки.Колонки.Удалить("Несогласовано_" + ПолеСоСвязями.ИмяКолонки);
КонецЕсли;
КонецЦикла;
Если БылиНеуспехи Тогда
#Если Клиент Тогда
Ответ = Вопрос("Обнаружены статично несогласованные данные в загружаемых строках. Хотите отменить загрузку и посмотреть запрос проверки?", РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Да);
Если Ответ = КодВозвратаДиалога.Да Тогда
ОтладитьЛкс(Запрос);
Возврат Ложь;
КонецЕсли;
#Иначе
СообщитьЛкс("При выполнении на клиенте будет доступен просмотр запроса проверки согласованности.");
#КонецЕсли
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Истина;
КонецФункции
// Функция - Сформировать поля запроса проверки согласованности лкс
//
// Параметры:
// ТаблицаДляЗагрузки - ТаблицаЗначений - строки не нужны, достаточно колонок
// КолонкиСПроверками - -
// ПараметрыЗапроса - -
// ТабличноеПоле - -
// ПоляСУсловиями - -
// ЛиТЧ - -
// РеквизитыВладельца - -
//
// Возвращаемое значение:
// -
//
Функция СформироватьПоляЗапросаПроверкиСогласованностиЛкс(Знач КомпоновщикТаблицы, Знач КолонкиСПроверками, ПараметрыЗапроса, Знач ТабличноеПоле = Неопределено, ПоляСУсловиями = Неопределено,
Знач ЛиТЧ = Ложь, Знач РеквизитыВладельца = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
КомпоновщикТаблицы = Новый КомпоновщикНастроекКомпоновкиДанных;
#КонецЕсли
ПоляСУсловиями = Новый ТаблицаЗначений;
ПоляСУсловиями.Колонки.Добавить("ИмяКолонки");
ПоляСУсловиями.Колонки.Добавить("ВыражениеЗапроса");
ПоляСУсловиями.Индексы.Добавить("ИмяКолонки");
Если ПараметрыЗапроса = Неопределено Тогда
ПараметрыЗапроса = Новый Структура;
КонецЕсли;
Для Каждого КлючИЗначение Из КолонкиСПроверками Цикл
КолонкаСПроверками = КлючИЗначение.Значение;
ИмяКолонкиТЗ = КолонкаСПроверками.Имя;
ТекстУспехаПоля = "";
СвязиПараметровВыбора = КолонкаСПроверками.СвязиПараметровВыбора;
ПараметрыВыбора = КолонкаСПроверками.ПараметрыВыбора;
ВыраженияУсловий = Новый Массив;
Для Каждого СвязьПараметраВыбора Из СвязиПараметровВыбора Цикл
#Если Сервер И Не Сервер Тогда
СвязьПараметраВыбора = Новый СвязьПараметраВыбора;
#КонецЕсли
Фрагменты = СтрРазделитьЛкс(СвязьПараметраВыбора.Имя, "Отбор.");
Если Фрагменты.Количество() < 2 Тогда
Продолжить;
КонецЕсли;
ИмяРеквизитаКолонки = Фрагменты[1];
//Если СвязьПараметраВыбора.ИзменениеЗначения = РежимИзмененияСвязанногоЗначения.НеИзменять Тогда
// Продолжить;
//КонецЕсли;
//Если КолонкаСПроверками.Свойство("НовоеЗначение") Тогда
// ИмяПараметра = АвтоУникальноеИмяВКоллекцииЛкс(ПараметрыЗапроса, ИдентификаторИзПредставленияЛкс(КолонкаСПроверками.НовоеЗначение));
// ПараметрыЗапроса.Вставить(ИмяПараметра, КолонкаСПроверками.НовоеЗначение);
// ПолеКомпоновки = "(ВЫРАЗИТЬ &" + ИмяПараметра + " КАК " + КолонкаСПроверками.НовоеЗначение.Метаданные().ПолноеИмя() + ")." + ИмяРеквизитаКолонки;
//Иначе
ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ИмяКолонкиТЗ + "." + ИмяРеквизитаКолонки);
Если КомпоновщикТаблицы.Настройки.Отбор.ДоступныеПоляОтбора.НайтиПоле(ПолеКомпоновки) = Неопределено Тогда
Продолжить;
КонецЕсли;
//КонецЕсли;
ПутьКДанным = СвязьПараметраВыбора.ПутьКДанным;
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
// ПутьКДанным = "Элементы.Товары.ТекущиеДанные.Номенклатура"
Фрагменты = СтрРазделитьЛкс(ПутьКДанным, ТабличноеПоле.Имя + ".ТекущиеДанные.");
Если Фрагменты.Количество() > 1 Тогда
ВлияющееВыражение = "Т." + Фрагменты[1];
Иначе
ВлияющееЗначение = Вычислить("РеквизитыВладельца." + ПутьКДанным);
ИмяПараметра = АвтоУникальноеИмяВКоллекцииЛкс(ПараметрыЗапроса, ИдентификаторИзПредставленияЛкс(ВлияющееЗначение));
ПараметрыЗапроса.Вставить(ИмяПараметра, ВлияющееЗначение);
ВлияющееВыражение = "&" + ИмяПараметра;
КонецЕсли;
Иначе
Фрагменты = СтрРазделитьЛкс(ПутьКДанным);
Если ЛиТЧ Тогда
Если Фрагменты.Количество() = 1 Тогда
Если РеквизитыВладельца <> Неопределено Тогда
ВлияющееЗначение = РеквизитыВладельца[Фрагменты[0]];
ИмяПараметра = АвтоУникальноеИмяВКоллекцииЛкс(ПараметрыЗапроса, ИдентификаторИзПредставленияЛкс(ВлияющееЗначение));
ПараметрыЗапроса.Вставить(ИмяПараметра, ВлияющееЗначение);
ВлияющееВыражение = "&" + ИмяПараметра;
Иначе
ВлияющееВыражение = "Т.Ссылка." + Фрагменты[0];
КонецЕсли;
Иначе
ВлияющееВыражение = "Т." + Фрагменты[1];
КонецЕсли;
Иначе
ВлияющееВыражение = "Т." + Фрагменты[0];
КонецЕсли;
КонецЕсли;
ВыраженияУсловий.Добавить("ЕСТЬNULL(" + ВлияющееВыражение + " = Т." + ПолеКомпоновки + ", ИСТИНА)");
КонецЦикла;
Если Не КолонкаСПроверками.Свойство("НовоеЗначение") Тогда
Для Каждого ПараметрВыбора Из ПараметрыВыбора Цикл
#Если Сервер И Не Сервер Тогда
ПараметрВыбора = Новый ПараметрВыбора;
#КонецЕсли
Фрагменты = СтрРазделитьЛкс(ПараметрВыбора.Имя, "Отбор.");
Если Фрагменты.Количество() < 2 Тогда
Продолжить;
КонецЕсли;
ИмяРеквизитаКолонки = Фрагменты[1];
ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ИмяКолонкиТЗ + "." + ИмяРеквизитаКолонки);
Если КомпоновщикТаблицы.Настройки.Отбор.ДоступныеПоляОтбора.НайтиПоле(ПолеКомпоновки) = Неопределено Тогда
Продолжить;
КонецЕсли;
ИмяПараметра = АвтоУникальноеИмяВКоллекцииЛкс(ПараметрыЗапроса, ИдентификаторИзПредставленияЛкс(ПараметрВыбора.Значение));
ПараметрыЗапроса.Вставить(ИмяПараметра, ПараметрВыбора.Значение);
ВыраженияУсловий.Добавить("ЕСТЬNULL(Т." + ПолеКомпоновки + " В (&" + ИмяПараметра + "), ИСТИНА)");
КонецЦикла;
КонецЕсли;
Если ВыраженияУсловий.Количество() > 0 Тогда
ПолеСУСловиями = ПоляСУсловиями.Добавить();
ПолеСУСловиями.ИмяКолонки = ИмяКолонкиТЗ;
//ПолеСУСловиями.ВыражениеЗапроса = "ВЫБОР КОГДА " + СтрСоединитьЛкс(ВыраженияУсловий, Символы.ПС + " И ") + " ТОГДА ЛОЖЬ ИНАЧЕ ИСТИНА КОНЕЦ КАК Несогласовано_" + ИмяКолонкиТЗ;
ПолеСУСловиями.ВыражениеЗапроса = "НЕ (" + СтрСоединитьЛкс(ВыраженияУсловий, Символы.ПС + " И ") + ") КАК Несогласовано_" + ИмяКолонкиТЗ;
КонецЕсли;
КонецЦикла;
Возврат ПараметрыЗапроса;
КонецФункции
Функция СоединениеHTTPЛкс(СерверЗапроса, ПортВременный = 80, ПользовательЗапроса = "", ПарольЗапроса = "", СобственныйПрокси = Ложь, ТаймаутЗапроса = 0, ИспользоватьЗащищенноеСоединение = Ложь,
АутентификацияОС = Неопределено, ПредставлениеСоединения = "Соединение", ПроверитьНаСервере = Ложь) Экспорт
Если ПроверитьНаСервере Тогда
ирСервер.СоединениеHTTPЛкс(СерверЗапроса, ПортВременный, ПользовательЗапроса, ПарольЗапроса, СобственныйПрокси, ТаймаутЗапроса, ИспользоватьЗащищенноеСоединение, АутентификацияОС,
ПредставлениеСоединения);
КонецЕсли;
ИнтернетПрокси = ИнтернетПроксиЛкс(СобственныйПрокси, ИспользоватьЗащищенноеСоединение);
ЗащищенноеСоединение = ?(ИспользоватьЗащищенноеСоединение, Новый ЗащищенноеСоединениеOpenSSL(), Неопределено);
Если АутентификацияОС <> Неопределено Тогда
Попытка
// параметр АутентификацияОС появился в 8.3.7
СоединениеHTTP = Вычислить("Новый HTTPСоединение(СерверЗапроса, ПортВременный, ПользовательЗапроса, ПарольЗапроса, ИнтернетПрокси, ТаймаутЗапроса, ЗащищенноеСоединение, АутентификацияОС)");
Исключение
Сообщить(ПредставлениеСоединения + " не установлено по причине: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
Иначе
СоединениеHTTP = Новый HTTPСоединение(СерверЗапроса, ПортВременный, ПользовательЗапроса, ПарольЗапроса, ИнтернетПрокси, ТаймаутЗапроса, ЗащищенноеСоединение);
КонецЕсли;
Возврат СоединениеHTTP;
КонецФункции
Функция ИнтернетПроксиЛкс(ИспользоватьСобственныйПрокси = Ложь, ЗащищенноеСоединение = Ложь) Экспорт
ИнтернетПрокси = Новый ИнтернетПрокси(Не ИспользоватьСобственныйПрокси);
Если ИспользоватьСобственныйПрокси Тогда
СобственныеПрокси = ирОбщий.ВосстановитьЗначениеЛкс("ИнтернетПрокси");
#Если Сервер И Не Сервер Тогда
СобственныеПрокси = Новый Структура;
#КонецЕсли
Протокол = ?(ЗащищенноеСоединение, "https", "http");
Если СобственныеПрокси.Свойство(Протокол) Тогда
НастройкиПрокси = СобственныеПрокси[Протокол];
Если ЗначениеЗаполнено(НастройкиПрокси.Сервер) Тогда
ИнтернетПрокси.Установить(Протокол, НастройкиПрокси.Сервер, НастройкиПрокси.Порт, НастройкиПрокси.Пользователь, НастройкиПрокси.Пароль, НастройкиПрокси.АутентификацияОС);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ИнтернетПрокси;
КонецФункции
Процедура ОчиститьДвиженияДокументаЛкс(Знач Ссылка, Знач ВключаяПоследовательности = Ложь, Знач ВключаяПерерасчеты = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
Ссылка = Документы.АвансовыйОтчет.ПустаяСсылка();
#КонецЕсли
ОбъектыМД = ирОбщий.МетаданныеНаборовЗаписейПоРегистраторуЛкс(Ссылка.Метаданные(), ВключаяПоследовательности, ВключаяПерерасчеты);
Для Каждого МетаРегистр из ОбъектыМД Цикл
ПолноеИмяМД = МетаРегистр.ПолноеИмя();
ИмяТаблицыБДРегистра = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
ИмяПоляОтбора = ирОбщий.ИмяПоляОтбораПодчиненногоНабораЗаписейЛкс(ИмяТаблицыБДРегистра);
СтруктураНаборЗаписей = ирОбщий.ОбъектБДПоКлючуЛкс(ПолноеИмяМД, Новый Структура(ИмяПоляОтбора, Ссылка),, Ложь);
ирОбщий.ЗаписатьОбъектЛкс(СтруктураНаборЗаписей.Методы);
КонецЦикла;
КонецПроцедуры
// Процедура - Установить использование истории данных лкс
//
// Параметры:
// ИменаМД - Строка, Массив - если передана строка, то из нее создается массив с одним элементом
// НовоеИспользование - -
// НовоеИспользованиеПолей - -
//
Функция УстановитьИспользованиеИсторииДанныхЛкс(Знач ИменаМД, Знач НовоеИспользование = Неопределено, Знач НовоеИспользованиеПолей = Неопределено) Экспорт
Если ТипЗнч(ИменаМД) = Тип("Строка") Тогда
ИменаМД = ЗначенияВМассивЛкс(ИменаМД);
КонецЕсли;
#Если Клиент И Не Сервер Тогда
// Антибаг платформы https://www.hostedredmine.com/issues/922251
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
СообщитьЛкс("Серверный контекст не увидит изменений настроек истории данных до перезапуска сеанса из-за ошибки платформы");
Иначе
ирСервер.УстановитьИспользованиеИсторииДанныхЛкс(ИменаМД, НовоеИспользование, НовоеИспользованиеПолей);
КонецЕсли;
#КонецЕсли
ИсторияДанныхМоя = Вычислить("ИсторияДанных");
#Если Сервер И Не Сервер Тогда
ИсторияДанныхМоя = ИсторияДанных;
#КонецЕсли
Результат = Новый Массив;
Для Каждого ПолноеИмяМД Из ИменаМД Цикл
ОбъектМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмяМД);
НастройкиИстории = ИсторияДанныхМоя.ПолучитьНастройки(ОбъектМД);
Если НастройкиИстории = Неопределено Тогда
НастройкиИстории = Новый ("НастройкиИсторииДанных");
КонецЕсли;
Если НовоеИспользование <> Неопределено Тогда
НастройкиИстории.Использование = НовоеИспользование;
КонецЕсли;
Если НовоеИспользованиеПолей <> Неопределено Тогда
НастройкиИстории.ИспользованиеПолей = НовоеИспользованиеПолей;
КонецЕсли;
ИсторияДанныхМоя.УстановитьНастройки(ОбъектМД, НастройкиИстории);
Результат.Добавить(НастройкиИстории);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ЗапросВСтруктуруЛкс(Запрос) Экспорт
Результат = Новый Структура("Текст, Параметры");
Если Запрос <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(Результат, Запрос);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЗапросИзСтруктурыЛкс(Знач Структура) Экспорт
Запрос = Новый Запрос(Структура.Текст);
СкопироватьУниверсальнуюКоллекциюЛкс(Структура.Параметры, Запрос.Параметры);
Возврат Запрос;
КонецФункции
// Параметры:
// ИсключаяБезымянные - Булево, *Истина - механизм перетаскивания зачем то добавляет свою колонку в таблицу-копию перетаскиваемых строк, а этот параметр включает их игнорирование
//
// Результат - Булево
Функция ЛиКолонкиТаблицСовпадаютЛкс(Таблица1, Таблица2, ИсключаяБезымянные = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
Таблица1 = новый ТаблицаЗначений;
Таблица2 = новый ТаблицаЗначений;
#КонецЕсли
Колонки1 = Новый СписокЗначений;
Для Каждого Колонка Из Таблица1.Колонки Цикл
Если ИсключаяБезымянные И Не ЗначениеЗаполнено(Колонка.Имя) Тогда
Продолжить;
КонецЕсли;
Колонки1.Добавить(Колонка.ТипЗначения, Колонка.Имя);
КонецЦикла;
Колонки1.СортироватьПоПредставлению();
Колонки2 = Новый СписокЗначений;
Для Каждого Колонка Из Таблица2.Колонки Цикл
Если ИсключаяБезымянные И Не ЗначениеЗаполнено(Колонка.Имя) Тогда
Продолжить;
КонецЕсли;
Колонки2.Добавить(Колонка.ТипЗначения, Колонка.Имя);
КонецЦикла;
Колонки2.СортироватьПоПредставлению();
Результат = ОбъектВСтрокуXMLЛкс(Колонки1) = ОбъектВСтрокуXMLЛкс(Колонки2);
Возврат Результат;
КонецФункции
Процедура ВычислитьВыраженияПараметровЛкс(Знач ТаблицаВычисляемыхПараметров, СтруктураПараметров, Знач МодальныйРежим = Ложь, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
СтруктураПараметровXML = ирОбщий.ОбъектВСтрокуXMLЛкс(СтруктураПараметров);
ирСервер.ВычислитьВыраженияПараметровЛкс(ТаблицаВычисляемыхПараметров, СтруктураПараметровXML);
СтруктураПараметров = ирОбщий.ОбъектИзСтрокиXMLЛкс(СтруктураПараметровXML);
Иначе
Для каждого СтрокаПараметра Из ТаблицаВычисляемыхПараметров Цикл
Значение = Неопределено;
Если ЗначениеЗаполнено(СтрокаПараметра.Выражение) Тогда
ТекстАлгоритма = "
|Параметры = _П0;
|лПараметры = _П0; // Устаревшее
|Результат = " + СтрокаПараметра.Выражение;
Попытка
Значение = ВыполнитьАлгоритм(ТекстАлгоритма,,, СтруктураПараметров);
Исключение
СообщитьСУчетомМодальностиЛкс("Ошибка при вычислении параметра """ + СтрокаПараметра.ИмяПараметра + """"
+ Символы.ПС + ОписаниеОшибки(), МодальныйРежим, СтатусСообщения.Важное);
КонецПопытки;
КонецЕсли;
СтруктураПараметров.Вставить(СтрокаПараметра.ИмяПараметра, Значение);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция КоличествоСтрокВРезультатеЗапросаЛкс(ЗапросИлиПостроитель, ЛиЗамерВремени = Ложь, МодальныйРежим = Ложь, ИмяЗапроса = "") Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если ТипЗнч(ЗапросИлиПостроитель) = Тип("ПостроительЗапроса") Тогда
Запрос = ЗапросИлиПостроитель.ПолучитьЗапрос();
Иначе
Запрос = ЗапросИлиПостроитель;
КонецЕсли;
ОригинальныйТекстЗапроса = Запрос.Текст;
// Исключаем тяжелые типы из финальной выборки
МассивИменВременныхТаблиц = Новый Массив();
ТекстПостроителя = мПлатформа.ЗамаскироватьВременныеТаблицы(Запрос, , МассивИменВременныхТаблиц);
ПостроительЗапроса = Новый ПостроительЗапроса;
Попытка
ПостроительЗапроса.Текст = ТекстПостроителя;
Исключение
ОписаниеОшибки = ОписаниеОшибки();
Возврат ОписаниеОшибки;
КонецПопытки;
ПостроительЗапроса.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
ПостроительЗапроса.ЗаполнитьНастройки();
УдаляемыеВыбранныеПоля = Новый Массив;
Для Каждого ВыбранноеПоле Из ПостроительЗапроса.ВыбранныеПоля Цикл
ДоступноеПоле = ПостроительЗапроса.ДоступныеПоля.Найти(ВыбранноеПоле.Имя);
ТипЗначенияПоля = ДоступноеПоле.ТипЗначения;
Если Ложь
Или (Истина
И ТипЗначенияПоля.СодержитТип(Тип("Строка"))
И ТипЗначенияПоля.КвалификаторыСтроки.Длина = 0)
Или ТипЗначенияПоля.СодержитТип(Тип("ХранилищеЗначения"))
Тогда
УдаляемыеВыбранныеПоля.Добавить(ВыбранноеПоле);
КонецЕсли;
КонецЦикла;
Для Каждого ВыбранноеПоле Из УдаляемыеВыбранныеПоля Цикл
ПостроительЗапроса.ВыбранныеПоля.Удалить(ВыбранноеПоле);
КонецЦикла;
ПромежуточныйТекстЗапроса = ПостроительЗапроса.ПолучитьЗапрос().Текст;
ПромежуточныйТекстЗапроса = мПлатформа.РазмаскироватьВременныеТаблицы(ПромежуточныйТекстЗапроса, МассивИменВременныхТаблиц);
МассивТекстовЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросыЛкс(ПромежуточныйТекстЗапроса); // разбивка производится второй раз. можно оптимизировать
ТекстПоследнегоЗапроса = МассивТекстовЗапросов[МассивТекстовЗапросов.ВГраница()];
ТекстДоПоследнегоЗапроса = "";
Для Индекс = 0 По МассивТекстовЗапросов.ВГраница() - 1 Цикл
ТекстДоПоследнегоЗапроса = ТекстДоПоследнегоЗапроса + МассивТекстовЗапросов[Индекс];
КонецЦикла;
ТекстПоследнегоЗапроса = мПлатформа.ПреобразоватьЗапросВПодзапрос(ТекстПоследнегоЗапроса, "КОЛИЧЕСТВО(*) КАК КоличествоСтрок",, Истина);
Запрос.Текст = ТекстДоПоследнегоЗапроса + ТекстПоследнегоЗапроса;
#Если Клиент Тогда
НачалоПредварительногоВыполнения = мПлатформа.ПолучитьТекущееВремяВМиллисекундах();
#КонецЕсли
Попытка
РезультатПредварительногоЗапроса = Запрос.Выполнить();
ПредварительныйЗапросБылиОшибки = Ложь;
Исключение
ПредварительныйЗапросБылиОшибки = Истина;
КоличествоСтрок = ОписаниеОшибки();
КонецПопытки;
#Если Клиент Тогда
Если Истина
И ЛиЗамерВремени
И Не ПредварительныйЗапросБылиОшибки
Тогда
ирОбщий.СообщитьСУчетомМодальностиЛкс("Время формирования предварительного результата """ + ИмяЗапроса + """ - "
+ Строка(мПлатформа.ПолучитьТекущееВремяВМиллисекундах() - НачалоПредварительногоВыполнения) + " мс", МодальныйРежим);
КонецЕсли;
#КонецЕсли
Если Не ПредварительныйЗапросБылиОшибки Тогда
КоличествоСтрок = РезультатПредварительногоЗапроса.Выгрузить()[0].КоличествоСтрок;
КонецЕсли;
Запрос.Текст = ОригинальныйТекстЗапроса;
Возврат КоличествоСтрок;
КонецФункции
Функция КоличествоСтрокВРезультатеКомпоновкиЛкс(МакетКомпоновкиДанныхВКоллекциюЗначений, БылиОшибки = Ложь, ЛиЗамерВремени = Ложь,
МодальныйРежим = Ложь) Экспорт
КоличествоСтрокВсего = 0;
Запрос = Новый Запрос;
Для Каждого ЗначениеПараметра Из МакетКомпоновкиДанныхВКоллекциюЗначений.ЗначенияПараметров Цикл
Запрос.Параметры.Вставить(ЗначениеПараметра.Имя, ЗначениеПараметра.Значение);
КонецЦикла;
Для Каждого НаборДанных Из МакетКомпоновкиДанныхВКоллекциюЗначений.НаборыДанных Цикл
Если ТипЗнч(НаборДанных) <> Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
Запрос.Текст = НаборДанных.Запрос;
КоличествоСтрок = КоличествоСтрокВРезультатеЗапросаЛкс(Запрос, ЛиЗамерВремени, МодальныйРежим, НаборДанных.Имя);
Если ТипЗнч(КоличествоСтрок) = Тип("Число") Тогда
КоличествоСтрокВсего = КоличествоСтрокВсего + КоличествоСтрок;
Иначе
БылиОшибки = Истина;
КонецЕсли;
КонецЦикла;
Возврат КоличествоСтрокВсего;
КонецФункции
Функция СкомпоноватьОтчетВКонсолиЛкс(КоллекцияВывода, Знач МакетКомпоновкиДанных, ВнешниеНаборыДанных = Неопределено, Автофиксация = Истина, МодальныйРежим = Ложь, ЛиОтладка = Ложь,
АдресДанныхРасшифровки = Неопределено, НаСервере = Ложь, выхЭлементыРезультата = Неопределено, ВыполнятьПредварительныйЗапрос = Ложь) Экспорт
Если НаСервере Тогда
АдресКоллекцииВывода = ПоместитьВоВременноеХранилище(КоллекцияВывода);
АдресМакетаКомпоновки = ПоместитьВоВременноеХранилище(МакетКомпоновкиДанных);
Результат = ирСервер.СкомпоноватьОтчетВКонсолиЛкс(АдресКоллекцииВывода, АдресМакетаКомпоновки, ВнешниеНаборыДанных, Автофиксация, МодальныйРежим, ЛиОтладка, АдресДанныхРасшифровки,
ВыполнятьПредварительныйЗапрос);
КоллекцияВывода = ПолучитьИзВременногоХранилища(АдресКоллекцииВывода);
Возврат Результат;
КонецЕсли;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
МакетКомпоновкиДанных = Новый МакетКомпоновкиДанных;
#КонецЕсли
// Осторожная выборка
Если ВыполнятьПредварительныйЗапрос = Истина Тогда
БезопасныйПорогКоличестваСтрок = ВосстановитьЗначениеЛкс("ир_БезопасныйПорогКоличестваСтрок");
//Если ТипЗнч(КоллекцияВывода) = Тип("ТабличныйДокумент") Тогда
МакетКомпоновкиДанныхВКоллекциюЗначений = МакетКомпоновкиДанных;
//Иначе
// МакетКомпоновкиДанныхВКоллекциюЗначений = ПолучитьМакетКомпоновки("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений");
//КонецЕсли;
БылиОшибки = Ложь;
КоличествоСтрокВсего = КоличествоСтрокВРезультатеКомпоновкиЛкс(МакетКомпоновкиДанныхВКоллекциюЗначений, БылиОшибки, ЛиОтладка, МодальныйРежим);
ТекстВопроса = "Оценка общего размера результатов запросов макета составляет " + КоличествоСтрокВсего + " строк.";
Если БылиОшибки Тогда
ТекстВопроса = ТекстВопроса + "
|При расчете некоторые запросы не удалось проанализировать."
КонецЕсли;
Если Ложь
Или БезопасныйПорогКоличестваСтрок * 1000 < КоличествоСтрокВсего
Или БылиОшибки
Тогда
#Если Клиент Тогда
Ответ = Вопрос(ТекстВопроса + " Продолжить?", РежимДиалогаВопрос.ОКОтмена);
Отменить = Ответ <> КодВозвратаДиалога.ОК;
#Иначе
СообщитьЛкс(ТекстВопроса + " Отмена.");
Отменить = Истина;
#КонецЕсли
Если Отменить Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЛиОтладка Тогда
Запрос = Новый Запрос;
Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл
ЗначениеПараметра = Параметр.Значение;
Если ТипЗнч(ЗначениеПараметра) = Тип("ВыражениеКомпоновкиДанных") Тогда
Попытка
ЗначениеПараметра = Вычислить(ЗначениеПараметра);
Исключение
ЗначениеПараметра = Неопределено;
ирОбщий.СообщитьСУчетомМодальностиЛкс("Ошибка вычисления значения параметра """ + Параметр.Имя + """: " + ОписаниеОшибки(), МодальныйРежим, СтатусСообщения.Внимание);
КонецПопытки;
КонецЕсли;
Запрос.УстановитьПараметр(Параметр.Имя, ЗначениеПараметра);
КонецЦикла;
СтруктураНаборовДанныхЗапросовМакета = ВсеНаборыДанныхЗапросовКомпоновкиЛкс(МакетКомпоновкиДанных.НаборыДанных);
Для Каждого ЭлементНаборДанныхМакета Из СтруктураНаборовДанныхЗапросовМакета Цикл
НаборДанных = ЭлементНаборДанныхМакета.Значение.НаборДанных;
Если Не ЗначениеЗаполнено(НаборДанных.Имя) Тогда
// Служебные наборы данных пропускаем
Продолжить;
КонецЕсли;
Запрос.Текст = НаборДанных.Запрос;
ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Запрос - " + НаборДанных.Имя)
КонецЦикла;
КонецЕсли;
Если ЛиОтладка Тогда
НачалоВывода = мПлатформа.ПолучитьТекущееВремяВМиллисекундах();
КонецЕсли;
Если АдресДанныхРасшифровки <> Неопределено Тогда
ДанныеРасшифровки = АдресДанныхРасшифровки;
КонецЕсли;
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина);
Если Ложь
Или ТипЗнч(КоллекцияВывода) = Тип("ТабличныйДокумент")
#Если Клиент Тогда
Или ТипЗнч(КоллекцияВывода) = Тип("ПолеТабличногоДокумента")
#КонецЕсли
Тогда
выхЭлементыРезультата = Новый Массив;
ЭлементыРасшифровки = Неопределено;
Если ДанныеРасшифровки <> Неопределено Тогда
ЭлементыРасшифровки = ДанныеРасшифровки.Элементы;
КонецЕсли;
ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(КоллекцияВывода, ПроцессорКомпоновкиДанных, ЭлементыРасшифровки, , , Автофиксация, выхЭлементыРезультата);
Иначе
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
КоллекцияВывода.Колонки.Очистить();
ПроцессорВывода.УстановитьОбъект(КоллекцияВывода);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных, Истина);
КонецЕсли;
Если АдресДанныхРасшифровки <> Неопределено Тогда
АдресДанныхРасшифровки = ДанныеРасшифровки;
КонецЕсли;
Если ЛиОтладка Тогда
СообщитьСУчетомМодальностиЛкс("Формирование результата - " + Строка(мПлатформа.ПолучитьТекущееВремяВМиллисекундах() - НачалоВывода)
+ " мс", МодальныйРежим);
КонецЕсли;
Возврат Истина;
КонецФункции
// Получает линейную структуру наборов данных запросов компоновки. Работает и со схемой и с макетом.
// Содержит рекурсивный вызов.
//
// Параметры:
// НаборыДанных - НаборыДанныхСхемыКомпоновкиДанных, НаборыДанныхМакетаКомпоновкиДанных;
// *СтруктураНаборовДанных - Структура, *Неопределено - Структура("Имя", Структура("КоллекцияВладелец, НаборДанных"))
//
// Возвращаемое значение:
// Структура.
//
Функция ВсеНаборыДанныхЗапросовКомпоновкиЛкс(Знач НаборыДанных, СтруктураНаборовДанных = Неопределено) Экспорт
Если СтруктураНаборовДанных = Неопределено Тогда
СтруктураНаборовДанных = Новый Структура;
КонецЕсли;
Для каждого НаборДанных Из НаборыДанных Цикл
Если Ложь
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных")
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросСхемыКомпоновкиДанных")
Тогда
Если Не ЗначениеЗаполнено(НаборДанных.Имя) Тогда
// Платформа генерит такие наборы для служебных целей
ИмяНабора = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", "");
Иначе
ИмяНабора = НаборДанных.Имя;
КонецЕсли;
СтруктураНаборовДанных.Вставить(ИмяНабора, Новый Структура("КоллекцияВладелец, НаборДанных", НаборыДанных, НаборДанных));
ИначеЕсли Ложь
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеМакетаКомпоновкиДанных")
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеСхемыКомпоновкиДанных")
Тогда
ВсеНаборыДанныхЗапросовКомпоновкиЛкс(НаборДанных.Элементы, СтруктураНаборовДанных);
КонецЕсли;
КонецЦикла;
Возврат СтруктураНаборовДанных;
КонецФункции
// Выводит результат СКД с установкой вертикальной автофиксации.
// Параметры:
// Таб - ТабличныеДокумент, ПолеТабличногоДокумента - куда выводим отчет;
// ПроцессорКомпоновкиДанных - ПроцессорКомпоновкиДанных;
// ЭлементыРасшировки - ЭлементыРасшифровкиКомпоновкиДанных;
// МассивИгнорируемыхПолей - Массив, *Неопределено - массив имен игнорируемых полей;
// РазрешитьПрерывание - Булево, *Истина.
//
Процедура ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(Таб, ПроцессорКомпоновкиДанных, ЭлементыРасшировки = Неопределено,
Знач МассивИгнорируемыхПолей = Неопределено, РазрешитьПрерывание = Истина, Автофиксация = Истина, выхЭлементыРезультата = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
#КонецЕсли
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.ОтображатьПроцентВывода = Ложь;
ПроцессорВывода.УстановитьДокумент(Таб);
ПроцессорВывода.НачатьВывод();
ФиксацияВыполнена = Ложь;
Если МассивИгнорируемыхПолей = Неопределено Тогда
МассивИгнорируемыхПолей = Новый Массив;
КонецЕсли;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(100, "Компоновка",,, РазрешитьПрерывание);
Пока Истина Цикл
Если РазрешитьПрерывание Тогда
#Если Клиент Тогда
ОбработкаПрерыванияПользователя();
#КонецЕсли
КонецЕсли;
Если ирКэш.РежимОтладкиЛкс() Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
ЭлементРезультатаКомпоновкиДанных = ПроцессорКомпоновкиДанных.Следующий();
Если ЭлементРезультатаКомпоновкиДанных = Неопределено Тогда
Прервать;
КонецЕсли;
Если Индикатор.Счетчик <> ЭлементРезультатаКомпоновкиДанных.ПроцентВывода Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор, ЭлементРезультатаКомпоновкиДанных.ПроцентВывода);
КонецЕсли;
// Автофиксация
Если Истина
И Автофиксация
И Не ФиксацияВыполнена
И ЭлементыРасшировки <> Неопределено
Тогда
Для Каждого ЗначениеПараметра Из ЭлементРезультатаКомпоновкиДанных.ЗначенияПараметров Цикл
Если ТипЗнч(ЗначениеПараметра.Значение) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
ЗначенияПолейРасшифровки = ЭлементыРасшировки[ЗначениеПараметра.Значение].ПолучитьПоля();
Для Каждого ЗначениеПоляРасшифровки Из ЗначенияПолейРасшифровки Цикл
Если МассивИгнорируемыхПолей.Найти(ЗначениеПоляРасшифровки.Поле) = Неопределено Тогда
Таб.ФиксацияСверху = Таб.ВысотаТаблицы;
ФиксацияВыполнена = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ФиксацияВыполнена Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпоновкиДанных);
Если Истина
И выхЭлементыРезультата <> Неопределено
И выхЭлементыРезультата.Количество() < 10000
Тогда
выхЭлементыРезультата.Добавить(ЭлементРезультатаКомпоновкиДанных);
КонецЕсли;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
ЭлементРезультатаКомпоновкиДанных = ПроцессорКомпоновкиДанных.Следующий(); Если ЭлементРезультатаКомпоновкиДанных = Неопределено Тогда Прервать; КонецЕсли; Если Индикатор.Счетчик <> ЭлементРезультатаКомпоновкиДанных.ПроцентВывода Тогда ирОбщий.ОбработатьИндикаторЛкс(Индикатор, ЭлементРезультатаКомпоновкиДанных.ПроцентВывода); КонецЕсли; Если Истина И Автофиксация И Не ФиксацияВыполнена И ЭлементыРасшировки <> Неопределено Тогда Для Каждого ЗначениеПараметра Из ЭлементРезультатаКомпоновкиДанных.ЗначенияПараметров Цикл Если ТипЗнч(ЗначениеПараметра.Значение) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда ЗначенияПолейРасшифровки = ЭлементыРасшировки[ЗначениеПараметра.Значение].ПолучитьПоля(); Для Каждого ЗначениеПоляРасшифровки Из ЗначенияПолейРасшифровки Цикл Если МассивИгнорируемыхПолей.Найти(ЗначениеПоляРасшифровки.Поле) = Неопределено Тогда Таб.ФиксацияСверху = Таб.ВысотаТаблицы; ФиксацияВыполнена = Истина; Прервать; КонецЕсли; КонецЦикла; Если ФиксацияВыполнена Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпоновкиДанных); Если Истина И выхЭлементыРезультата <> Неопределено И выхЭлементыРезультата.Количество() < 10000 Тогда выхЭлементыРезультата.Добавить(ЭлементРезультатаКомпоновкиДанных); КонецЕсли;
КонецЕсли;
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();
КонецПроцедуры
// Для табличного поля может вернуть полное имя МД табличной части обработки!
// Поэтому вместо это функции рекомендуется вызов ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле,,, ИмяТаблицыБД) = "Список"
Функция ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле, выхПолноеИмяМД = "") Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
//выхПолноеИмяМД = ДинамическийСписок.ОсновнаяТаблица; // На клиенте недоступно
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле);
ПутьКДаннымСписка = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТабличноеПоле,, ЭтаФорма);
СлужебныеДанные = СлужебныеДанныеФормыЛкс(ЭтаФорма);
ДинамическийСписок = Неопределено;
Если Истина
И Найти(ПутьКДаннымСписка, ".") = 0
И СлужебныеДанные <> Неопределено
Тогда
СлужебныеДанные.ДинамическиеСписки.Свойство(ПутьКДаннымСписка, ДинамическийСписок);
КонецЕсли;
Если ДинамическийСписок <> Неопределено Тогда
ПолноеИмяТаблицы = ДинамическийСписок.ОсновнаяТаблица;
Иначе
Если ЗначениеЗаполнено(ПутьКДаннымСписка) Тогда
ДинамическийСписок = Вычислить("ЭтаФорма." + ПутьКДаннымСписка);
КонецЕсли;
ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
ТипЗначенияСтроки = Неопределено;
Если Ложь
Или ТекущаяСтрока = Неопределено
Или ТипЗнч(ТекущаяСтрока) = Тип("Число") // Основная таблица не указана
Тогда
Если ДинамическийСписок <> Неопределено Тогда
КомпоновщикНастроек = ДинамическийСписок.КомпоновщикНастроек;
#Если Сервер И Не Сервер Тогда
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
#КонецЕсли
ДоступныеПоля = КомпоновщикНастроек.Настройки.Выбор.ДоступныеПоляВыбора.Элементы;
ДоступноеПолеСсылка = ДоступныеПоля.Найти("Ссылка");
Если ДоступныеПоля.Найти("ПометкаУдаления") <> Неопределено Тогда
ТипЗначенияСтроки = ДоступноеПолеСсылка.Тип.Типы()[0];
КонецЕсли;
КонецЕсли;
Иначе
ТипЗначенияСтроки = ТипЗнч(ТекущаяСтрока);
КонецЕсли;
Если ТипЗначенияСтроки = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗначенияСтроки);
Если ОбъектМД = Неопределено Тогда
Возврат Неопределено
КонецЕсли;
ПолноеИмяТаблицы = ОбъектМД.ПолноеИмя();
КонецЕсли;
#Если Сервер Тогда
Если Не ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда
ПолноеИмяТаблицы = СокрЛП(ирОбщий.СтрокаМеждуМаркерамиЛкс(ДинамическийСписок.ТекстЗапроса, "ИЗ ", " КАК _Т", Ложь));
КонецЕсли;
#КонецЕсли
ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы);
Иначе
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение));
КонецЕсли;
Если ОбъектМД <> Неопределено Тогда
выхПолноеИмяМД = ОбъектМД.ПолноеИмя();
КонецЕсли;
Если ЗначениеЗаполнено(выхПолноеИмяМД) Тогда
ПолноеИмяТаблицы = ирКэш.ИмяТаблицыИзМетаданныхЛкс(выхПолноеИмяМД);
КонецЕсли;
Возврат ПолноеИмяТаблицы;
КонецФункции
Функция РазбитьГрубоТекстПакетногоЗапросаНаЗапросыЛкс(Знач ТекстПакета, Знач ПозицияКурсора = Неопределено, выхПозиции = Неопределено) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
МассивТекстовЗапросов = мПлатформа.РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ТекстПакета, ПозицияКурсора, выхПозиции);
Возврат МассивТекстовЗапросов;
КонецФункции
// Формирует макет компоновки и извлекает из него запрос
// Параметры:
// Схема - СхемаКомпоновкиДанных
// НастройкаКомпоновкиДанных - НастройкиКомпоновкиДанных
// ДобавлятьУпорядочивание - Булево
// ПрефиксИменПараметров - Строка, *"" - используется для переименования параметров, полезно при смешивании нескольких запросов из компоновки в один
// выхСхемаКолонок - Структура, *Неопределено - если не равно Неопределено, то возвращается структура,
// где ключи - имена колонок, а значения - полные имена полей
//
// Результат - Запрос
//
Функция ЗапросИзКомпоновкиЛкс(Знач Схема, Знач НастройкаКомпоновки, Знач ДобавлятьУпорядочивание = Ложь, ПрефиксИменПараметров = "",
ДобавитьВыбранноеПоле = "", выхСхемаКолонок = Неопределено, Автоупорядочивание = Истина, ПроверятьДоступностьПолей = Ложь, СПредставлениямиСсылок = Ложь) Экспорт
НастройкаКомпоновки = КопияОбъектаЛкс(НастройкаКомпоновки, Истина);
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных
#КонецЕсли
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура);
КонецЕсли;
Если ЗначениеЗаполнено(ДобавитьВыбранноеПоле) Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ДобавитьВыбранноеПоле);
КонецЕсли;
Если НастройкаКомпоновки.Выбор.Элементы.Количество() = 0 Тогда
ВыбратьВсеДоступныеПоляКомпоновки(Схема, НастройкаКомпоновки); // Опасно
КонецЕсли;
Если Не СПредставлениямиСсылок Тогда
Для Каждого ВыбранноеПоле Из ВсеВыбранныеПоляГруппировкиКомпоновкиЛкс(НастройкаКомпоновки.Выбор, Истина) Цикл
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(НастройкаКомпоновки.Структура[0].Отбор, "" + ВыбранноеПоле.Поле); // Отбор здесь используется не для фильтрации
КонецЦикла;
НастройкаКомпоновки.Выбор.Элементы.Очистить();
КонецЕсли;
КопияПорядка = Новый Массив;
Для Каждого ЭлементПорядка Из НастройкаКомпоновки.Порядок.Элементы Цикл
Если ЭлементПорядка.Использование Тогда
КопияПорядка.Добавить(ЭлементПорядка);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ЭлементПорядка.Поле);
КонецЕсли;
КонецЦикла;
НастройкаКомпоновки.Порядок.Элементы.Очистить();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
// ирОбщий.ОтЛкс(Схема, НастройкаКомпоновки)
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, НастройкаКомпоновки, ,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"), ПроверятьДоступностьПолей);
Если МакетКомпоновки.НаборыДанных.Количество() = 0 Тогда
// Нет прав на таблицу
Возврат Неопределено;
КонецЕсли;
СтрокаПорядка = ВыражениеПорядкаКомпоновкиНаЯзыкеЗапросовЛкс(КопияПорядка,,,, МакетКомпоновки.НаборыДанных[0].Поля);
Запрос = Новый Запрос;
Если МакетКомпоновки.НаборыДанных.Количество() > 2 Тогда
СообщитьЛкс("В макете компоновки обнаружено более одного запроса");
КонецЕсли;
ТекстЗапроса = МакетКомпоновки.НаборыДанных[0].Запрос;
Если ДобавлятьУпорядочивание Тогда
Если ЗначениеЗаполнено(СтрокаПорядка) Тогда
ТекстЗапроса = ТекстЗапроса + "
|//Секция_Упорядочить. Этот комментарий используется в коде
|УПОРЯДОЧИТЬ ПО
| " + СтрокаПорядка;
КонецЕсли;
Если Ложь
Или Автоупорядочивание
//Или ЗначениеЗаполнено(СтрокаПорядка)
Тогда
ТекстЗапроса = ТекстЗапроса + "
|//Секция_Упорядочить. Этот комментарий используется в коде
|АВТОУПОРЯДОЧИВАНИЕ";
КонецЕсли;
КонецЕсли;
Запрос.Текст = ТекстЗапроса;
Для Каждого ЗначениеПараметра Из МакетКомпоновки.ЗначенияПараметров Цикл
Запрос.Параметры.Вставить(ЗначениеПараметра.Имя, ЗначениеПараметра.Значение);
КонецЦикла;
Если ПрефиксИменПараметров <> "" Тогда
ДобавитьПрефиксВсемПараметрамЗапросаЛкс(Запрос, ПрефиксИменПараметров);
КонецЕсли;
Если выхСхемаКолонок <> Неопределено Тогда
//выхСхемаКолонок = ПолучитьСхемуКолонокМакетаКомпоновкиДанныхЛкс(МакетКомпоновки);
//
НаборДанныхМакета = МакетКомпоновки.НаборыДанных[0];
Для Каждого ПолеНабора Из НаборДанныхМакета.Поля Цикл
выхСхемаКолонок.Вставить(ПолеНабора.Имя, ПолеНабора.ПутьКДанным);
КонецЦикла;
Для Каждого ВложенныйНаборДанных Из НаборДанныхМакета.ВложенныеНаборыДанных Цикл
выхСхемаКолонок.Вставить(ВложенныйНаборДанных.Имя, ВложенныйНаборДанных.ПутьКДанным);
КонецЦикла;
КонецЕсли;
Возврат Запрос;
КонецФункции
Функция ОбренутьВыражениеЗапросаДляГруппировкиЛкс(Выражение, ОписаниеТипов, ДобавитьКонечноеПодчеркивание = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов = Новый ОписаниеТипов;
#КонецЕсли
Результат = Выражение;
Если ОписаниеТипов.СодержитТип(Тип("Строка")) Тогда
Если ОписаниеТипов.КвалификаторыСтроки.Длина = 0 Тогда
Результат = "ПОДСТРОКА(ВЫРАЗИТЬ(" + Результат + " КАК СТРОКА(300)), 1, 300)";
КонецЕсли;
Если ДобавитьКонечноеПодчеркивание Тогда
Результат = Результат + " + ""_"""
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Получает строку для установки порядка компоновки.
//
// Параметры:
// ПорядокКомпоновки - ПорядокКомпоновкиДанных, ЭлементыПорядкаКомпоновкиДанных
// ИсключаемоеПоле - Строка
// СимволЗаменыТочки - Строка
// ДиалектSQL - Строка
// ПутиКДаннымПолей - ПоляНабораДанныхЗапросаМакетаКомпоновкиДанных
//
// Возвращаемое значение:
// Строка - для установки порядка.
//
Функция ВыражениеПорядкаКомпоновкиНаЯзыкеЗапросовЛкс(Знач ПорядокКомпоновки, ИсключаемоеПоле = "", СимволЗаменыТочки = Неопределено, ДиалектSQL = "1С", ПутиКДаннымПолей = Неопределено,
УчитыватьПравыеПробелыСтрок = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый НастройкиКомпоновкиДанных;
ПорядокКомпоновки = Пустышка.Порядок;
#КонецЕсли
Это1С = СтрокиРавныЛкс(ДиалектSQL, "1С");
Если Это1С Тогда
СтрокаВозр = "Возр";
СтрокаУбыв = "Убыв";
Иначе
СтрокаВозр = "Asc";
СтрокаУбыв = "Desc";
КонецЕсли;
Если ТипЗнч(ПорядокКомпоновки) = Тип("ПорядокКомпоновкиДанных") Тогда
Если Это1С И ПутиКДаннымПолей = Неопределено Тогда
ДоступныеПоля = ПорядокКомпоновки.ДоступныеПоляПорядка;
КонецЕсли;
ПорядокКомпоновки = ПорядокКомпоновки.Элементы;
КонецЕсли;
Строка = "";
Для Каждого ЭлементПорядка Из ПорядокКомпоновки Цикл
Если Ложь
Или Не ЭлементПорядка.Использование
Или ТипЗнч(ЭлементПорядка) = Тип("АвтоЭлементПорядкаКомпоновкиДанных")
Или ИсключаемоеПоле = "" + ЭлементПорядка.Поле
Тогда
Продолжить;
КонецЕсли;
ИмяПоля = "" + ЭлементПорядка.Поле;
Если ПутиКДаннымПолей <> Неопределено Тогда
ПутьКДаннымПоля = НайтиЭлементКоллекцииЛкс(ПутиКДаннымПолей, "ПутьКДанным", ИмяПоля);
Если ПутьКДаннымПоля = Неопределено Тогда
// Например реквизит ТЧ
Продолжить;
КонецЕсли;
ИмяПоля = ПутьКДаннымПоля.Имя;
КонецЕсли;
Если ДоступныеПоля <> Неопределено Тогда
ДоступноеПоле = ДоступныеПоля.НайтиПоле(ЭлементПорядка.Поле);
КонецЕсли;
Если СимволЗаменыТочки <> Неопределено Тогда
ИмяПоля = СтрЗаменить(ИмяПоля, ".", СимволЗаменыТочки);
КонецЕсли;
Если ДоступныеПоля <> Неопределено И ДоступноеПоле <> Неопределено Тогда
ИмяПоля = ОбренутьВыражениеЗапросаДляГруппировкиЛкс(ИмяПоля, ДоступноеПоле.ТипЗначения, УчитыватьПравыеПробелыСтрок);
КонецЕсли;
Строка = Строка + ", " + ИмяПоля + " ";
Если ЭлементПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда
Строка = Строка + СтрокаВозр;
Иначе
Строка = Строка + СтрокаУбыв;
КонецЕсли;
КонецЦикла;
Возврат Сред(Строка, 3);
КонецФункции
// ТипНастроек - Число
Функция НастройкиДинамическогоСпискаЛкс(Знач ДинамическийСписок, ТипНастроек = "Результирующие") Экспорт
Если ТипЗнч(ДинамическийСписок) = Тип("ДинамическийСписок") Тогда
Если ТипНастроек = "Результирующие" Тогда
НастройкиСписка = ДинамическийСписок.КомпоновщикНастроек.ПолучитьНастройки();
ИначеЕсли ТипНастроек = "Фиксированные" Тогда
НастройкиСписка = ДинамическийСписок.КомпоновщикНастроек.ФиксированныеНастройки;
ИначеЕсли ТипНастроек = "Пользовательские" Тогда
ПользовательскиеНастройки = ДинамическийСписок.КомпоновщикНастроек.ПользовательскиеНастройки;
#Если Сервер И Не Сервер Тогда
ПользовательскиеНастройки = Новый ПользовательскиеНастройкиКомпоновкиДанных;
#КонецЕсли
НастройкиСписка = Новый Структура("Отбор, Порядок, УсловноеОформление");
Для Каждого ЭлементПользовательскихНастроек Из ПользовательскиеНастройки.Элементы Цикл
Если ТипЗнч(ЭлементПользовательскихНастроек) = Тип("ОтборКомпоновкиДанных") Тогда
НастройкиСписка.Отбор = ЭлементПользовательскихНастроек;
ИначеЕсли ТипЗнч(ЭлементПользовательскихНастроек) = Тип("ПорядокКомпоновкиДанных") Тогда
НастройкиСписка.Порядок = ЭлементПользовательскихНастроек;
ИначеЕсли ТипЗнч(ЭлементПользовательскихНастроек) = Тип("УсловноеОформлениеКомпоновкиДанных") Тогда
НастройкиСписка.УсловноеОформление = ЭлементПользовательскихНастроек;
КонецЕсли;
КонецЦикла;
Иначе
НастройкиСписка = ДинамическийСписок;
КонецЕсли;
Иначе
НастройкиСписка = ДинамическийСписок;
КонецЕсли;
Возврат НастройкиСписка;
КонецФункции
Функция ИмяОтсутствияПодсистемыЛкс() Экспорт
Возврат "<Не входящие в подсистемы>";
КонецФункции
Функция ПодсистемаПоПолномуИмениЛкс(Знач ПолноеИмяПодсистемы, Знач ПодсистемаПеревод = "") Экспорт
Если Не ЗначениеЗаполнено(ПодсистемаПеревод) Тогда
ПодсистемаПеревод = ПеревестиСтроку("Подсистема");
КонецЕсли;
МДПодсистема = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПодсистемаПеревод + "." + СтрЗаменить(ПолноеИмяПодсистемы, ".", "." + ПодсистемаПеревод + "."));
Возврат МДПодсистема;
КонецФункции
Функция ПолноеИмяПодсистемыЛкс(Знач Подсистема, Знач ПодсистемаПеревод = "") Экспорт
Если Не ЗначениеЗаполнено(ПодсистемаПеревод) Тогда
ПодсистемаПеревод = ПеревестиСтроку("Подсистема");
КонецЕсли;
ПолноеИмяПодсистемы = СтрЗаменить(Подсистема.ПолноеИмя(), ПодсистемаПеревод + ".", "");
Возврат ПолноеИмяПодсистемы;
КонецФункции
Функция ВсеПодсистемыЛкс(Подсистема = Неопределено, Результат = Неопределено) Экспорт
Если Подсистема = Неопределено Тогда
Подсистема = Метаданные;
КонецЕсли;
Если Результат = Неопределено Тогда
Результат = Новый СписокЗначений;
КонецЕсли;
Для Каждого ДочерняяПодсистема Из Подсистема.Подсистемы Цикл
Результат.Добавить(ПолноеИмяПодсистемыЛкс(ДочерняяПодсистема));
ВсеПодсистемыЛкс(ДочерняяПодсистема, Результат);
КонецЦикла;
Возврат Результат;
КонецФункции
// Параметры:
// СписокПодсистем - СписокЗначений
// Результат - Соответствие - ключи - объекты метаданных входящие в заданные подсистемы
Функция ОбъектыПодсистемЛкс(СписокПодсистем, СтрокаДереваПодсистем = Неопределено, ОбъектыВыбранныхПодсистем = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
СписокПодсистем = Новый СписокЗначений;
#КонецЕсли
Если ОбъектыВыбранныхПодсистем = Неопределено Тогда
ОбъектыВыбранныхПодсистем = Новый Соответствие;
КонецЕсли;
ПодсистемаПеревод = ПеревестиСтроку("Подсистема");
ИмяОтсутствияПодсистемы = ИмяОтсутствияПодсистемыЛкс();
Для Каждого ЭлементСписка Из СписокПодсистем Цикл
Если ЭлементСписка.Значение = ИмяОтсутствияПодсистемы Тогда
ВсеПодсистемы = ВсеПодсистемыЛкс();
ОбъектыВсехПодсистем = ОбъектыПодсистемЛкс(ВсеПодсистемы);
Для Каждого СтрокаТипаМетаданных Из ирКэш.ТипыМетаОбъектов(, Ложь, Ложь) Цикл
Если СтрокаТипаМетаданных.Единственное = "Перерасчет" Тогда
Продолжить;
КонецЕсли;
Для Каждого ОбъектМД Из Метаданные[СтрокаТипаМетаданных.Множественное] Цикл
Если ОбъектыВсехПодсистем[ОбъектМД] <> Неопределено Тогда
Продолжить;
КонецЕсли;
ОбъектыВыбранныхПодсистем.Вставить(ОбъектМД, 1);
КонецЦикла;
КонецЦикла;
Иначе
ПодсистемаМД = ПодсистемаПоПолномуИмениЛкс(ЭлементСписка.Значение);
Для Каждого ЭлементСостава Из ПодсистемаМД.Состав Цикл
ОбъектыВыбранныхПодсистем.Вставить(ЭлементСостава, 1);
КонецЦикла;
КонецЕсли;
КонецЦикла;
Возврат ОбъектыВыбранныхПодсистем;
КонецФункции
Функция НоваяТаблицаНастроекСтандартногоХранилищаЛкс() Экспорт
ТабОписаний = Новый ТаблицаЗначений;
ТабОписаний.Колонки.Добавить("ИмяХранилища");
ТабОписаний.Колонки.Добавить("ИмяОбъекта");
ТабОписаний.Колонки.Добавить("КлючНастроек");
ТабОписаний.Колонки.Добавить("Настройка");
ТабОписаний.Колонки.Добавить("ИмяПользователя");
ТабОписаний.Колонки.Добавить("Описание");
Возврат ТабОписаний;
КонецФункции
Функция МетаданныеНаборовЗаписейПоРегистраторуЛкс(мдОбъекта, ВключаяПоследовательности = Ложь, ВключаяПерерасчеты = Ложь, Сортировать = Ложь) Экспорт
ОбъектыМД = Новый Массив();
ЗащитаОтДублей = Новый Соответствие;
Для Каждого МетаРегистр из мдОбъекта.Движения Цикл
Если ЗащитаОтДублей[МетаРегистр.Имя] <> Неопределено Тогда
// https://www.hostedredmine.com/issues/943296
Продолжить;
КонецЕсли;
ЗащитаОтДублей[МетаРегистр.Имя] = 1;
ОбъектыМД.Добавить(МетаРегистр);
Если ВключаяПерерасчеты Тогда
Если ЛиКорневойТипРегистраРасчетаЛкс(ПервыйФрагментЛкс(МетаРегистр.ПолноеИмя())) Тогда
Для Каждого ПерерасчетМД Из МетаРегистр.Перерасчеты Цикл
ОбъектыМД.Добавить(ПерерасчетМД);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ВключаяПоследовательности Тогда
Для Каждого МетаПоследовательность Из Метаданные.Последовательности Цикл
Если МетаПоследовательность.Документы.Содержит(мдОбъекта) Тогда
ОбъектыМД.Добавить(МетаПоследовательность);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Сортировать Тогда
Список = Новый СписокЗначений;
Список.ЗагрузитьЗначения(ОбъектыМД);
Для Каждого ЭлементСписка Из Список Цикл
ЭлементСписка.Представление = ЭлементСписка.Значение.Имя;
КонецЦикла;
Список.СортироватьПоПредставлению();
ОбъектыМД = Список.ВыгрузитьЗначения();
КонецЕсли;
Возврат ОбъектыМД;
КонецФункции
// Функция считывает в табличный документ данные из текстового файла
//
// Параметры:
// ТабличныйДокумент - ТабличныйДокумент, в который необходимо прочитать данные
// ИмяФайла - имя текстового файла, из которого необходимо прочитать данные
//
// Возвращаемое значение:
// Истина, если файл прочитан, Ложь - иначе
//
Функция ПрочитатьТабличныйДокументИзТекстаЛкс(ТабличныйДокумент, ИмяФайла, Разделитель = ",", ОбрезатьНепечатныеСимволы = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
ВыбФайл = Новый Файл(ИмяФайла);
Если НЕ ВыбФайл.Существует() Тогда
СообщитьЛкс("Файл не существует!");
Возврат Ложь;
КонецЕсли;
ТекстовыйДокумент = Новый ТекстовыйДокумент;
Попытка
ТекстовыйДокумент.Прочитать(ИмяФайла);
Исключение
СообщитьЛкс("Ошибка открытия файла!");
Возврат Ложь;
КонецПопытки;
ТабличныйДокумент.Очистить();
Текст = ТекстовыйДокумент.ПолучитьТекст();
#Если Клиент Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаРазбивки = мПлатформа.ПолучитьФорму("РазбивкаТекста");
ФормаРазбивки.Приемник = ТабличныйДокумент;
ФормаРазбивки.Текст = Текст;
Если ФормаРазбивки.ОткрытьМодально() = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
#Иначе
ирОбщий.ТаблицаИзСтрокиСРазделителемЛкс(Текст, Разделитель, ОбрезатьНепечатныеСимволы, ТабличныйДокумент);
#КонецЕсли
Возврат Истина;
КонецФункции
// Функция считывает в табличный документ данные из файла в формате dBase III (*.dbf)
//
// Параметры:
// ТабличныйДокумент - ТабличныйДокумент, в который необходимо прочитать данные
// ИмяФайла - имя файла в формате TXT, из которого необходимо прочитать данные
//
// Возвращаемое значение:
// Истина, если файл прочитан, Ложь - иначе
//
Функция ПрочитатьТабличныйДокументИзDBFЛкс(ТабличныйДокумент, ИмяФайла) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
ВыбФайл = Новый Файл(ИмяФайла);
Если НЕ ВыбФайл.Существует() Тогда
СообщитьЛкс("Файл не существует!");
Возврат Ложь;
КонецЕсли;
XBase = Новый XBase;
XBase.Кодировка = КодировкаXBase.OEM;
Попытка
XBase.ОткрытьФайл(ИмяФайла);
Исключение
СообщитьЛкс("Ошибка открытия файла!");
Возврат Ложь;
КонецПопытки;
ТабличныйДокумент.Очистить();
ТекущаяСтрока = 1;
ТекущаяКолонка = 0;
Для каждого Поле Из XBase.поля Цикл
ТекущаяКолонка = ТекущаяКолонка + 1;
ТабличныйДокумент.Область("R" + Формат(ТекущаяСтрока, "ЧГ=") +"C" + Формат(ТекущаяКолонка, "ЧГ=")).Текст = Поле.Имя;
КонецЦикла;
Рез = XBase.Первая();
Пока Не XBase.ВКонце() Цикл
ТекущаяСтрока = ТекущаяСтрока + 1;
ТекущаяКолонка = 0;
Для каждого Поле Из XBase.поля Цикл
ТекущаяКолонка = ТекущаяКолонка + 1;
Если Поле.Тип = "M" Тогда
Продолжить;
КонецЕсли;
ТабличныйДокумент.Область("R" + Формат(ТекущаяСтрока, "ЧГ=") +"C" + Формат(ТекущаяКолонка, "ЧГ=")).Текст = XBase.ПолучитьЗначениеПоля(ТекущаяКолонка - 1);
КонецЦикла;
XBase.Следующая();
КонецЦикла;
Возврат Истина;
КонецФункции // ()
// Параметры:
// ТаблицаПриемник - ТабличныйДокумент, ТаблицаЗначений, *Неопределено
//
Функция ТаблицаИзСтрокиСРазделителемЛкс(Знач Текст, Разделитель = ",", ОбрезатьНепечатныеСимволы = Ложь, Знач ИменаКолонокИзПервойСтроки = Ложь, Знач ТаблицаПриемник = Неопределено,
Знач ОписаниеТипов = Неопределено, Знач РазворачиватьКавычки = Истина) Экспорт
Если ТаблицаПриемник = Неопределено Тогда
ТаблицаПриемник = Новый ТаблицаЗначений;
КонецЕсли;
КоличествоКолонок = 0;
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(Текст);
КоличествоСтрок = ТекстовыйДокумент.КоличествоСтрок();
Индикатор = ПолучитьИндикаторПроцессаЛкс(КоличествоСтрок, "Разбивка текста");
Для СчетчикСтроки = 1 По КоличествоСтрок Цикл
ОбработатьИндикаторЛкс(Индикатор);
СтрокаТекста = ТекстовыйДокумент.ПолучитьСтроку(СчетчикСтроки);
Массив = СтрРазделитьЛкс(СтрокаТекста, Разделитель, ОбрезатьНепечатныеСимволы, Истина);
Если КоличествоКолонок < Массив.Количество() Тогда
Если ТипЗнч(ТаблицаПриемник) = Тип("ТаблицаЗначений") Тогда
Для ИндексКолонки = КоличествоКолонок По Массив.Количество() - 1 Цикл
Если ИменаКолонокИзПервойСтроки И СчетчикСтроки = 1 Тогда
ЗаголовокКолонки = Массив[ИндексКолонки];
Если РазворачиватьКавычки Тогда
ЗаголовокКолонки = ирОбщий.СтрокаИзВыраженияВстроенногоЯзыкаЛкс(ЗаголовокКолонки);
КонецЕсли;
ИмяКолонки = ИдентификаторИзПредставленияЛкс(ЗаголовокКолонки);
ИмяКолонки = АвтоУникальноеИмяВКоллекцииЛкс(ТаблицаПриемник.Колонки, ИмяКолонки);
Иначе
ИмяКолонки = "Колонка" + XMLСтрока(ИндексКолонки);
ЗаголовокКолонки = "";
КонецЕсли;
ТаблицаПриемник.Колонки.Добавить(ИмяКолонки, ОписаниеТипов, ЗаголовокКолонки);
КонецЦикла;
КонецЕсли;
КоличествоКолонок = Массив.Количество();
//ИначеЕсли КоличествоКолонок > Массив.Количество() Тогда
// СообщитьЛкс("В строке текст №" + XMLСтрока(СчетчикСтроки) + " указаны значения не для всех колонок");
КонецЕсли;
Если ТипЗнч(ТаблицаПриемник) = Тип("ТаблицаЗначений") Тогда
Если ИменаКолонокИзПервойСтроки И СчетчикСтроки = 1 Тогда
Продолжить;
КонецЕсли;
СтрокаТаблицы = ТаблицаПриемник.Добавить();
Для ИндексКолонки = 0 По Массив.ВГраница() Цикл
ТекстЯчейки = Массив[ИндексКолонки];
Если РазворачиватьКавычки Тогда
ТекстЯчейки = ирОбщий.СтрокаИзВыраженияВстроенногоЯзыкаЛкс(ТекстЯчейки);
КонецЕсли;
СтрокаТаблицы[ИндексКолонки] = ТекстЯчейки;
КонецЦикла;
Иначе //Если ТипЗнч(ТаблицаПриемник) = Тип("ТабличныйДокумент") Тогда
#Если Сервер И Не Сервер Тогда
ТаблицаПриемник = Новый ТабличныйДокумент;
#КонецЕсли
АдресЯчейки = "R" + Формат(СчетчикСтроки, "ЧГ=") + "C";
Для ИндексКолонки = 0 По Массив.ВГраница() Цикл
ТекстЯчейки = Массив[ИндексКолонки];
Если РазворачиватьКавычки Тогда
ТекстЯчейки = ирОбщий.СтрокаИзВыраженияВстроенногоЯзыкаЛкс(ТекстЯчейки);
КонецЕсли;
ТаблицаПриемник.Область(АдресЯчейки + Формат(ИндексКолонки + 1, "ЧГ=")).Текст = ТекстЯчейки;
КонецЦикла;
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
Возврат ТаблицаПриемник;
КонецФункции
Процедура КонвертироватьСтроковуюТаблицуВТипизированнуюЛкс(ТаблицаСтроковыхЗначений, ТаблицаТипизированая, АмериканскоеПоложениеМесяца = Ложь, РазворачиватьКавычки = Истина) Экспорт
Конвертор = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирЗагрузкаТабличныхДанных");
#Если Сервер И Не Сервер Тогда
ТаблицаСтроковыхЗначений = Новый ТаблицаЗначений;
ТаблицаТипизированая = Новый ТаблицаЗначений;
Конвертор = Обработки.ирЗагрузкаТабличныхДанных.Создать();
#КонецЕсли
Для Каждого СтрокаСтроковая Из ТаблицаСтроковыхЗначений Цикл
СтрокаТипизированная = ТаблицаТипизированая.Добавить();
Для Каждого Колонка Из ТаблицаСтроковыхЗначений.Колонки Цикл
СтроковоеЗначение = СтрокаСтроковая[Колонка.Имя];
Если Истина
И РазворачиватьКавычки
И Лев(СтроковоеЗначение, 1) = """"
И Прав(СтроковоеЗначение, 1) = """"
Тогда
СтроковоеЗначение = ирОбщий.СтрокаИзВыраженияВстроенногоЯзыкаЛкс(СтроковоеЗначение);
//СтроковеЗначение = ирОбщий.СтрокаБезКонцаЛкс(Сред(СтроковеЗначение, 2), 1);
КонецЕсли;
ТипКолонки = ТипЗнч(СтрокаТипизированная[Колонка.Имя]);
Если ТипКолонки = Тип("Дата") Тогда
СтрокаТипизированная[Колонка.Имя] = Конвертор.мПривестиКДате(СтроковоеЗначение,,, АмериканскоеПоложениеМесяца);
ИначеЕсли Ложь
Или ТипКолонки = Тип("Число")
Или ТипКолонки = Тип("Булево")
Тогда
СтрокаТипизированная[Колонка.Имя] = Конвертор.СтрокаВЧислоЛкс(СтроковоеЗначение);
Иначе
СтрокаТипизированная[Колонка.Имя] = СтроковоеЗначение;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция ИнтерактивноКонвертироватьМассивСтрокЛкс(Знач Массив, ОписаниеТипов = Неопределено) Экспорт
ЗагрузкаТабличныхДанных = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирЗагрузкаТабличныхДанных");
#Если Сервер И Не Сервер Тогда
ЗагрузкаТабличныхДанных = Обработки.ирЗагрузкаТабличныхДанных.Создать();
#КонецЕсли
Форма = ЗагрузкаТабличныхДанных.ПолучитьФорму();
ТаблицаЗначений = Новый ТаблицаЗначений;
ТаблицаЗначений.Колонки.Добавить("Значение", ОписаниеТипов);
Форма.ТаблицаЗначений = ТаблицаЗначений;
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.Область(1, 1).Текст = "Значение";
ТабличныйДокумент.Область(1, 1).Шрифт = Новый Шрифт(,, Истина);
Для Счетчик = 1 По Массив.Количество() Цикл
ТабличныйДокумент.Область(Счетчик + 1, 1).Текст = Массив[Счетчик - 1];
КонецЦикла;
Форма.ПараметрТабличныйДокумент = ТабличныйДокумент;
Форма.РежимРедактора = Истина;
РезультатКонвертации = Форма.ОткрытьМодально();
Если РезультатКонвертации <> Неопределено Тогда
Массив = Форма.ТаблицаЗначений.ВыгрузитьКолонку("Значение");
КонецЕсли;
Возврат Массив;
КонецФункции
Функция ОбщийТипДанныхТабличногоПоляЛкс(Знач ТабличноеПоле, ПреобразоватьТипДанныхФормыИнструмента = Ложь, выхСтруктураТипаМетаданных = Неопределено, выхПолноеИмяТаблицыБД = "",
выхДанныеТабличногоПоля = Неопределено) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
выхДанныеТабличногоПоля = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
Если ПреобразоватьТипДанныхФормыИнструмента Тогда
ТипЗначенияТабличногоПоля = ирОбщий.ТипЗначенияЭлементаФормыЛкс(ТабличноеПоле).Типы()[0];
Иначе
ТипЗначенияТабличногоПоля = ТипЗнч(выхДанныеТабличногоПоля);
КонецЕсли;
Если ТипЗначенияТабличногоПоля = Тип("ТаблицаЗначений") Тогда
ТипИсточника = "ТаблицаЗначений";
ИначеЕсли ТипЗначенияТабличногоПоля = Тип("ДеревоЗначений") Тогда
ТипИсточника = "ДеревоЗначений";
ИначеЕсли ТипЗначенияТабличногоПоля = Тип("СписокЗначений") Тогда
ТипИсточника = "СписокЗначений";
ИначеЕсли ЛиДанныеФормыСВозможностьюПоискаЛкс(ТипЗначенияТабличногоПоля) Тогда
ТипИсточника = "ТаблицаЗначений";
ИначеЕсли ТипЗначенияТабличногоПоля = Тип("ДанныеФормыДерево") Тогда
ТипИсточника = "ДеревоЗначений";
Иначе
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(ТипЗначенияТабличногоПоля);
Если Ложь
Или Найти(СтруктураТипа.ИмяОбщегоТипа, "<Имя табличной части>") > 0
Или Найти(СтруктураТипа.ИмяОбщегоТипа, "ВидыСубконто") > 0
Или Найти(СтруктураТипа.ИмяОбщегоТипа, "БазовыеВидыРасчета") > 0
Или Найти(СтруктураТипа.ИмяОбщегоТипа, "ВедущиеВидыРасчета") > 0
Или Найти(СтруктураТипа.ИмяОбщегоТипа, "ВытесняющиеВидыРасчета") > 0
Тогда
ТипИсточника = "ТабличнаяЧасть";
ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "НаборЗаписей.") > 0 Тогда
ТипИсточника = "НаборЗаписей";
ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "Список.") > 0 Тогда
ТипИсточника = "Список";
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ДинамическийСписок" Тогда
ТипИсточника = "Список";
КонецЕсли;
Если СтруктураТипа.ИмяОбщегоТипа <> "Неопределено" Тогда
выхСтруктураТипаМетаданных = СтруктураТипа;
КонецЕсли;
выхПолноеИмяТаблицыБД = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле);
Если Истина
И Не ЗначениеЗаполнено(ТипИсточника)
И ЗначениеЗаполнено(выхПолноеИмяТаблицыБД)
Тогда
ТипИсточника = "Список";
КонецЕсли;
КонецЕсли;
Возврат ТипИсточника;
КонецФункции
Функция ЛиДанныеФормыСВозможностьюПоискаЛкс(Знач ДанныеИлиТипТаблицы) Экспорт
Если ТипЗнч(ДанныеИлиТипТаблицы) <> Тип("Тип") Тогда
Тип = ТипЗнч(ДанныеИлиТипТаблицы);
Иначе
Тип = ДанныеИлиТипТаблицы;
КонецЕсли;
Возврат Ложь
Или Тип = Тип("СписокЗначений")
Или Тип = Тип("ДанныеФормыКоллекция")
Или Тип = Тип("ДанныеФормыСтруктураСКоллекцией");
КонецФункции
// Параметры:
// ЭтаФорма - Форма
// ТабличноеПоле - ТабличноеПоле
// КлючевоеПоле - Строка
// ЗначениеКлюча -
// СообщатьОбУспехе - Булево
//
Функция УстановитьТекущуюСтрокуСКонтролемУспешностиЛкс(Знач ЭтаФорма, Знач ТабличноеПоле, Знач КлючевоеПоле = "Ссылка", Знач ЗначениеКлюча = Неопределено, Знач СообщатьОбУспехе = Ложь,
АктивизироватьТабличноеПолеПриУспехе = Ложь, ВыводитьСообщения = Истина) Экспорт
ПолноеИмяТаблицыБД = "";
ДанныеТабличногоПоля = Неопределено;
ТипИсточника = ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле,,, ПолноеИмяТаблицыБД, ДанныеТабличногоПоля);
Если Ложь
Или ТипИсточника = "ТаблицаЗначений"
Или ТипИсточника = "ТабличнаяЧасть"
Или ТипИсточника = "НаборЗаписей"
Тогда
ДанныеТабличногоПоля = ирОбщий.ДанныеЭлементаФормыЛкс(ТабличноеПоле);
#Если Сервер И Не Сервер Тогда
ДанныеТабличногоПоля = Новый ТаблицаЗначений;
#КонецЕсли
Если КлючевоеПоле <> Неопределено Тогда
НайденныеСтроки = ДанныеТабличногоПоля.НайтиСтроки(Новый Структура(КлючевоеПоле, ЗначениеКлюча));
Иначе
НайденныеСтроки = ДанныеТабличногоПоля;
КонецЕсли;
Если НайденныеСтроки.Количество() > 0 Тогда
НайденнаяСтрока = НайденныеСтроки[0];
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
НайденнаяСтрока = НайденнаяСтрока.ПолучитьИдентификатор();
КонецЕсли;
КонецЕсли;
ЭтоКлиентскийИсточникДанных = Истина;
ИначеЕсли ТипИсточника = "ДеревоЗначений" Тогда
НайденнаяСтрока = ТабличноеПоле.Значение.Строки.Найти(ЗначениеКлюча, КлючевоеПоле, Истина);
ЭтоКлиентскийИсточникДанных = Истина;
Иначе
НайденнаяСтрока = ЗначениеКлюча;
Если ДанныеТабличногоПоля <> Неопределено Тогда
Отбор = ДанныеТабличногоПоля.Отбор;
ЭтоКлиентскийИсточникДанных = Ложь;
ПостроительЗапроса = Новый ПостроительЗапроса;
ПостроительЗапроса.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ " + ПолноеИмяТаблицыБД;
ПостроительЗапроса.ЗаполнитьНастройки();
СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицыБД,,, Ложь);
ЗаполнитьЗначенияСвойств(СтруктураКлюча, ЗначениеКлюча);
УстановитьОтборПоСтруктуреЛкс(ПостроительЗапроса.Отбор, СтруктураКлюча);
СтрокаЕстьВИсточникеДанных = Не ПостроительЗапроса.Результат.Пустой();
Иначе
СтрокаЕстьВИсточникеДанных = Истина; // Немного криво
КонецЕсли;
КонецЕсли;
Если ЭтоКлиентскийИсточникДанных Тогда
СтрокаЕстьВИсточникеДанных = НайденнаяСтрока <> Неопределено;
КонецЕсли;
Если СтрокаЕстьВИсточникеДанных Тогда
ТабличноеПоле.ТекущаяСтрока = НайденнаяСтрока;
ИначеЕсли ВыводитьСообщения Тогда
СообщитьЛкс("Строка не найдена в источнике данных");
КонецЕсли;
Если ТабличноеПоле.ТекущаяСтрока = НайденнаяСтрока Тогда
Если АктивизироватьТабличноеПолеПриУспехе Тогда
ЭтаФорма.ТекущийЭлемент = ТабличноеПоле;
КонецЕсли;
Результат = Истина;
Иначе
Если ВыводитьСообщения И СтрокаЕстьВИсточникеДанных Тогда
ТекстСообщения = "Строка найдена в источнике данных, но не найдена в табличном поле";
Если Отбор <> Неопределено Тогда
ТекстСообщения = ТекстСообщения + " с учетом отбора " + Отбор;
КонецЕсли;
СообщитьЛкс(ТекстСообщения, СтатусСообщения.Внимание);
КонецЕсли;
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры
// МетаданныеКолонок - КоллекцияОбъектовМетаданных, ТаблицаЗначений - для таблицы значений используются колонки Имя и Метаданные
Процедура НастроитьДобавленныеКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, ОписанияКолонок = Неопределено, МетаданныеКолонок = Неопределено, ДоступныеПоляВыбора = Неопределено,
ТолькоПросмотр = Ложь, Формат = "") Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
Если ОписанияКолонок = Неопределено Тогда
ОписанияКолонок = ирСервер.ПолучитьТаблицуДочернихРеквизитовЛкс(ТабличноеПоле);
КонецЕсли;
Иначе
#Если Клиент Тогда
ТабличноеПолеВключитьСтаруюЦветовуюСхемуЛкс(ТабличноеПоле);
#КонецЕсли
Если ОписанияКолонок = Неопределено Тогда
ОписанияКолонок = ТабличноеПоле.Значение.Колонки;
КонецЕсли;
КонецЕсли;
КолонкиТабличногоПоля = ТабличноеПоле.Колонки;
#Если Сервер И Не Сервер Тогда
КолонкиТабличногоПоля = Новый ТаблицаЗначений;
КолонкиТабличногоПоля = КолонкиТабличногоПоля.Колонки;
#КонецЕсли
МассивКолонокДанных = МассивИзКоллекцииЛкс(КолонкиТабличногоПоля);
Для Каждого КолонкаДанных Из МассивКолонокДанных Цикл
Для Каждого КолонкаДанныхОсновная Из МассивКолонокДанных Цикл
Если "Несогласовано_" + КолонкаДанныхОсновная.Имя = КолонкаДанных.Имя Тогда
КолонкиТабличногоПоля.Сдвинуть(КолонкаДанных, КолонкиТабличногоПоля.Индекс(КолонкаДанныхОсновная) - КолонкиТабличногоПоля.Индекс(КолонкаДанных) + 1);
КонецЕсли;
КонецЦикла;
КонецЦикла;
МинимальнаяШиринаКолонки = МинимальнаяШиринаКолонкиЛкс();
Для Каждого КолонкаТаблицы Из ОписанияКолонок Цикл
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
КолонкаТП = ТабличноеПоле.ПодчиненныеЭлементы.Найти(ТабличноеПоле.Имя + КолонкаТаблицы.Имя);
Иначе
КолонкаТП = ТабличноеПоле.Колонки.Найти(КолонкаТаблицы.Имя);
КонецЕсли;
Если КолонкаТП = Неопределено Тогда
Продолжить;
КонецЕсли;
Если КолонкаТП.Видимость Тогда
УстановитьТекущуюКолонкуТаблицыФормыЛкс(ТабличноеПоле, КолонкаТП, Истина);
КонецЕсли;
Если ТолькоПросмотр Тогда
КолонкаТП.ТолькоПросмотр = Истина;
КонецЕсли;
Если ЗначениеЗаполнено(Формат) Тогда
КолонкаТП.Формат = Формат;
КонецЕсли;
Если ДоступныеПоляВыбора <> Неопределено Тогда
ДоступноеПоле = ДоступныеПоляВыбора.НайтиПоле(Новый ПолеКомпоновкиДанных(КолонкаТаблицы.Имя));
Если ДоступноеПоле <> Неопределено Тогда
ТекстШапки = ДоступноеПоле.Заголовок;
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
КолонкаТП.Заголовок = ТекстШапки;
Иначе
КолонкаТП.ТекстШапки = ТекстШапки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Ложь
#Если Клиент Тогда
Или ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле")
#КонецЕсли
Тогда
ТипЗначенияКолонки = КолонкаТаблицы.ТипЗначения;
#Если Сервер И Не Сервер Тогда
ТипЗначенияКолонки = Новый ОписаниеТипов;
#КонецЕсли
ТипЗначенияКолонки = Новый ОписаниеТипов(ТипЗначенияКолонки,, "Null");
ТипыРеквизита = ТипЗначенияКолонки.Типы();
Если ТипыРеквизита.Количество() = 1 И ТипыРеквизита[0] = Тип("Булево") Тогда
КолонкаТП.Ширина = МинимальнаяШиринаКолонки;
КолонкаТП.КартинкиСтрок = ирКэш.КартинкаПоИмениЛкс("ирСостоянияФлажка");
ИначеЕсли Истина
И ТипыРеквизита.Количество() = 1
И ТипЗначенияКолонки.СодержитТип(Тип("Число"))
И ТипЗначенияКолонки.КвалификаторыЧисла.Разрядность = 0
И КолонкаТП.Ширина = 1
Тогда
// Почему то в этом случае платформа устанавливает ширину 1
КолонкаТП.Ширина = 10;
Иначе
Если КолонкаТаблицы.Ширина > 0 Тогда
КолонкаТП.Ширина = Мин(КолонкаТаблицы.Ширина, 50); // Почему то в редакторе таблицы значений не работала автоширина (-1)
КонецЕсли;
Если КолонкаТП.Ширина = 0 Тогда
КолонкаТП.Ширина = МинимальнаяШиринаКолонки; // Для 8.2 необходимо, иначе колонки будут не видны
КонецЕсли;
КонецЕсли;
Если МетаданныеКолонок <> Неопределено Тогда
Если ТипЗнч(МетаданныеКолонок) = Тип("КоллекцияОбъектовМетаданных") Тогда
Метареквизит = МетаданныеКолонок.Найти(КолонкаТаблицы.Имя);
Иначе
СтрокаПоля = МетаданныеКолонок.Найти(КолонкаТаблицы.Имя, "Имя");
Если СтрокаПоля <> Неопределено Тогда
Метареквизит = СтрокаПоля.Метаданные;
Иначе
Метареквизит = Неопределено;
КонецЕсли;
КонецЕсли;
Если Метареквизит <> Неопределено Тогда
Попытка
Подсказка = Метареквизит.Подсказка;
Исключение
// У графы журнала нет подсказки
Подсказка = Неопределено;
КонецПопытки;
Если Подсказка <> Неопределено Тогда
КолонкаТП.ПодсказкаВШапке = Подсказка;
Если Истина
И Метареквизит.Тип.СодержитТип(Тип("Строка"))
И Метареквизит.МногострочныйРежим
Тогда
КолонкаТП.ЭлементУправления.МногострочныйРежим = Метареквизит.МногострочныйРежим;
КолонкаТП.ЭлементУправления.РасширенноеРедактирование = Метареквизит.РасширенноеРедактирование;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ДобавитьОписаниеТиповВПодсказкуШапкиКолонкиЛкс(КолонкаТП, ТипЗначенияКолонки);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура НастроитьКолонкуКартинкиЛкс(Знач КолонкаКартинки) Экспорт
#Если Клиент Тогда
КолонкаКартинки.ТолькоПросмотр = Истина;
КолонкаКартинки.Видимость = Истина;
КолонкаКартинки.Ширина = 4;
КолонкаКартинки.ИзменениеРазмера = ИзменениеРазмераКолонки.НеИзменять;
КолонкаКартинки.ЦветТекстаШапки = ЦветаСтиля.ЦветФонаКнопки;
#КонецЕсли
КонецПроцедуры
Процедура ДобавитьОписаниеТиповВПодсказкуШапкиКолонкиЛкс(Знач КолонкаТабличногоПоля, ТипЗначенияКолонки) Экспорт
Если ТипЗнч(КолонкаТабличногоПоля) = Тип("ПолеФормы") Тогда
НоваяПодсказка = КолонкаТабличногоПоля.Подсказка;
Если Не ЗначениеЗаполнено(НоваяПодсказка) Тогда
НоваяПодсказка = КолонкаТабличногоПоля.Заголовок;
КонецЕсли;
Иначе
НоваяПодсказка = КолонкаТабличногоПоля.ПодсказкаВШапке;
Если Не ЗначениеЗаполнено(НоваяПодсказка) Тогда
НоваяПодсказка = КолонкаТабличногоПоля.ТекстШапки;
КонецЕсли;
КонецЕсли;
МаркерТипа = Символы.ПС + "Тип: ";
Если Найти(НоваяПодсказка, МаркерТипа) = 0 Тогда
НоваяПодсказка = НоваяПодсказка + МаркерТипа + РасширенноеПредставлениеЗначенияЛкс(ТипЗначенияКолонки,,,,,, 5);
Если ТипЗнч(КолонкаТабличногоПоля) = Тип("ПолеФормы") Тогда
КолонкаТабличногоПоля.Подсказка = НоваяПодсказка;
Иначе
КолонкаТабличногоПоля.ПодсказкаВШапке = НоваяПодсказка;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура УстановитьТекущуюКолонкуТаблицыФормыЛкс(Знач ТабличноеПоле, Знач Колонка, Знач ТолькоЕслиНеопределена = Ложь) Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
Если Не ТолькоЕслиНеопределена Или ТабличноеПоле.ТекущийЭлемент = Неопределено Тогда
ТабличноеПоле.ТекущийЭлемент = Колонка;
КонецЕсли;
Иначе
Если Не ТолькоЕслиНеопределена Или ТабличноеПоле.ТекущаяКолонка = Неопределено Тогда
ТабличноеПоле.ТекущаяКолонка = Колонка;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция СостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс() Экспорт
МассивСостояний = Новый Массив;
МассивСостояний.Добавить("Не отображать");
МассивСостояний.Добавить("Отображать пустые");
МассивСостояний.Добавить("Отображать пустые и идентификаторы");
Возврат МассивСостояний;
КонецФункции
Функция КлючХраненияНастроекФормыЛкс(Знач ЭтаФорма) Экспорт
Результат = ирОбщий.ИмяФормыИзФормыЛкс(ЭтаФорма);
// Сделать потом новый режим формирования ключа хранения и флажок в общих настройках чтобы пользователь сам его включал для использования нового ключа.
//Фрагменты = СтрРазделитьЛкс(Результат);
//Фрагменты.Удалить(2);
//Фрагменты.Удалить(0);
//Результат = СтрСоединитьЛкс(Фрагменты);
Возврат Результат;
КонецФункции
Функция КлючСохраненияСпискаПоследнихЗначенийФормыЛкс(ЭтаФорма, Знач ТабличноеПолеИлиКлюч = Неопределено, ТипКлюча = "Выбранные", Знач ДопКлючХранения = "") Экспорт
Если ТипЗнч(ТабличноеПолеИлиКлюч) = Тип("Строка") Тогда
Результат = ТабличноеПолеИлиКлюч;
Иначе
Если ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма") Тогда
КлючУникальности = ЭтаФорма.мКлючУникальности;
Иначе
КлючУникальности = ЭтаФорма.КлючУникальности;
КонецЕсли;
Результат = КлючХраненияНастроекФормыЛкс(ЭтаФорма) + ".";
Если Не ЭтаФорма.РежимВыбора Тогда
Если ТабличноеПолеИлиКлюч <> Неопределено Тогда
Результат = Результат + ТабличноеПолеИлиКлюч.Имя + ".";
Иначе
ирОбщий.СообщитьЛкс("В форме не в режиме выбора при формировании ключа списка последних выбранных значений нужно указывать табличное поле");
КонецЕсли;
КонецЕсли;
Результат = Результат + Лев(ДопКлючХранения, 30);
Результат = Результат + Лев(КлючУникальности, 30);
КонецЕсли;
Результат = Результат + ".Последние" + ТипКлюча;
Возврат Результат;
КонецФункции
// Параметры:
// ЭтаФорма - Форма
// КнопкаПодменю - Кнопка - подменю, в которое будут добавлены кнопки
//
Процедура ПоследниеВыбранныеЗаполнитьПодменюЛкс(Знач ЭтаФорма, Знач КнопкаПодменю, Знач ТабличноеПолеИлиКлюч = Неопределено, Знач ОбработчикКнопки = Неопределено,
Знач ТипКлюча = "Выбранные", Знач ДопКлючХранения = "") Экспорт
КлючЗначения = КлючСохраненияСпискаПоследнихЗначенийФормыЛкс(ЭтаФорма, ТабличноеПолеИлиКлюч, ТипКлюча, ДопКлючХранения);
ПоследниеВыбранные = ВосстановитьЗначениеЛкс(КлючЗначения);
Если ТипЗнч(КнопкаПодменю) = Тип("ГруппаФормы") Тогда
ОчиститьПодчиненныеЭлементыФормыЛкс(КнопкаПодменю, 0);
Иначе
КнопкаПодменю.Кнопки.Очистить();
КонецЕсли;
Если ТипЗнч(ПоследниеВыбранные) <> Тип("СписокЗначений") Тогда
Возврат;
КонецЕсли;
ЗапоминатьПоследниеВыбранные = КоличествоЗапоминаемыхПоследнихВыбранныхЛкс();
Для Счетчик = ЗапоминатьПоследниеВыбранные По ПоследниеВыбранные.Количество() - 1 Цикл
ПоследниеВыбранные.Удалить(ЗапоминатьПоследниеВыбранные);
КонецЦикла;
#Если Клиент Тогда
Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда
КомандныеПанелиКнопок = СлужебныеДанныеФормыЛкс(ЭтаФорма).КомандныеПанелиКнопок;
КонецЕсли;
#КонецЕсли
ПодсказкаКнопки = "Активировать выбранный элемент в списке";
Для каждого ЭлементСписка Из ПоследниеВыбранные Цикл
ИмяКнопки = НачалоИмениКнопкиПодменюПоследнихВыбранных(ТипКлюча) + ПоследниеВыбранные.Индекс(ЭлементСписка);
Если ТипЗнч(КнопкаПодменю) = Тип("ГруппаФормы") Тогда
Кнопка = ЭтаФорма.Элементы.Добавить(КнопкаПодменю.Имя + ИмяКнопки, Тип("КнопкаФормы"), КнопкаПодменю);
//Кнопка.Отображение = ОтображениеКнопкиКоманднойПанели.Авто;
Кнопка.Заголовок = ЭлементСписка.Представление;
Попытка
Кнопка.ИмяКоманды = ИмяКнопки;
Исключение
Прервать;
КонецПопытки;
Иначе
#Если Клиент Тогда
Кнопка = КнопкаПодменю.Кнопки.Добавить();
Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
Кнопка.Имя = ИмяКнопки;
//Кнопка.Отображение = ОтображениеКнопкиКоманднойПанели.Авто;
ТекстКнопки = ЭлементСписка.Представление;
ЗаменитьФигурныеСкобкиЛкс(ТекстКнопки); // https://www.hostedredmine.com/issues/946247
Кнопка.Текст = ТекстКнопки;
Кнопка.Подсказка = ПодсказкаКнопки;
Кнопка.Пояснение = Кнопка.Подсказка;
Если ОбработчикКнопки = Неопределено Тогда
ОбработчикКнопки = Новый Действие("ПоследниеВыбранныеНажатие");
КонецЕсли;
Попытка
Кнопка.Действие = ОбработчикКнопки;
Исключение
Прервать;
КонецПопытки;
КомандныеПанелиКнопок[Кнопка] = КнопкаПодменю;
#КонецЕсли
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ЗаменитьФигурныеСкобкиЛкс(ТекстКнопки)
ТекстКнопки = СтрЗаменить(ТекстКнопки, "{", " ");
ТекстКнопки = СтрЗаменить(ТекстКнопки, "}", " ");
КонецПроцедуры
Процедура ОбновитьПодменюПоследнихОтборовЛкс(ЭтаФорма, Знач КоманднаяПанель, Знач ТабличноеПоле) Экспорт
#Если Клиент Тогда
ирОбщий.ПоследниеВыбранныеЗаполнитьПодменюЛкс(ЭтаФорма, КоманднаяПанель.Кнопки.ПоследниеОтборы, ТабличноеПоле, Новый Действие("КлсКомандаНажатие"), "Отборы");
ЭтаФорма.ОбработчикИзмененияДанных("ЭлементыФормы." + ТабличноеПоле.Имя + ".Отбор");
#КонецЕсли
КонецПроцедуры
Функция КоличествоЗапоминаемыхПоследнихВыбранныхЛкс()
Возврат 20;
КонецФункции
Функция НачалоИмениКнопкиПодменюПоследнихВыбранных(ТипКлюча = "Выбранные")
Возврат "Последние" + ТипКлюча;
КонецФункции
Процедура ПодменюПереключетеляНажатиеЛкс(Знач Подменю, Кнопка, Знач ИмяКнопкиПоУмолчанию = "") Экспорт
Если Кнопка = Неопределено Или Не Кнопка.Доступность Тогда
Если ЗначениеЗаполнено(ИмяКнопкиПоУмолчанию) Тогда
Кнопка = Подменю.Кнопки[ИмяКнопкиПоУмолчанию];
Иначе
Кнопка = Подменю.Кнопки[0];
КонецЕсли;
КонецЕсли;
Для Каждого КнопкаСпособа Из Подменю.Кнопки Цикл
КнопкаСпособа.Пометка = Кнопка = КнопкаСпособа;
КонецЦикла;
ирОбщий.ОбновитьТекстПослеМаркераВСтрокеЛкс(Подменю.Текст,, Кнопка.Текст, ": ");
КонецПроцедуры
Функция ИспользованиеДинамическогоСпискаВместоОсновнойФормыЛкс(ПолноеИмяМД) Экспорт
Возврат ирОбщий.ВосстановитьЗначениеЛкс("ирДинамическийСписок.ВместоОсновной." + ПолноеИмяМД) <> Ложь;
КонецФункции // УстановитьОбъектМетаданных()
Функция КлючИсторииВыбораПоляВводаЛкс(Знач ПолеВводаИлиЭлементОтбора, Знач КлючИстории, Знач ДополнительныйКлючИстории = "") Экспорт
Если ТипЗнч(КлючИстории) <> Тип("Строка") Тогда
КлючИстории = КлючХраненияНастроекФормыЛкс(КлючИстории);
КлючИстории = КлючИстории + ДополнительныйКлючИстории;
КлючИстории = КлючИстории + "." + ПолеВводаИлиЭлементОтбора.Имя;
ИначеЕсли Ложь
Или ТипЗнч(ПолеВводаИлиЭлементОтбора) = Тип("ЭлементОтбора")
Или ТипЗнч(ПолеВводаИлиЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных")
Тогда
КлючИстории = КлючИстории + ДополнительныйКлючИстории;
КлючИстории = КлючИсторииВыбораЗначенияОтбораЛкс(КлючИстории, ПолеВводаИлиЭлементОтбора);
КонецЕсли;
КлючИстории = КлючИстории + ".ПоследниеЗначения";
Возврат КлючИстории;
КонецФункции
Функция КлючИсторииВыбораЗначенияОтбораЛкс(ПолноеИмяМД, ЭлементОтбора) Экспорт
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
Результат = ПолноеИмяМД + ".Отбор." + ЭлементОтбора.Имя;
ИначеЕсли ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
Результат = ПолноеИмяМД + ".Отбор." + ЭлементОтбора.ЛевоеЗначение;
ИначеЕсли ТипЗнч(ЭлементОтбора) = Тип("Строка") Тогда
Результат = ПолноеИмяМД + ".Отбор." + ЭлементОтбора;
Иначе
ВызватьИсключение "Неверный тип элемента отбора";
КонецЕсли;
Возврат Результат;
КонецФункции
// Процедура - Поле ввода с историей выбора при изменении
//
// Параметры:
// ПолеВвода - -
// КлючИстории - Строка, Форма -
// ЗапоминатьПоследние - -
// НеЗапоминатьПустыеТипизированные - -
// ДополнительныйКлючИстории - Строка - используется только если КлючИстории не ялвяется строкой
//
Процедура ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(Знач ЭлементФормыИлиЭлементОтбора, Знач КлючИстории, Знач ЗапоминатьПоследние = 20, Знач _НеЗапоминатьПустыеТипизированные = Истина,
ДополнительныйКлючИстории = "", Знач ЗначениеПоля = Неопределено) Экспорт
Если ЗначениеПоля = Неопределено Тогда
Если ТипЗнч(ЭлементФормыИлиЭлементОтбора) = Тип("ЭлементОтбора") Тогда
ЗначениеПоля = ЭлементФормыИлиЭлементОтбора.Значение;
ИначеЕсли ТипЗнч(ЭлементФормыИлиЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
ЗначениеПоля = ЭлементФормыИлиЭлементОтбора.ПравоеЗначение;
ИначеЕсли ТипЗнч(ЭлементФормыИлиЭлементОтбора) = Тип("КолонкаТабличногоПоля") Тогда
ПолеВвода = ЭлементФормыИлиЭлементОтбора.ЭлементУправления;
ЗначениеПоля = ПолеВвода.Значение;
Иначе
ПолеВвода = ЭлементФормыИлиЭлементОтбора;
ЗначениеПоля = ДанныеЭлементаФормыЛкс(ПолеВвода);
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(ЗначениеПоля) Тогда
НовоеЗначениеXML = ОбъектВСтрокуXMLЛкс(ЗначениеПоля);
Если СтрДлина(НовоеЗначениеXML) > 1000 Тогда
Возврат;
КонецЕсли;
КлючИстории = КлючИсторииВыбораПоляВводаЛкс(ЭлементФормыИлиЭлементОтбора, КлючИстории, ДополнительныйКлючИстории);
ПоследниеЗначения = ВосстановитьЗначениеЛкс(КлючИстории);
Если ТипЗнч(ПоследниеЗначения) <> Тип("Массив") Тогда
ПоследниеЗначения = Новый Массив;
КонецЕсли;
ПоследниеЗначенияXML = Новый Массив;
Для Каждого Значение Из ПоследниеЗначения Цикл
ПоследниеЗначенияXML.Добавить(ОбъектВСтрокуXMLЛкс(Значение));
КонецЦикла;
Индекс = ПоследниеЗначенияXML.Найти(НовоеЗначениеXML);
Если Индекс <> Неопределено Тогда
ПоследниеЗначения.Удалить(Индекс);
КонецЕсли;
ПоследниеЗначения.Вставить(0, ЗначениеПоля);
Для Счетчик = ЗапоминатьПоследние По ПоследниеЗначения.ВГраница() Цикл
ПоследниеЗначения.Удалить(ЗапоминатьПоследние);
КонецЦикла;
СохранитьЗначениеЛкс(КлючИстории, ПоследниеЗначения);
Если Ложь
Или ТипЗнч(ПолеВвода) = Тип("ПолеФормы")
Или ТипЗнч(ПолеВвода) = Тип("ПолеВвода")
Тогда
// https://partners.v8.1c.ru/forum/topic/1150632
ПолеВвода.СписокВыбора.ЗагрузитьЗначения(ПоследниеЗначения);
Если Истина
И ТипЗнч(ЗначениеПоля) = Тип("СписокЗначений")
И ПолеВвода.ПолучитьДействие("ОбработкаВыбора") = Неопределено
Тогда
// Без этого обработчика выбор из списка не устанавливает значение
ирОбщий.СообщитьЛкс("В поле ввода отсутствует обработчик ОбработкаВыбора");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Процедура - Поле ввода с историей выбора начало выбора из списка лкс
//
// Параметры:
// ЭлементФормы - -
// КлючИстории - Форма, Строка -
// ДополнительныйКлючИстории - -
// ОтборВыбора - -
//
Процедура ПолеВводаСИсториейВыбора_НачалоВыбораИзСпискаЛкс(Знач ЭлементФормы, Знач КлючИстории, ДополнительныйКлючИстории = "", ОтборВыбора = Неопределено) Экспорт
Если ТипЗнч(ЭлементФормы) = Тип("КолонкаТабличногоПоля") Тогда
ПолеВвода = ЭлементФормы.ЭлементУправления;
Иначе
ПолеВвода = ЭлементФормы;
КонецЕсли;
КлючИстории = КлючИсторииВыбораПоляВводаЛкс(ЭлементФормы, КлючИстории, ДополнительныйКлючИстории);
ПоследниеЗначения = ВосстановитьЗначениеЛкс(КлючИстории);
ПолеВвода.СписокВыбора.Очистить();
Если ТипЗнч(ПоследниеЗначения) = Тип("Массив") Тогда
Если ОтборВыбора <> Неопределено Тогда
ТаблицаСсылок = Новый ТаблицаЗначений;
ТаблицаСсылок.Колонки.Добавить("Ссылка");
Для Каждого Значение Из ПоследниеЗначения Цикл
ТаблицаСсылок.Добавить().Ссылка = Значение;
КонецЦикла;
ТаблицаСсылок = ирОбщий.СузитьТипыКолонокТаблицыБезПотериДанныхЛкс(ТаблицаСсылок);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, "Ссылка");
СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, ОтборВыбора,,,, "Ссылка");
ПоследниеЗначения = ОтобратьТаблицуЗначенийКомпоновкойЛкс(ТаблицаСсылок, НастройкаКомпоновки,, Истина);
#Если Сервер И Не Сервер Тогда
ПоследниеЗначения = Новый ТаблицаЗначений;
#КонецЕсли
ПоследниеЗначения = ПоследниеЗначения.ВыгрузитьКолонку("Ссылка");
КонецЕсли;
Для Каждого Значение Из ПоследниеЗначения Цикл
ПолеВвода.СписокВыбора.Добавить(Значение, РасширенноеПредставлениеЗначенияЛкс(Значение));
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьИндексКартинкиСловаПодсказкиЛкс(ДанныеСтроки) Экспорт
Попытка
ТипЗначения = ДанныеСтроки.ТипЗначения;
Исключение
ТипЗначения = Неопределено;
КонецПопытки;
ИндексКартинки = -1;
Если ДанныеСтроки.ТипСлова = "Конструкция" Тогда
ИндексКартинки = 13;
ИначеЕсли ТипЗначения = "Имя типа" Тогда
ИндексКартинки = 12;
ИначеЕсли ДанныеСтроки.ТипСлова = "Метод" Тогда
Попытка
Пустышка = ДанныеСтроки.Успех;
ЕстьУспех = Истина;
Исключение
ЕстьУспех = Ложь;
КонецПопытки;
Если Ложь
Или (Истина
И ЕстьУспех
И (Ложь
Или ДанныеСтроки.ТаблицаСтруктурТипов = Неопределено
Или ДанныеСтроки.ТаблицаСтруктурТипов.Количество() = 0
Или ДанныеСтроки.ТаблицаСтруктурТипов[0].ИмяОбщегоТипа = ""))
Или (Истина
И Не ЕстьУспех
И ДанныеСтроки.ТипЗначения = "")
Тогда
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 0;
ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда
ИндексКартинки = 6;
//ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда
// ИндексКартинки = 9;
Иначе
ИндексКартинки = 3;
КонецЕсли;
Иначе
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 1;
ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда
ИндексКартинки = 7;
//ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда
// ИндексКартинки = 10;
Иначе
ИндексКартинки = 4;
КонецЕсли;
КонецЕсли;
ИначеЕсли ДанныеСтроки.ТипСлова = "Свойство" Тогда
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 2;
ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда
ИндексКартинки = 8;
//ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда
// ИндексКартинки = 11;
Иначе
ИндексКартинки = 5;
КонецЕсли;
ИначеЕсли ДанныеСтроки.ТипСлова = "Таблица" Тогда
ИндексКартинки = 14;
ИначеЕсли ДанныеСтроки.ТипСлова = "Поле" Тогда
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 15;
Иначе
ИндексКартинки = 16;
КонецЕсли;
ИначеЕсли ДанныеСтроки.ТипСлова = "Группа" Тогда
ИндексКартинки = 18;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции
Функция СтроковыйИдентификаторСсылкиЛкс(Ссылка, ВместеСТипом = Ложь) Экспорт
ИдентификаторСсылки = Неопределено;
XMLТип = XMLТипЗнч(Ссылка);
Если XMLТип <> Неопределено Тогда
Если Найти(XMLТип.ИмяТипа, "Ref.") > 0 Тогда
Если Найти(XMLТип.ИмяТипа, "ExternalDataSourceTableRef.") > 0 Тогда
ИдентификаторСсылки = "{" + ирОбщий.СтрокаМеждуМаркерамиЛкс(ЗначениеВСтрокуВнутр(Ссылка), "," + Символы.ПС + "{", "}" + Символы.ПС + "}") + "}";
ИдентификаторСсылки = СтрЗаменить(ИдентификаторСсылки, Символы.ПС, "");
Иначе
ИдентификаторСсылки = XMLСтрока(Ссылка);
КонецЕсли;
ИначеЕсли XMLТип.ИмяТипа = "Type" Тогда
XMLТипТипа = XMLТип(Ссылка);
Если XMLТипТипа <> Неопределено Тогда
ИдентификаторСсылки = XMLТипТипа.ИмяТипа;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ВместеСТипом И ИдентификаторСсылки <> Неопределено Тогда
ИдентификаторСсылки = ИдентификаторСсылки + "." + XMLТип.ИмяТипа;
КонецЕсли;
Возврат ИдентификаторСсылки;
КонецФункции
Функция ИменаИспользуемыхВЗапросеВременныхТаблицЛкс(Знач ЗапросИлиМенеджерВременныхТаблиц, Знач ОбязательныеДляПроверкиИмена = """") Экспорт
Платформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
Платформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
МассивИмен = СтрРазделитьЛкс(ОбязательныеДляПроверкиИмена, ",", Истина, Ложь);
Если ТипЗнч(ЗапросИлиМенеджерВременныхТаблиц) = Тип("Запрос") Тогда
#Если Сервер И Не Сервер Тогда
ЗапросИлиМенеджерВременныхТаблиц = Новый Запрос;
#КонецЕсли
ИменаИспользуемыхВременныхТаблиц = Платформа.НайтиВозможныеИменаВременныхТаблиц(ЗапросИлиМенеджерВременныхТаблиц.Текст);
Для Каждого ИмяИспользуемойВременнойТаблицы Из ИменаИспользуемыхВременныхТаблиц Цикл
МассивИмен.Добавить(ИмяИспользуемойВременнойТаблицы);
КонецЦикла;
МенеджерВременныхТаблиц = ЗапросИлиМенеджерВременныхТаблиц.МенеджерВременныхТаблиц;
Иначе
Если Не ирКэш.ДоступныТаблицыМенеджераВременныхТаблицЛкс() И Не ЗначениеЗаполнено(ОбязательныеДляПроверкиИмена) Тогда
ВызватьИсключение "Необходимо указать имена временных таблиц";
КонецЕсли;
МенеджерВременныхТаблиц = ЗапросИлиМенеджерВременныхТаблиц;
КонецЕсли;
Если Истина
И ирКэш.ДоступныТаблицыМенеджераВременныхТаблицЛкс()
И МенеджерВременныхТаблиц <> Неопределено
Тогда
#Если Сервер И Не Сервер Тогда
МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
#КонецЕсли
Для Каждого ТаблицаМенеджера Из МенеджерВременныхТаблиц.Таблицы Цикл
МассивИмен.Добавить(ТаблицаМенеджера.ПолноеИмя);
КонецЦикла;
КонецЕсли;
Возврат МассивИмен;
КонецФункции
Процедура СкопироватьДеревоЛкс(ИсходноеДерево, НовоеДерево, ОчиститьПередЗагрузкой = Истина, ЗначенияПоУмолчанию = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ЗначенияПоУмолчанию = Новый Структура;
#КонецЕсли
Если ОчиститьПередЗагрузкой Тогда
НовоеДерево.Строки.Очистить();
КонецЕсли;
Если ИсходноеДерево.Строки.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Если ЗначенияПоУмолчанию <> Неопределено Тогда
ИменаСвойствПоУмолчанию = ИменаСвойствСтруктурыЛкс(ЗначенияПоУмолчанию);
КонецЕсли;
Для каждого СтрокаДерева из ИсходноеДерево.Строки Цикл
НоваяСтрока = НовоеДерево.Строки.Добавить();
Если ЗначенияПоУмолчанию <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(НоваяСтрока, ЗначенияПоУмолчанию, ИменаСвойствПоУмолчанию);
КонецЕсли;
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаДерева);
СкопироватьДеревоЛкс(СтрокаДерева, НоваяСтрока, ОчиститьПередЗагрузкой = Истина);
КонецЦикла;
КонецПроцедуры
Функция СоздатьСамоудаляющийсяКомандныйФайлЛкс(Знач ТекстКомандногоФайла = "", Знач КраткоеИмяФайла = "") Экспорт
Если ЗначениеЗаполнено(КраткоеИмяФайла) Тогда
ПолноеИмяФайла = КаталогВременныхФайлов() + КраткоеИмяФайла + ".bat";
Иначе
ПолноеИмяФайла = ПолучитьИмяВременногоФайла("bat");
КонецЕсли;
Если ирОбщий.СтрНачинаетсяСЛкс(ТекущийЯзыкСистемы(), "ru") Тогда
ТекстКомандногоФайла = "Chcp 866" + Символы.ПС + ТекстКомандногоФайла;
КонецЕсли;
ТекстКомандногоФайла = ТекстКомандногоФайла + "
|del """ + ПолноеИмяФайла + """
|";
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ТекстКомандногоФайла);
ТекстовыйДокумент.Записать(ПолноеИмяФайла, КодировкаТекста.OEM);
Результат = ПолноеИмяФайла;
Возврат Результат;
КонецФункции
// Проверить уникальность строк ТЧ по колонке
//
// Параметры:
// Объект - <тип> -
// ИмяТаблицы - <тип> -
// ИмяКолонки - <тип>, "" -
//
// Возвращаемое значение:
//
Функция ПроверитьУникальностьСтрокТЧПоКолонкеЛкс(Объект, ИмяТаблицы, ИмяКолонки = "", ИгнорироватьРегистрДляПростогоСтрокогоТипа = Истина, ОтборСтрок = Неопределено,
МассивИсключений = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ИмяКолонки = Объект.Метаданные().ТабличныеЧасти[ИмяТаблицы].Реквизиты[0].Имя;
КонецЕсли;
Если Истина
И МассивИсключений <> Неопределено
И ИгнорироватьРегистрДляПростогоСтрокогоТипа
Тогда
НовыйМассивИсключений = Новый Массив;
Для Каждого ИсключаемоеЗначение Из МассивИсключений Цикл
Если ТипЗнч(ИсключаемоеЗначение) = Тип("Строка") Тогда
ИсключаемоеЗначение = НРег(ИсключаемоеЗначение);
КонецЕсли;
НовыйМассивИсключений.Добавить(ИсключаемоеЗначение);
КонецЦикла;
МассивИсключений = НовыйМассивИсключений;
КонецЕсли;
Успех = Истина;
НеуникальныеЗначения = НеуникальныеЗначенияКолонкиТаблицыЛкс(Объект[ИмяТаблицы], ИмяКолонки, ИгнорироватьРегистрДляПростогоСтрокогоТипа, ОтборСтрок);
Для Каждого НеуникальноеЗначение Из НеуникальныеЗначения Цикл
Если Истина
И МассивИсключений <> Неопределено
И МассивИсключений.Найти(НеуникальноеЗначение) <> Неопределено
Тогда
Продолжить;
КонецЕсли;
СообщитьЛкс(СтрШаблонИменЛкс("Значение %1 встречается более одного раза среди активных строк в колонке %2 таблицы %3",
1, НеуникальноеЗначение, 2, ИмяКолонки, 3, ИмяТаблицы), СтатусСообщения.Внимание);
Успех = Ложь;
КонецЦикла;
Возврат Успех;
КонецФункции
Функция ПолучитьПроцессОСЛкс(Знач ИдентификаторПроцесса = Неопределено, Знач НачалоПроцесса = Неопределено, Знач Компьютер = Неопределено,
ВызватьИсключениеПриОшибкеПодключенияWMI = Истина, ДопустимоеОтклонениеВремени = 2, МаркерВКоманднойСтроке = Неопределено, ИмяИсполняемогоФайла = Неопределено) Экспорт
Если СтрокиРавныЛкс(ИдентификаторПроцесса, "текущий") Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ИдентификаторПроцесса = мПлатформа.ИдентификаторПроцессаОС();
КонецЕсли;
Попытка
WMIЛокатор = ирКэш.ПолучитьCOMОбъектWMIЛкс(Компьютер);
Исключение
Если ВызватьИсключениеПриОшибкеПодключенияWMI Тогда
ВызватьИсключение;
КонецЕсли;
ОписаниеОшибки = ОписаниеОшибки();
СообщитьЛкс(ОписаниеОшибки, СтатусСообщения.Внимание);
WMIЛокатор = Неопределено;
КонецПопытки;
Если WMIЛокатор = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
// ТекстОтбора = "1=1 AND"; Синтаксис WQL такого не допускает
ТекстОтбора = "";
Если ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда
Если ТекстОтбора <> "" Тогда
ТекстОтбора = ТекстОтбора + "AND ";
КонецЕсли;
ТекстОтбора = ТекстОтбора + " ProcessID = " + XMLСтрока(ИдентификаторПроцесса);
КонецЕсли;
Если ЗначениеЗаполнено(МаркерВКоманднойСтроке) Тогда
Если ТекстОтбора <> "" Тогда
ТекстОтбора = ТекстОтбора + "AND ";
КонецЕсли;
ТекстОтбора = ТекстОтбора + " CommandLine LIKE '%" + МаркерВКоманднойСтроке + "%'";
КонецЕсли;
Если ЗначениеЗаполнено(ИмяИсполняемогоФайла) Тогда
Если ТекстОтбора <> "" Тогда
ТекстОтбора = ТекстОтбора + "AND ";
КонецЕсли;
ТекстОтбора = ТекстОтбора + " Name = '" + ИмяИсполняемогоФайла + "'";
КонецЕсли;
Если НачалоПроцесса <> Неопределено Тогда
Если ТекстОтбора <> "" Тогда
ТекстОтбора = ТекстОтбора + "AND ";
КонецЕсли;
ТекстОтбора = ТекстОтбора + " CreationDate >= " + ПолучитьЛитералДатыДляWQLЛкс(НачалоПроцесса - ДопустимоеОтклонениеВремени);
ТекстОтбора = ТекстОтбора + " AND CreationDate <= " + ПолучитьЛитералДатыДляWQLЛкс(НачалоПроцесса + 1 + ДопустимоеОтклонениеВремени);
КонецЕсли;
Результат = "Процесс ОС с отбором (" + ТекстОтбора + ") не найден";
ТекстЗапросаWQL = "Select * from Win32_Process Where " + ТекстОтбора;
ВыборкаПроцессовОС = WMIЛокатор.ExecQuery(ТекстЗапросаWQL);
Для Каждого ПроцессОС Из ВыборкаПроцессовОС Цикл
Результат = ПроцессОС;
Прервать;
КонецЦикла;
Возврат Результат;
КонецФункции
// Функция - Ли процесс ОСКонфигуратора лкс
//
// Параметры:
// ПроцессОС - WMI:Win32_Process -
//
// Возвращаемое значение:
// -
//
Функция ЛиПроцессОСКонфигуратораЛкс(Знач ПроцессОС) Экспорт
Результат = Ложь
Или Найти(НРег(ПроцессОС.CommandLine), "config") > 0
Или Найти(НРег(ПроцессОС.CommandLine), "designer") > 0;
Возврат Результат;
КонецФункции
Функция ПолучитьЛитералДатыДляWQLЛкс(Знач Результат) Экспорт
Результат = Результат - СмещениеСтандартногоВремени();
Результат = "'" + Формат(Результат, "ДФ='yyyyMMdd HH:mm:ss'; ДП=") + "'";
Возврат Результат
КонецФункции
Функция ПолучитьФайлWMIЛкс(ПолноеИмяФайла, КомпьютерИлиИмя = Неопределено) Экспорт
СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс(КомпьютерИлиИмя);
ФайлыWMI = СлужбаWMI.ExecQuery("Select * from CIM_Datafile where name='" + ЗаменитьСлешиНаДвойныеЛкс(ПолноеИмяФайла) + "'");
Для каждого ФайлWMI Из ФайлыWMI цикл
КонецЦикла;
Возврат ФайлWMI;
КонецФункции
Процедура ЗаполнитьДоступныеСборкиПлатформыЛкс(СборкиПлатформы, Компьютер = "", ТипыComКлассов = Неопределено, ТабличноеПоле = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
СборкиПлатформы = Обработки.ирУправлениеСлужбамиСервера1С.Создать().СборкиПлатформы;
#КонецЕсли
Если ТабличноеПоле <> Неопределено Тогда
СостояниеСтрокТП = ирОбщий.ТабличноеПолеСостояниеСтрокЛкс(ТабличноеПоле, "Каталог");
КонецЕсли;
СборкиПлатформы.Очистить();
// Оба варианта пришлось оставить, т.к. WMI вариант очень долгий
Если ирОбщий.ЭтоИмяЛокальногоКомпьютераЛкс(Компьютер) Тогда
Инсталлер = Новый COMОбъект("WindowsInstaller.Installer");
Продукты = Инсталлер.Products;
Иначе
СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс(Компьютер);
Если СлужбаWMI = Неопределено Тогда
Возврат;
КонецЕсли;
Продукты = СлужбаWMI.ExecQuery("SELECT * FROM Win32_Product WHERE Vendor LIKE '1C' OR Vendor LIKE '1С'");
КонецЕсли;
Для Каждого Продукт Из Продукты Цикл
Если ЭтоИмяЛокальногоКомпьютераЛкс(Компьютер) Тогда
Попытка
ПубликаторПродукта = Инсталлер.ProductInfo(Продукт, "Publisher");
Исключение
Продолжить;
КонецПопытки;
Если Истина
И ПубликаторПродукта <> "1C" // латинские буквы
И ПубликаторПродукта <> "1С" // русские буквы
И ПубликаторПродукта <> "1C-Soft" // латинские буквы
И ПубликаторПродукта <> "1С-Софт" // русские буквы
И ПубликаторПродукта <> "NetHelp" // Польша
Тогда
Продолжить;
КонецЕсли;
//НаименованиеПродукта = Инсталлер.ProductInfo(Продукт, "ProductName");
КаталогВерсии = Инсталлер.ProductInfo(Продукт, "InstallLocation");
//СтрокаРелиза = Инсталлер.ProductInfo(Продукт, "VersionString");
Иначе
КаталогВерсии = Продукт.InstallLocation;
КонецЕсли;
СтрокаТаблицыСборок = СборкиПлатформы.Добавить();
СтрокаТаблицыСборок.Каталог = КаталогВерсии;
ФайлПолученияВерсии = Неопределено;
Если ТипыComКлассов <> Неопределено Тогда
Для Каждого ТипКласса Из ТипыComКлассов Цикл
//Если Метаданные().ТабличныеЧасти.СборкиПлатформы.Реквизиты.Найти(ВыборкаКлассов.Имя) = Неопределено Тогда
// Продолжить;
//КонецЕсли;
ФайлКомпоненты = Новый Файл(СтрокаТаблицыСборок.Каталог + "bin\" + ТипКласса.КлючевойФайл); // Быстро
СтрокаТаблицыСборок[ТипКласса.Имя] = ФайлКомпоненты.Существует();
Если ФайлПолученияВерсии = Неопределено И СтрокаТаблицыСборок[ТипКласса.Имя] Тогда
ФайлПолученияВерсии = ФайлКомпоненты;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ИсполняемыйФайл = Новый Файл(СтрокаТаблицыСборок.Каталог + "bin\" + ИмяИсполняемогоФайлаЛкс("ragent")); // Быстро
СтрокаТаблицыСборок.АгентСервера = ИсполняемыйФайл.Существует();
Если ФайлПолученияВерсии = Неопределено И СтрокаТаблицыСборок.АгентСервера Тогда
ФайлПолученияВерсии = ИсполняемыйФайл;
КонецЕсли;
ИсполняемыйФайл = Новый Файл(СтрокаТаблицыСборок.Каталог + "bin\" + ИмяИсполняемогоФайлаЛкс("ras")); // Быстро
СтрокаТаблицыСборок.СерверАдминистрирования = ИсполняемыйФайл.Существует();
Если ФайлПолученияВерсии = Неопределено И СтрокаТаблицыСборок.СерверАдминистрирования Тогда
ФайлПолученияВерсии = ИсполняемыйФайл;
КонецЕсли;
ИсполняемыйФайл = Новый Файл(СтрокаТаблицыСборок.Каталог + "bin\" + ИмяИсполняемогоФайлаЛкс("dbgs")); // Быстро
СтрокаТаблицыСборок.СерверОтладки = ИсполняемыйФайл.Существует();
Если ФайлПолученияВерсии = Неопределено И СтрокаТаблицыСборок.СерверОтладки Тогда
ФайлПолученияВерсии = ИсполняемыйФайл;
КонецЕсли;
ИсполняемыйФайл = Новый Файл(СтрокаТаблицыСборок.Каталог + "bin\" + ИмяИсполняемогоФайлаЛкс("crserver")); // Быстро
СтрокаТаблицыСборок.СерверХранилища = ИсполняемыйФайл.Существует();
Если ФайлПолученияВерсии = Неопределено И СтрокаТаблицыСборок.СерверХранилища Тогда
ФайлПолученияВерсии = ИсполняемыйФайл;
КонецЕсли;
Если ФайлПолученияВерсии <> Неопределено Тогда
ФайлПолученияВерсии = ПолучитьФайлWMIЛкс(ФайлПолученияВерсии.ПолноеИмя, Компьютер);
СтрокаТаблицыСборок.ФайлыСуществуют = Истина;
СтрокаТаблицыСборок.x64 = ирКэш.Это64битнаяОСЛкс() И Найти(СтрокаТаблицыСборок.Каталог, "(x86)") = 0;
СтрокаТаблицыСборок.СборкаПлатформы = ФайлПолученияВерсии.Version;
СтрокаТаблицыСборок.КлючСборки = КлючСборкиПлатформыЛкс(СтрокаТаблицыСборок);
СтрокаВерсии = ФайлПолученияВерсии.Version;
Если ЗначениеЗаполнено(СтрокаВерсии) Тогда
СтрокаТаблицыСборок.СборкаПлатформы = СтрокаВерсии;
Фрагменты = СтрРазделитьЛкс(СтрокаВерсии);
ИзданиеПлатформы = Фрагменты[0] + "." + Фрагменты[1];
СтрокаТаблицыСборок.ИзданиеПлатформы = ИзданиеПлатформы;
СтрокаТаблицыСборок.Порядок = Фрагменты[0] * 10000000 + Фрагменты[1] * 1000000 + Фрагменты[2] * 10000 + Фрагменты[3];
КонецЕсли;
КонецЕсли;
СтрокаТаблицыСборок.НКаталог = НРег(СтрокаТаблицыСборок.Каталог);
КонецЦикла;
СборкиПлатформы.Сортировать("Порядок Убыв, ФайлыСуществуют Убыв, СборкаПлатформы Убыв, x64");
Если ТабличноеПоле <> Неопределено Тогда
ирОбщий.ТабличноеПолеВосстановитьСостояниеСтрокЛкс(ТабличноеПоле, СостояниеСтрокТП);
КонецЕсли;
КонецПроцедуры
Функция КлючСборкиПлатформыЛкс(Знач СтрокаТаблицыСборок) Экспорт
Возврат СтрокаТаблицыСборок.СборкаПлатформы + " - " + ?(СтрокаТаблицыСборок.x64, "64", "32");
КонецФункции
Функция ЗаменитьСлешиНаДвойныеЛкс(Строка) Экспорт
Результат = СтрЗаменить(Строка, "\", "\\");
Возврат Результат;
КонецФункции
// Функция - Выполнить команду ОСЛкс
//
// Параметры:
// СтрокаКоманды - Строка, Массив -
// ОжидатьЗавершения - Булево -
// ИмяКомпьютера - -
// Элевация - -
// Состояние - -
//
// Возвращаемое значение:
// Строка - текст вывода в синхронном режиме и полное имя файла в асинхронном режиме
//
Функция ВыполнитьКомандуОСЛкс(Знач СтрокаКоманды = "", ОжидатьЗавершения = Истина, Знач _ИмяКомпьютера = "", Элевация = Ложь, Состояние = "") Экспорт
ФайлРезультата = Новый Файл(ПолучитьИмяВременногоФайла("txt"));
Если ЗначениеЗаполнено(Состояние) Тогда
ирОбщий.СостояниеЛкс(Состояние);
КонецЕсли;
Если ТипЗнч(СтрокаКоманды) = Тип("Массив") Тогда
СтрокаКоманды = МассивВСтрокуКомандыЛкс(СтрокаКоманды);
КонецЕсли;
ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(СтрокаКоманды, ФайлРезультата.Путь,, ФайлРезультата.Имя, ОжидатьЗавершения, Элевация);
Если ОжидатьЗавершения Тогда
Если ФайлРезультата.Существует() Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ФайлРезультата.ПолноеИмя, СистемнаяКодировкаТекстаОСЛкс());
УдалитьФайлы(ФайлРезультата.ПолноеИмя);
Результат = СокрЛП(ТекстовыйДокумент.ПолучитьТекст());
Иначе
Результат = Неопределено;
КонецЕсли;
Иначе
Результат = ФайлРезультата.ПолноеИмя;
КонецЕсли;
Если ЗначениеЗаполнено(Состояние) Тогда
ирОбщий.СостояниеЛкс("");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СистемнаяКодировкаТекстаОСЛкс() Экспорт
Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда
Кодировка = КодировкаТекста.OEM;
Иначе
Кодировка = КодировкаТекста.Системная;
КонецЕсли;
Возврат Кодировка;
КонецФункции
// <Описание процедуры>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// ИмяФайлаРезультата - Краткое имя файла, в который будет выведен выходной поток, только в текущем каталоге.
// Элевация - Булево - используется только если текущая учетная запись Windows входит в группу Администраторы
//
Процедура ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(Знач СтрокаКоманды, Знач ТекущийКаталог = "", Знач _ИспользоватьWSH = Истина,
КраткоеИмяФайлаРезультата = "", ОжидатьЗавершения = Истина, Элевация = Ложь, СообщитьКоманду = Ложь) Экспорт
Если Не ЗначениеЗаполнено(ТекущийКаталог) Тогда
ТекущийКаталог = КаталогВременныхФайлов();
КонецЕсли;
Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда
СтрокаКоманды =
"cd """ + ТекущийКаталог + """
|cmd.exe /c """ + СтрокаКоманды + """";
Иначе
СтрокаКоманды =
"bash -c '" + СтрокаКоманды + "'";
КонецЕсли;
Если КраткоеИмяФайлаРезультата <> "" Тогда
СтрокаКоманды = СтрокаКоманды + " > """ + ТекущийКаталог + КраткоеИмяФайлаРезультата + """";
СтрокаКоманды = СтрокаКоманды + " 2>&1"; //stderr
КонецЕсли;
Если СообщитьКоманду Тогда
СообщитьЛкс(СтрокаКоманды);
КонецЕсли;
Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда
ИмяКомандногоФайла = ирОбщий.СоздатьСамоудаляющийсяКомандныйФайлЛкс(СтрокаКоманды);
ВК = ирОбщий.ВКОбщаяЛкс();
ВК.Run(ИмяКомандногоФайла, "", ТекущийКаталог, ОжидатьЗавершения, Элевация);
Иначе
КодВозврата = Неопределено;
ЗапуститьПриложение(СтрокаКоманды, ТекущийКаталог, ОжидатьЗавершения, КодВозврата);
КонецЕсли;
КонецПроцедуры
Функция ЛиДоступноВыполнениеКомандныхФайловЛкс(Знач ВыброситьИсключение = Ложь) Экспорт
Если Не ирКэш.ЛиПлатформаWindowsЛкс() Тогда
Возврат Истина;
КонецЕсли;
Файл = ПолучитьИмяВременногоФайла("bat");
Маркер = Новый УникальныйИдентификатор;
Текст = Новый ТекстовыйДокумент;
Текст.УстановитьТекст("echo " + Маркер);
Текст.Записать(Файл, КодировкаТекста.ANSI);
Результат = ирОбщий.ВыполнитьКомандуОСЛкс(Файл);
Результат = Найти(Результат, Маркер) > 0;
Если Не Результат И ВыброситьИсключение Тогда
ВызватьИсключение "Пользователю ОС недоступно выполнение командных файлов (bat)";
КонецЕсли;
Возврат Результат;
КонецФункции
Функция МассивВСтрокуКомандыЛкс(КомандаЗапуска) Экспорт
Результат = Новый Массив;
НужныКавычки = Ложь;
Для Каждого Аргумент Из КомандаЗапуска Цикл
Если Результат.Количество() > 0 Тогда
Результат.Добавить(" ")
КонецЕсли;
НужныКавычки = Ложь
Или Аргумент = Неопределено
Или ПустаяСтрока(Аргумент)
Или Найти(Аргумент, " ")
Или Найти(Аргумент, Символы.Таб)
Или Найти(Аргумент, "&")
Или Найти(Аргумент, "(")
Или Найти(Аргумент, ")")
Или Найти(Аргумент, "[")
Или Найти(Аргумент, "]")
Или Найти(Аргумент, "{")
Или Найти(Аргумент, "}")
Или Найти(Аргумент, "^")
Или Найти(Аргумент, "=")
Или Найти(Аргумент, ";")
Или Найти(Аргумент, "!")
Или Найти(Аргумент, "'")
Или Найти(Аргумент, "+")
Или Найти(Аргумент, ",")
Или Найти(Аргумент, "`")
Или Найти(Аргумент, "~")
Или Найти(Аргумент, "$")
Или Найти(Аргумент, "|");
Если НужныКавычки Тогда
Результат.Добавить("""");
КонецЕсли;
Результат.Добавить(СтрЗаменить(Аргумент, """", """"""));
Если НужныКавычки Тогда
Результат.Добавить("""");
КонецЕсли;
КонецЦикла;
Возврат СтрСоединитьЛкс(Результат, "");
КонецФункции
Функция КомандаСистемыЗапускаСкриптаPowerShellЛкс(Знач ИмяФайлаСкриптаСПараметрами) Экспорт
КомандаСистемыЗапускаСкрипта = "powershell.exe -executionpolicy unrestricted -file " + ИмяФайлаСкриптаСПараметрами;
Возврат КомандаСистемыЗапускаСкрипта;
КонецФункции
Функция ЗапретитьУправляемуюБлокировку(Знач НичегоДелатьБезТранзакции = Ложь) Экспорт
Возврат Ложь
Или Метаданные.РежимУправленияБлокировкойДанных = Метаданные.СвойстваОбъектов.РежимУправленияБлокировкойДанныхПоУмолчанию.Автоматический
Или Метаданные.РежимУправленияБлокировкойДанных = Метаданные.СвойстваОбъектов.РежимУправленияБлокировкойДанныхПоУмолчанию.АвтоматическийИУправляемый
Или (Истина
И НичегоДелатьБезТранзакции
И Не ТранзакцияАктивна());
КонецФункции
Процедура ЗаблокироватьНаборЗаписейПоОтборуЛкс(НаборЗаписей, НичегоДелатьБезТранзакции = Ложь, НовыйРежимБлокировкиДанных = Неопределено) Экспорт
Если ЗапретитьУправляемуюБлокировку(НичегоДелатьБезТранзакции) Тогда
Возврат;
КонецЕсли;
Блокировка = Новый БлокировкаДанных;
ОбъектМД = Метаданные.НайтиПоТипу(ирОбщий.ТипОбъектаБДЛкс(НаборЗаписей));
ПространствоБлокировок = ОбъектМД.ПолноеИмя();
КорневойТип = ПервыйФрагментЛкс(ПространствоБлокировок);
Если ирОбщий.ТипТаблицыБДЛкс(ПространствоБлокировок) = "Перерасчет" Тогда
Возврат;
//ПространствоБлокировок = ОбъектМД.Родитель().ПолноеИмя();
КонецЕсли;
Если Ложь
Или Не ЛиКорневойТипРегистраСведенийЛкс(КорневойТип)
Или ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору
Тогда
ПространствоБлокировок = ПространствоБлокировок + ".НаборЗаписей";
КонецЕсли;
ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок);
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
Если ЭлементОтбора.Использование Тогда
ЭлементБлокировки.УстановитьЗначение(ЭлементОтбора.Имя, ЭлементОтбора.Значение);
КонецЕсли;
КонецЦикла;
Если НовыйРежимБлокировкиДанных = Неопределено Тогда
НовыйРежимБлокировкиДанных = РежимБлокировкиДанных.Исключительный;
КонецЕсли;
ЭлементБлокировки.Режим = НовыйРежимБлокировкиДанных;
Блокировка.Заблокировать();
КонецПроцедуры
Процедура ЗаблокироватьРегистрПоМенеджеруЗаписиЛкс(МенеджерЗаписи, НичегоДелатьБезТранзакции = Ложь, Знач РежимБлокировки = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
МенеджерЗаписи = РегистрыСведений.КурсыВалют.СоздатьМенеджерЗаписи();
#КонецЕсли
Если ЗапретитьУправляемуюБлокировку(НичегоДелатьБезТранзакции) Тогда
Возврат;
КонецЕсли;
Блокировка = Новый БлокировкаДанных;
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(МенеджерЗаписи));
ПространствоБлокировок = ОбъектМД.ПолноеИмя();
КорневойТип = ПервыйФрагментЛкс(ПространствоБлокировок);
Если ирОбщий.ТипТаблицыБДЛкс(ПространствоБлокировок) = "Перерасчет" Тогда
Возврат;
//ПространствоБлокировок = ОбъектМД.Родитель().ПолноеИмя();
КонецЕсли;
Если ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда
ПространствоБлокировок = ПространствоБлокировок + ".НаборЗаписей";
КонецЕсли;
НаборЗаписей = Новый (ИмяТипаИзПолногоИмениМДЛкс(ОбъектМД, "НаборЗаписей"));
ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок);
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
ЭлементБлокировки.УстановитьЗначение(ЭлементОтбора.Имя, МенеджерЗаписи[ЭлементОтбора.Имя]);
КонецЦикла;
Если РежимБлокировки <> Неопределено Тогда
ЭлементБлокировки.Режим = РежимБлокировки;
КонецЕсли;
Блокировка.Заблокировать();
КонецПроцедуры
Процедура ЗаблокироватьСсылкуВТранзакцииЛкс(СсылочныйОбъект, НичегоДелатьБезТранзакции = Ложь) Экспорт
Если ЗапретитьУправляемуюБлокировку(НичегоДелатьБезТранзакции) Тогда
Возврат;
КонецЕсли;
Блокировка = Новый БлокировкаДанных;
ОбъектМД = СсылочныйОбъект.Метаданные();
ПространствоБлокировок = ОбъектМД.ПолноеИмя();
ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок);
ЭлементБлокировки.УстановитьЗначение("Ссылка", СсылочныйОбъект.Ссылка);
Блокировка.Заблокировать();
КонецПроцедуры
Процедура ЗаблокироватьКонстантуЛкс(КонстантаМенеджерЗначения, НичегоДелатьБезТранзакции = Ложь, Знач РежимБлокировки = Неопределено) Экспорт
Если ЗапретитьУправляемуюБлокировку(НичегоДелатьБезТранзакции) Тогда
Возврат;
КонецЕсли;
Блокировка = Новый БлокировкаДанных;
ОбъектМД = Метаданные.НайтиПоТипу(ирОбщий.ТипОбъектаБДЛкс(КонстантаМенеджерЗначения));
ПространствоБлокировок = ОбъектМД.ПолноеИмя();
ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок);
Если РежимБлокировки <> Неопределено Тогда
ЭлементБлокировки.Режим = РежимБлокировки;
КонецЕсли;
Блокировка.Заблокировать();
КонецПроцедуры
Функция ПредставлениеПоляБДЛкс(СтрокаПоля, ЛиИменаБД = Ложь, _ЭтоТабличнаяЧасть = Ложь, ИспользоватьИмяПоляВместоПустогоПредставления = Ложь) Экспорт
ПредставлениеПоля = СтрокаПоля.ИмяПоля;
Если ПустаяСтрока(ПредставлениеПоля) Тогда
Если ЛиИменаБД Тогда
Если ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_Period") Тогда
ПредставлениеПоля = "Период";
ИначеЕсли Найти(СтрокаПоля.ИмяПоляХранения, "IDRRef") > 0 Тогда
// Антибаг платформы. У некоторых полей почему то пустое имя, а должно быть непустое. https://partners.v8.1c.ru/forum/topic/1275356#m_1275356
ПредставлениеПоля = "Ссылка";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_KeyField") Тогда
ПредставлениеПоля = "КлючСтроки";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_SliceUsing") Тогда
ПредставлениеПоля = "ВключенСрезПоследних";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_Version") Тогда
ПредставлениеПоля = "Версия";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_MessageNo") Тогда
ПредставлениеПоля = "НомерСообщения";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_RecordKey") Тогда
ПредставлениеПоля = "КлючСтроки";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_ConstID") Тогда
ПредставлениеПоля = "КлючКонстанты";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_NumberPrefix") Тогда
ПредставлениеПоля = "ПрефиксНомера";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_NodeTRef") Тогда
ПредставлениеПоля = "Узел_ТипСсылки";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_NodeRRef") Тогда
ПредставлениеПоля = "Узел";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_ObjectKey") Тогда
ПредставлениеПоля = "КлючОбъекта";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_UserId") Тогда
ПредставлениеПоля = "КлючПользователя";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_SettingsKey") Тогда
ПредставлениеПоля = "КлючНастроек";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_SettingsData") Тогда
ПредставлениеПоля = "Настройки";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_SettingsPresentation") Тогда
ПредставлениеПоля = "ОписаниеНастроек";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_PredefinedID") Тогда
ПредставлениеПоля = "ИмяПредопределенныхДанных";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_RecorderTRef") Тогда
ПредставлениеПоля = "Регистратор_ТипСсылки";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_RecorderRRef") Тогда
ПредставлениеПоля = "Регистратор";
ИначеЕсли ЗначениеЗаполнено(СтрокаПоля.Метаданные) Тогда
ПредставлениеПоля = ПоследнийФрагментЛкс(СтрокаПоля.Метаданные);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(ПредставлениеПоля) Тогда
Если ЛиИменаБД Тогда
НИмяПоляХранения = НРег(СтрокаПоля.ИмяПоляХранения);
НМаркерПоляТипаЗначения = НРег("TYPE");
НМаркерПоляТипаСсылки = НРег("TRef");
//МаркерПоляЗначенияСсылки = НРег("RRef");
Если Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляТипаСсылки)) = НМаркерПоляТипаСсылки Тогда
ПредставлениеПоля = ПредставлениеПоля + "_ТипСсылки";
ИначеЕсли Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляТипаЗначения)) = НМаркерПоляТипаЗначения Тогда
ПредставлениеПоля = ПредставлениеПоля + "_ТипЗначения";
//ИначеЕсли Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляЗначенияСсылки)) = НМаркерПоляЗначенияСсылки Тогда
// ПредставлениеПоля = ПредставлениеПоля + "_Ссылка";
КонецЕсли;
КонецЕсли;
ИначеЕсли ИспользоватьИмяПоляВместоПустогоПредставления Тогда
ПредставлениеПоля = СтрокаПоля.ИмяПоляХранения;
КонецЕсли;
Возврат ПредставлениеПоля;
КонецФункции
Функция ПредставлениеСтруктурыЛкс(Структура) Экспорт
#Если Сервер И Не Сервер Тогда
Структура = Новый Структура;
#КонецЕсли
ПредставлениеСтруктуры = "";
Для Каждого КлючИЗначение Из Структура Цикл
Если ПредставлениеСтруктуры <> "" Тогда
ПредставлениеСтруктуры = ПредставлениеСтруктуры + ", ";
КонецЕсли;
ПредставлениеСтруктуры = ПредставлениеСтруктуры + КлючИЗначение.Ключ + " = " + КлючИЗначение.Значение;
КонецЦикла;
Возврат ПредставлениеСтруктуры;
КонецФункции
Функция ПредставлениеИндексаХраненияЛкс(СтрокаИндексаСтруктурыБД, ЛиСтруктураДанныхВИменахБД = Ложь, СтрокаТаблицыХранения, ЛиПредставлениеВИменахБД = Ложь) Экспорт
ЭтоТабличнаяЧасть = СтрокаТаблицыХранения.Назначение = "ТабличнаяЧасть";
ПредставлениеИндекса = "";
Разделитель = "";
Если ирКэш.РежимОтладкиЛкс() Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для каждого СтрокаПоля Из СтрокаИндексаСтруктурыБД.Поля Цикл
Если ЛиПредставлениеВИменахБД Тогда
ПредставлениеПоля = СтрокаПоля.ИмяПоляХранения;
Иначе
ПредставлениеПоля = ПредставлениеПоляБДЛкс(СтрокаПоля, ЛиСтруктураДанныхВИменахБД, ЭтоТабличнаяЧасть, Истина);
КонецЕсли;
ПредставлениеИндекса = ПредставлениеИндекса + Разделитель + ПредставлениеПоля;
Разделитель = ", ";
КонецЦикла;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для каждого СтрокаПоля Из СтрокаИндексаСтруктурыБД.Поля Цикл Если ЛиПредставлениеВИменахБД Тогда ПредставлениеПоля = СтрокаПоля.ИмяПоляХранения; Иначе ПредставлениеПоля = ПредставлениеПоляБДЛкс(СтрокаПоля, ЛиСтруктураДанныхВИменахБД, ЭтоТабличнаяЧасть, Истина); КонецЕсли; ПредставлениеИндекса = ПредставлениеИндекса + Разделитель + ПредставлениеПоля; Разделитель = ", "; КонецЦикла;
КонецЕсли;
Возврат ПредставлениеИндекса;
КонецФункции
Процедура ОбработатьВыборкуСтруктурыХраненияБДЛкс(Знач Результат, ЛиИменаБД = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
Результат = Новый ТаблицаЗначений;
#КонецЕсли
Если Результат.Колонки.Найти("КраткоеИмяТаблицыХранения") <> Неопределено Тогда
// Например это схема чужой БД
//Возврат;
Иначе
//Результат.Колонки.ИмяТаблицыХранения.Имя = "ИмяТаблицыХраненияСРегистромБукв";
Результат.Колонки.Добавить("КраткоеИмяТаблицыХранения", Новый ОписаниеТипов("Строка"));
//Результат.Колонки.Добавить("ИмяТаблицыХранения", Новый ОписаниеТипов("Строка"));
КонецЕсли;
ПеревестиКолонкиСтруктурыХраненияБДТаблицыЛкс(Результат);
Для Каждого СтрокаТаблицыХранения Из Результат Цикл
// Антибаг платформы 8.2.16 У ряда назначений таблиц ИмяТаблицы пустое http://partners.v8.1c.ru/forum/thread.jsp?id=1090307#1090307
Если ПустаяСтрока(СтрокаТаблицыХранения.ИмяТаблицы) Тогда
МетаПолноеИмяТаблицы = "";
Если ЗначениеЗаполнено(СтрокаТаблицыХранения.Метаданные) Тогда
МетаПолноеИмяТаблицы = СтрокаТаблицыХранения.Метаданные;
КонецЕсли;
Если СтрокаТаблицыХранения.Назначение = "РегистрацияИзменений" Тогда
СтрокаТаблицыХранения.ИмяТаблицы = МетаПолноеИмяТаблицы + ".Изменения";
ИначеЕсли СтрокаТаблицыХранения.Назначение = "Основная" Тогда
СтрокаТаблицыХранения.ИмяТаблицы = МетаПолноеИмяТаблицы;
Иначе
Если ЗначениеЗаполнено(МетаПолноеИмяТаблицы) Тогда
МетаПолноеИмяТаблицы = МетаПолноеИмяТаблицы + "." + СтрокаТаблицыХранения.Назначение;
Иначе
МетаПолноеИмяТаблицы = СтрокаТаблицыХранения.Назначение;
КонецЕсли;
СтрокаТаблицыХранения.ИмяТаблицы = МетаПолноеИмяТаблицы;
КонецЕсли;
КонецЕсли;
//СтрокаТаблицыХранения.ИмяТаблицыХранения = НРег(ПоследнийФрагментЛкс(СтрокаТаблицыХранения.ИмяТаблицыХраненияСРегистромБукв));
// В режим ЛиИменаБД=Ложь Document209.VT2672->VT2672
Если Не ЗначениеЗаполнено(СтрокаТаблицыХранения.КраткоеИмяТаблицыХранения) Тогда
СтрокаТаблицыХранения.КраткоеИмяТаблицыХранения = НРег(ПоследнийФрагментЛкс(СтрокаТаблицыХранения.ИмяТаблицыХранения));
КонецЕсли;
КонецЦикла;
ДобавитьИндексВТаблицуЛкс(Результат, "КраткоеИмяТаблицыХранения");
КонецПроцедуры
Процедура ЗаполнитьИмяИндексаХраненияЛкс(Знач СтрокаИндексаХранения, Знач ЛиИменаБД, Знач СтрокаТаблицыХранения) Экспорт
Индексы = СтрокаТаблицыХранения.Индексы;
Если Индексы.Колонки.Найти("ИмяИндекса") = Неопределено Тогда
Индексы.Колонки.Добавить("ИмяИндекса", Новый ОписаниеТипов("Строка"));
ПеревестиКолонкиСтруктурыХраненияБДИндексыЛкс(Индексы);
КонецЕсли;
Если Не ЗначениеЗаполнено(СтрокаИндексаХранения.ИмяИндекса) Тогда
ПеревестиКолонкиСтруктурыХраненияБДПоляЛкс(СтрокаИндексаХранения.Поля);
ПредставлениеИндекса = ПредставлениеИндексаХраненияЛкс(СтрокаИндексаХранения, ЛиИменаБД, СтрокаТаблицыХранения);
СтрокаИндексаХранения.ИмяИндекса = "Индекс(" + ПредставлениеИндекса + ")";
КонецЕсли;
КонецПроцедуры
Процедура ПеревестиКолонкиСтруктурыХраненияБДПоляЛкс(Знач Поля) Экспорт
#Если Сервер И Не Сервер Тогда
Поля = Новый ТаблицаЗначений;
#КонецЕсли
Если Поля.Колонки.Найти("ИмяПоля") = Неопределено Тогда
Поля.Колонки[ПеревестиСтроку("ИмяПоля")].Имя = "ИмяПоля";
Поля.Колонки[ПеревестиСтроку("ИмяПоляХранения")].Имя = "ИмяПоляХранения";
Поля.Колонки[ПеревестиСтроку("Метаданные")].Имя = "Метаданные";
КонецЕсли;
КонецПроцедуры
Процедура ПеревестиКолонкиСтруктурыХраненияБДИндексыЛкс(Знач Индексы) Экспорт
#Если Сервер И Не Сервер Тогда
Индексы = Новый ТаблицаЗначений;
#КонецЕсли
Если Индексы.Колонки.Найти("Поля") = Неопределено Тогда
Индексы.Колонки[ПеревестиСтроку("ИмяИндексаХранения")].Имя = "ИмяИндексаХранения";
Индексы.Колонки[ПеревестиСтроку("Поля")].Имя = "Поля";
КонецЕсли;
КонецПроцедуры
Процедура ПеревестиКолонкиСтруктурыХраненияБДТаблицыЛкс(Знач Результат) Экспорт
#Если Сервер И Не Сервер Тогда
Результат = Новый ТаблицаЗначений;
#КонецЕсли
Если Результат.Колонки.Найти("Поля") = Неопределено Тогда
Результат.Колонки[ПеревестиСтроку("ИмяТаблицы")].Имя = "ИмяТаблицы";
Результат.Колонки[ПеревестиСтроку("ИмяТаблицыХранения")].Имя = "ИмяТаблицыХранения";
Результат.Колонки[ПеревестиСтроку("Индексы")].Имя = "Индексы";
Результат.Колонки[ПеревестиСтроку("Метаданные")].Имя = "Метаданные";
Результат.Колонки[ПеревестиСтроку("Назначение")].Имя = "Назначение";
Результат.Колонки[ПеревестиСтроку("Поля")].Имя = "Поля";
КонецЕсли;
КонецПроцедуры
Процедура ПеревестиКолонкиНайтиПоСсылкамЛкс(Знач Таблица, НуженПеревод = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Таблица = Новый ТаблицаЗначений;
#КонецЕсли
Если НуженПеревод = Неопределено Тогда
НуженПеревод = Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский;
КонецЕсли;
Если НуженПеревод Тогда
Попытка
Таблица.Колонки[ПеревестиСтроку("Ссылка")].Имя = "Ссылка";
Таблица.Колонки[ПеревестиСтроку("Данные")].Имя = "Данные";
Таблица.Колонки[ПеревестиСтроку("Метаданные")].Имя = "Метаданные";
Исключение
// Повторный перевод
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Процедура ПеревестиКолонкиСистемнойТаблицыЛкс(Знач Таблица, НуженПеревод = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Таблица = Новый ТаблицаЗначений;
#КонецЕсли
Если НуженПеревод = Неопределено Тогда
НуженПеревод = Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский;
КонецЕсли;
Если НуженПеревод Тогда
Для Каждого Колонка Из Таблица.Колонки Цикл
Таблица.Колонки[Колонка.Имя].Имя = ПеревестиВРусский(Колонка.Имя);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция СтруктураХраненияБДЛкс(Знач ОтборПоМетаданным = Неопределено, ЛиИменаБД = Ложь, АдресЧужойСхемыБД = "") Экспорт
Если ОтборПоМетаданным = Неопределено Тогда
#Если Клиент Тогда
СостояниеЛкс("Получение структуры БД…");
#КонецЕсли
ИначеЕсли ТипЗнч(ОтборПоМетаданным) <> Тип("Массив") Тогда
Массив = Новый Массив;
Массив.Добавить(ОтборПоМетаданным);
ОтборПоМетаданным = Массив;
КонецЕсли;
Если ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда
СтруктураСхемы = ПолучитьЧужуюСхемуБДЛкс(АдресЧужойСхемыБД);
Если ЛиИменаБД Тогда
ГлавнаяТаблица = СтруктураСхемы.СУБД;
Иначе
ГлавнаяТаблица = СтруктураСхемы.SDBL;
КонецЕсли;
Если ОтборПоМетаданным <> Неопределено Тогда
Результат = ГлавнаяТаблица.СкопироватьКолонки();
Если ГлавнаяТаблица.Индексы.Количество() = 0 Тогда
ГлавнаяТаблица.Индексы.Добавить("Метаданные");
КонецЕсли;
Для Каждого ИмяМД Из ОтборПоМетаданным Цикл
Для Каждого СтрокаТаблицы Из ГлавнаяТаблица.НайтиСтроки("Метаданные", ИмяМД) Цикл
ЗаполнитьЗначенияСвойств(Результат.Добавить(), СтрокаТаблицы);
КонецЦикла;
КонецЦикла;
Иначе
Результат = ГлавнаяТаблица;
КонецЕсли;
Иначе
Результат = ПолучитьСтруктуруХраненияБазыДанных(ОтборПоМетаданным, ЛиИменаБД);
КонецЕсли;
ОбработатьВыборкуСтруктурыХраненияБДЛкс(Результат, ЛиИменаБД);
Если ОтборПоМетаданным = Неопределено Тогда
#Если Клиент Тогда
СостояниеЛкс("");
#КонецЕсли
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьЧужуюСхемуБДЛкс(АдресЧужойСхемыБД) Экспорт
Если Не ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда
Возврат Неопределено;
Иначе
Результат = ПолучитьИзВременногоХранилища(АдресЧужойСхемыБД);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ДочернийОбъектМДПоИмениЛкс(Знач МетаОбъект, Знач ИмяПоля, Знач ТипТаблицы = "") Экспорт
Если Не ЗначениеЗаполнено(ТипТаблицы) Тогда
ТипТаблицы = КорневойТипКонфигурацииЛкс(МетаОбъект);
КонецЕсли;
Если Ложь
Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы)
Или ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы)
Тогда
#Если Сервер И Не Сервер Тогда
МетаОбъект = Метаданные.Справочники.Валюты;
#КонецЕсли
Результат = МетаОбъект.Реквизиты.Найти(ИмяПоля);
ИначеЕсли ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда
#Если Сервер И Не Сервер Тогда
МетаОбъект = Метаданные.РегистрыСведений.КурсыВалют;
#КонецЕсли
Результат = МетаОбъект.Измерения.Найти(ИмяПоля);
Если Не ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы) Тогда
Если Результат = Неопределено Тогда
Результат = МетаОбъект.Ресурсы.Найти(ИмяПоля);
КонецЕсли;
Если Результат = Неопределено Тогда
Результат = МетаОбъект.Реквизиты.Найти(ИмяПоля);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Результат = Неопределено И ирКэш.ДоступныОбщиеРеквизитыЛкс() Тогда
ОбщийРеквизит = Метаданные.ОбщиеРеквизиты.Найти(ИмяПоля);
Если ОбщийРеквизит <> Неопределено Тогда
Если ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, МетаОбъект) Тогда
Результат = ОбщийРеквизит;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОбновитьПовторноИспользуемыеЗначенияЛкс() Экспорт
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ирПортативный.ОбновитьПовторноИспользуемыеЗначенияЛкс();
Иначе
ОбновитьПовторноИспользуемыеЗначения();
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСовместимоеЗначениеПараметраЗапросаЛкс(Знач ЗначениеПараметра, ИмяПараметра, ОписаниеТиповЭлементаУправленияПараметра = Неопределено) Экспорт
Результат = ЗначениеПараметра;
ТипЗначенияПараметра = ТипЗнч(Результат);
Если Истина
И ТипЗначенияПараметра = Тип("Массив")
И ОписаниеТиповЭлементаУправленияПараметра <> Неопределено
Тогда
СписокЗначений = Новый СписокЗначений;
ПреобразованиеУспешно = Истина;
Для Каждого ЭлементМассива Из Результат Цикл
Если ОписаниеТиповЭлементаУправленияПараметра.СодержитТип(ТипЗнч(ЭлементМассива)) Тогда
СписокЗначений.Добавить(ЭлементМассива);
Иначе
ПреобразованиеУспешно = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПреобразованиеУспешно Тогда
Результат = СписокЗначений;
КонецЕсли;
Иначе
// http://www.hostedredmine.com/issues/885230
//МетаданныеТипаЗначения = Метаданные.НайтиПоТипу(ТипЗначенияПараметра);
//Если МетаданныеТипаЗначения <> Неопределено Тогда
// ТипТаблицы = ТипТаблицыБДЛкс(МетаданныеТипаЗначения.ПолноеИмя());
// Если ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
// Результат = ЗначениеПараметра.Выгрузить();
// КонецЕсли;
//КонецЕсли;
Попытка
Результат = Результат.Выгрузить();
Исключение
КонецПопытки;
Если ОписаниеТиповЭлементаУправленияПараметра <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ОписаниеТиповЭлементаУправленияПараметра = Новый ОписаниеТипов;
#КонецЕсли
Результат = ОписаниеТиповЭлементаУправленияПараметра.ПривестиЗначение(Результат);
КонецЕсли;
КонецЕсли;
Если Результат <> ЗначениеПараметра Тогда
СообщитьЛкс(СтрШаблонИменЛкс("Значение параметра %1 было преобразовано %2->%3", 1, ИмяПараметра, 2, ТипЗначенияПараметра, 3, ТипЗнч(Результат)), СтатусСообщения.Внимание);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПолучитьСхемуИНастройкиКомпоновкиДинамическогоСпискаЛкс(Знач ДинамическийСписок, выхНастройкаКомпоновки, выхСхема) Экспорт
ТекстЗапроса = ДинамическийСписок.ТекстЗапроса;
Если Не ЗначениеЗаполнено(ТекстЗапроса) Тогда
ТекстЗапроса = "ВЫБРАТЬ * ИЗ " + ДинамическийСписок.ОсновнаяТаблица;
КонецЕсли;
Запрос = Новый Запрос(ТекстЗапроса);
выхНастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
ТекущаяГруппировка = выхНастройкаКомпоновки;
Для Каждого ПолеГруппировки Из ДинамическийСписок.Группировка.Элементы Цикл
Если ПолеГруппировки.Использование Тогда
ТекущаяГруппировка = НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура, ПолеГруппировки.Поле);
КонецЕсли;
КонецЦикла;
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура);
Для Каждого ДоступноеПоле Из ДинамическийСписок.УсловноеОформление.ДоступныеПоляПолей.Элементы Цикл
Если ДоступноеПоле.Папка Тогда
Продолжить;
КонецЕсли;
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(выхНастройкаКомпоновки.Выбор, ДоступноеПоле.Поле);
КонецЦикла;
НастройкаXDTO = СериализаторXDTO.ЗаписатьXDTO(выхНастройкаКомпоновки);
НастройкаXDTO.Filter = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Отбор);
НастройкаXDTO.DataParameters = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Параметры);
НастройкаXDTO.Order = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Порядок);
НастройкаXDTO.ConditionalAppearance = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.УсловноеОформление);
выхНастройкаКомпоновки = СериализаторXDTO.ПрочитатьXDTO(НастройкаXDTO);
выхСхема = СоздатьСхемуКомпоновкиПоЗапросу(Запрос);
КонецПроцедуры
// Создает новый экземпляр объекта и полностью замещает в нем выбранные настройки компоновки. Для дополнения оригинального объекта следует использовать СкопироватьЭлементыКомпоновкиЛкс()
Функция СкопироватьНастройкиКомпоновкиЛкс(НастройкаКомпоновкиИлиДинамическийСписокИсточник, Знач НастройкаКомпоновкиПриемник = Неопределено, КопироватьОтбор = Ложь,
КопироватьПараметрыДанных = Ложь, КопироватьПорядок = Ложь, КопироватьУсловноеОформление = Ложь, КопироватьВыбор = Ложь, КопироватьПараметрыВывода = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновкиИсточник = Новый НастройкиКомпоновкиДанных;
НастройкаКомпоновкиИлиДинамическийСписокИсточник = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
Если ТипЗнч(НастройкаКомпоновкиИлиДинамическийСписокИсточник) = Тип("НастройкиКомпоновкиДанных") Тогда
Если КопироватьПараметрыДанных Тогда
ПараметрыДанных = НастройкаКомпоновкиИлиДинамическийСписокИсточник.ПараметрыДанных;
КонецЕсли;
Если КопироватьПараметрыВывода Тогда
ПараметрыВывода = НастройкаКомпоновкиИлиДинамическийСписокИсточник.ПараметрыВывода;
КонецЕсли;
Иначе // ДинамическийСписок
Если КопироватьПараметрыДанных Тогда
ПараметрыДанных = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Параметры;
КонецЕсли;
КонецЕсли;
Если КопироватьВыбор Тогда
Выбор = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Выбор;
КонецЕсли;
Если КопироватьОтбор Тогда
Отбор = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Отбор;
КонецЕсли;
Если КопироватьПорядок Тогда
Порядок = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Порядок;
КонецЕсли;
Если КопироватьУсловноеОформление Тогда
УсловноеОформление = НастройкаКомпоновкиИлиДинамическийСписокИсточник.УсловноеОформление;
КонецЕсли;
НастройкаКомпоновкиПриемник = УстановитьКомпонентыНастроекКомпоновкиЛкс(НастройкаКомпоновкиПриемник, ПараметрыДанных, Выбор, Отбор, Порядок, УсловноеОформление, ПараметрыВывода);
Возврат НастройкаКомпоновкиПриемник;
КонецФункции
// Параметры:
// НастройкаКомпоновкиПриемник - ? -
// Параметры - ? -
// Выбор - ? -
// Отбор - ? -
// Порядок - ? -
// УсловноеОформление - ? -
// Возвращаемое значение:
// НастройкиКомпоновкиДанных - новый объект настроек с установленными компонентами
Функция УстановитьКомпонентыНастроекКомпоновкиЛкс(Знач НастройкаКомпоновкиПриемник = Неопределено, Знач ПараметрыДанных = Неопределено, Знач Выбор = Неопределено, Знач Отбор = Неопределено,
Знач Порядок = Неопределено, Знач УсловноеОформление = Неопределено, ПараметрыВывода = Неопределено) Экспорт
Если НастройкаКомпоновкиПриемник = Неопределено Тогда
НастройкаКомпоновкиПриемник = Новый НастройкиКомпоновкиДанных;
КонецЕсли;
НастройкаXDTO = СериализаторXDTO.ЗаписатьXDTO(НастройкаКомпоновкиПриемник);
Если ПараметрыДанных <> Неопределено Тогда
НастройкаXDTO.DataParameters = СериализаторXDTO.ЗаписатьXDTO(ПараметрыДанных);
КонецЕсли;
Если Выбор <> Неопределено Тогда
НастройкаXDTO.selection = СериализаторXDTO.ЗаписатьXDTO(Выбор);
КонецЕсли;
Если Отбор <> Неопределено Тогда
НастройкаXDTO.Filter = СериализаторXDTO.ЗаписатьXDTO(Отбор);
КонецЕсли;
Если Порядок <> Неопределено Тогда
НастройкаXDTO.Order = СериализаторXDTO.ЗаписатьXDTO(Порядок);
КонецЕсли;
Если УсловноеОформление <> Неопределено Тогда
НастройкаXDTO.ConditionalAppearance = СериализаторXDTO.ЗаписатьXDTO(УсловноеОформление);
КонецЕсли;
Если ПараметрыВывода <> Неопределено Тогда
НастройкаXDTO.OutputParameters = СериализаторXDTO.ЗаписатьXDTO(ПараметрыВывода);
КонецЕсли;
НастройкаКомпоновкиПриемник = СериализаторXDTO.ПрочитатьXDTO(НастройкаXDTO);
Возврат НастройкаКомпоновкиПриемник;
КонецФункции
Процедура КомпоновщикНастроекВосстановитьЛкс(Компоновщик) Экспорт
#Если Сервер И Не Сервер Тогда
Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
#КонецЕсли
Компоновщик.Восстановить(); //Удаляет некорректные элементы пользовательских настроек https://www.hostedredmine.com/issues/947616
// Защита от ошибки "глобальные элементы отбора обязательно должны использовать поля"
// https://partners.v8.1c.ru/forum/topic/2028705
Для Каждого ЭлементОтбора Из Компоновщик.Настройки.Отбор.Элементы Цикл
Если Истина
И ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных")
И ТипЗнч(ЭлементОтбора.ЛевоеЗначение) <> Тип("ПолеКомпоновкиДанных")
Тогда
ЭлементОтбора.Использование = Ложь;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция РасширениеФайловДляОтладкиЛкс() Экспорт
Результат = "deb";
Возврат Результат;
КонецФункции
Функция ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки = Неопределено, Знач Наименование = "")
Если Не ЗначениеЗаполнено(Наименование) Тогда
Наименование = "" + СтруктураПараметров.Объект;
КонецЕсли;
Наименование = "" + ТекущаяДата() + " " + СтруктураПараметров.ТипОперации + " " + Наименование;
Успех = Ложь;
ДоступноФоновоеЗадание = Не (Истина
И ТранзакцияАктивна()
И ирКэш.ЛиФайловаяБазаЛкс()
// В файловой базе даже 8.3 не получится, т.к. там не истинной параллельности
//И (Ложь
// Или РежимСовместимостиМеньше8_3_4Лкс()
// Или ирКэш.ЭтоФоновоеЗаданиеЛкс())
);
Если Истина
И Метаданные.Справочники.Найти("ирОбъектыДляОтладки") <> Неопределено
И ДоступноФоновоеЗадание
Тогда
Попытка
ХранимоеЗначение = ОбъектВСтрокуXMLЛкс(СтруктураПараметров);
СтруктураОбъекта = ОбъектБДПоКлючуЛкс(Метаданные.Справочники.ирОбъектыДляОтладки.ПолноеИмя());
ОбъектДляОтладки = СтруктураОбъекта.Данные;
ОбъектДляОтладки.Наименование = Наименование;
ОбъектДляОтладки.XML = ХранимоеЗначение;
выхОбъектДляОтладки = ЗаписатьОбъектДляОтладкиЛкс(СтруктураОбъекта.Методы);
Успех = Истина;
Исключение
Результат = "Ошибка записи объекта для отладки: " + ОписаниеОшибки();
КонецПопытки;
Если Успех Тогда
Результат = "Скопируйте эту строку и используйте команду ""Открыть объект для отладки"". Данные помещены в справочник ""Объекты для отладки""."
+ " Объект """ + ОбъектДляОтладки + """(" + выхОбъектДляОтладки.УникальныйИдентификатор() + ")";
КонецЕсли;
Иначе
//выхОбъектДляОтладки = ПоместитьВоВременноеХранилище(ХранимоеЗначение, Новый УникальныйИдентификатор);
//Результат = "Данные помещены в хранилище ДО КОНЦА СЕАНСА. Скопируйте эту строку и используйте команду ""Открыть объект для отладки""."
//+ " Адрес """ + выхОбъектДляОтладки + """";
КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс();
Успех = Ложь;
Если ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
РасширениеФайловДляОтладки = РасширениеФайловДляОтладкиЛкс();
Наименование = ИдентификаторИзПредставленияЛкс(Наименование);
ИмяФайла = КаталогОбъектовДляОтладки + РазделительПутиКФайлуЛкс() + Наименование + "." + РасширениеФайловДляОтладки;
ФайлОбъектаДляОтладки = Новый Файл(ИмяФайла);
Попытка
ОбъектВСтрокуXMLЛкс(СтруктураПараметров, , ФайлОбъектаДляОтладки.ПолноеИмя);
Успех = Истина;
Исключение
СообщитьЛкс("Ошибка сохранения файла для отладки: " + ОписаниеОшибки());
КонецПопытки;
Если Успех Тогда
выхОбъектДляОтладки = ФайлОбъектаДляОтладки.ПолноеИмя;
Результат = "Скопируйте эту строку и используйте команду ""Открыть объект для отладки"". Данные помещены в файл."
+ " Файл """ + выхОбъектДляОтладки + """";
КонецЕсли;
Иначе
ТекстРекомендации = "Рекомендуется в общих настройках инструментов задать каталог объектов для отладки.";
СообщитьЛкс(ТекстРекомендации);
КонецЕсли;
Если Не Успех Тогда
Если ТранзакцияАктивна() И Не ДоступноФоновоеЗадание Тогда
Попытка
ОтменитьТранзакцию();
Успех = Истина;
Исключение
// Системная транзакция записи объекта
КонецПопытки;
Если Не Успех Тогда
Результат = "Невозможно отменить транзакцию записи объекта для сохранения объекта для отладки в общие настройки. " + ТекстРекомендации;
Иначе
СообщитьЛкс("Транзакция была отменена для сохранения объекта для отладки в общие настройки");
КонецЕсли;
Иначе
Успех = Истина;
КонецЕсли;
Если Успех Тогда
Успех = Ложь;
Попытка
КлючНастройки = ЗаписатьОбъектДляОтладкиЛкс(СтруктураПараметров);
Успех = Истина;
Исключение
Результат = "Ошибка записи объекта для отладки: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Если Успех Тогда
Результат = РезультатСохраненияОбъектаОтложеннойОтладкиВНастройкуЛкс(КлючНастройки);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И СтруктураПараметров.Свойство("СериализацияФабрикой")
И СтруктураПараметров.СериализацияФабрикой = "Внутр"
Тогда
Результат = Результат + ". Применена ЗначениеВСтрокуВнутр() и получено " + СтрДлина(СтруктураПараметров.Объект) + " символов.";
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// КлючНастройки - Ссылка, Строка
Функция РезультатСохраненияОбъектаОтложеннойОтладкиВНастройкуЛкс(Знач КлючНастройки = "") Экспорт
Если Не ЗначениеЗаполнено(КлючНастройки) Тогда
КлючНастройки = ИмяНастройкиХраненияОбъектаОтложеннойОтладкиЛкс();
КонецЕсли;
Результат = "Скопируйте эту строку и используйте команду ""Открыть объект для отладки"". Данные помещены в настройку """ + КлючНастройки + """."
+ " Пользователь """ + ИмяПользователя() + """";
Возврат Результат;
КонецФункции
Функция СоздаваемыеВременныеТаблицыПакетаЛкс(ТекстЗапроса, ТолькоТребующиеУничтоженияНаВходе = Ложь) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
МассивТаблиц = мПлатформа.ПолучитьМассивСоздаваемыхВременныхТаблицПакета(ТекстЗапроса, ТолькоТребующиеУничтоженияНаВходе);
Возврат МассивТаблиц;
КонецФункции
// Подставляет параметры в строку. Максимально возможное число параметров - 9.
// Параметры в строке задаются как %<номер параметра>. Нумерация параметров начинается с единицы.
//
// Параметры:
// СтрокаПодстановки - Строка - шаблон строки с параметрами (вхождениями вида "%ИмяПараметра");
// Параметр - Строка - подставляемый параметр.
//
// Возвращаемое значение:
// Строка - текстовая строка с подставленными параметрами.
//
// Пример:
// ПодставитьПараметрыВСтроку(НСтр("ru='%1 пошел в %2'"), "Вася", "Зоопарк") = "Вася пошел в Зоопарк".
//
Функция ПодставитьПараметрыВСтрокуЛкс(Знач СтрокаПодстановки,
Знач Параметр1, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено,
Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено,
Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) Экспорт
ИспользоватьАльтернативныйАлгоритм = Ложь
Или Найти(Параметр1, "%")
Или Найти(Параметр2, "%")
Или Найти(Параметр3, "%")
Или Найти(Параметр4, "%")
Или Найти(Параметр5, "%")
Или Найти(Параметр6, "%")
Или Найти(Параметр7, "%")
Или Найти(Параметр8, "%")
Или Найти(Параметр9, "%");
Если ИспользоватьАльтернативныйАлгоритм Тогда
СтрокаПодстановки = ПодставитьПараметрыВСтрокуАльтернативныйАлгоритм(СтрокаПодстановки, Параметр1,
Параметр2, Параметр3, Параметр4, Параметр5, Параметр6, Параметр7, Параметр8, Параметр9);
Иначе
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%1", Параметр1);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%2", Параметр2);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%3", Параметр3);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%4", Параметр4);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%5", Параметр5);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%6", Параметр6);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%7", Параметр7);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%8", Параметр8);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%9", Параметр9);
КонецЕсли;
Возврат СтрокаПодстановки;
КонецФункции
// Вставляет параметры в строку, учитывая, что в параметрах могут использоваться подстановочные слова %1, %2 и т.д.
Функция ПодставитьПараметрыВСтрокуАльтернативныйАлгоритм(Знач СтрокаПодстановки,
Знач Параметр1, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено,
Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено,
Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено)
Результат = "";
Позиция = Найти(СтрокаПодстановки, "%");
Пока Позиция > 0 Цикл
Результат = Результат + Лев(СтрокаПодстановки, Позиция - 1);
СимволПослеПроцента = Сред(СтрокаПодстановки, Позиция + 1, 1);
ПодставляемыйПараметр = "";
Если СимволПослеПроцента = "1" Тогда
ПодставляемыйПараметр = Параметр1;
ИначеЕсли СимволПослеПроцента = "2" Тогда
ПодставляемыйПараметр = Параметр2;
ИначеЕсли СимволПослеПроцента = "3" Тогда
ПодставляемыйПараметр = Параметр3;
ИначеЕсли СимволПослеПроцента = "4" Тогда
ПодставляемыйПараметр = Параметр4;
ИначеЕсли СимволПослеПроцента = "5" Тогда
ПодставляемыйПараметр = Параметр5;
ИначеЕсли СимволПослеПроцента = "6" Тогда
ПодставляемыйПараметр = Параметр6;
ИначеЕсли СимволПослеПроцента = "7" Тогда
ПодставляемыйПараметр = Параметр7
ИначеЕсли СимволПослеПроцента = "8" Тогда
ПодставляемыйПараметр = Параметр8;
ИначеЕсли СимволПослеПроцента = "9" Тогда
ПодставляемыйПараметр = Параметр9;
КонецЕсли;
Если ПодставляемыйПараметр = "" Тогда
Результат = Результат + "%";
СтрокаПодстановки = Сред(СтрокаПодстановки, Позиция + 1);
Иначе
Результат = Результат + ПодставляемыйПараметр;
СтрокаПодстановки = Сред(СтрокаПодстановки, Позиция + 2);
КонецЕсли;
Позиция = Найти(СтрокаПодстановки, "%");
КонецЦикла;
Результат = Результат + СтрокаПодстановки;
Возврат Результат;
КонецФункции
Функция ПолучитьКаталогОбъектовДляОтладкиЛкс(ДляСервера = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ирПортативный = Обработки.ирПортативный.Создать();
#КонецЕсли
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
КаталогОбъектовДляОтладки = ирПортативный.ПолучитьКаталогОбъектовДляОтладкиЛкс();
Иначе
//ИмяФайла = ПолучитьИмяВременногоФайла(РасширениеФайловДляОтладки);
КаталогОбъектовДляОтладки = ВосстановитьЗначениеЛкс("КаталогОбъектовДляОтладки");
#Если Клиент Тогда
Если Не ДляСервера И Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
КаталогОбъектовДляОтладки = ирКэш.Получить().КаталогФайловогоКэша;
КонецЕсли;
#КонецЕсли
Если ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
ИмяКаталогаБазы = ИдентификаторИзПредставленияЛкс(СтрокаСоединенияИнформационнойБазы());
КаталогОбъектовДляОтладки = КаталогОбъектовДляОтладки + "\" + ИмяКаталогаБазы + "\";
КаталогОбъектовДляОтладки = СтрЗаменить(КаталогОбъектовДляОтладки, "\", РазделительПутиКФайлуЛкс());
Каталог = Новый Файл(КаталогОбъектовДляОтладки);
Если Не Каталог.Существует() Тогда
Попытка
СоздатьКаталог(КаталогОбъектовДляОтладки);
Исключение
СообщитьЛкс("Ошибка создания каталога объектов для отладки: " + ОписаниеОшибки());
КаталогОбъектовДляОтладки = Неопределено;
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат КаталогОбъектовДляОтладки;
КонецФункции
Функция ИмяПродуктаЛкс() Экспорт
Возврат "ИнструментыРазработчикаTormozit";
КонецФункции
Функция ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(Параметры) Экспорт
// Антибаг платформы 8.2.18. Некорректная сериализация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СтруктураЗапроса.Параметры = КопияОбъектаЛкс(Объект.Параметры);
Структура = Новый Структура();
Для Каждого КлючИЗначение Из Параметры Цикл
ЗначениеПараметра = ПолучитьСовместимоеЗначениеПараметраЗапросаЛкс(КлючИЗначение.Значение, КлючИЗначение.Ключ);
Структура.Вставить(КлючИЗначение.Ключ, ЗначениеВСтрокуВнутр(ЗначениеПараметра));
КонецЦикла;
Возврат Структура;
КонецФункции
Функция СкопироватьЗапросЛкс(ЗапросИсточник, ЗапросПриемник = Неопределено) Экспорт
Если ЗапросПриемник = Неопределено Тогда
ЗапросПриемник = Новый Запрос;
КонецЕсли;
ЗапросПриемник.Текст = ЗапросИсточник.Текст;
ирОбщий.СкопироватьУниверсальнуюКоллекциюЛкс(ЗапросИсточник.Параметры, ЗапросПриемник.Параметры);
Возврат ЗапросПриемник;
КонецФункции // СкопироватьЗапросЛкс()
Функция ПолучитьТекстЗапросаВсехТиповСсылокЛкс(ИмяВременнойТаблицы = "ВсеТипыСсылок", Знач ОписаниеТипов = Неопределено) Экспорт
Если ОписаниеТипов = Неопределено Тогда
ОписаниеТипов = ОписаниеТиповВсеСсылкиЛкс();
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОписаниеВсехТипов = Новый ОписаниеТипов;
#КонецЕсли
ТекстТаблицыТипов = "";
Для Каждого Тип Из ОписаниеТипов.Типы() Цикл
ПолноеИмя = Метаданные.НайтиПоТипу(Тип).ПолноеИмя();
НоваяСтрока = "ВЫБРАТЬ ТИП(" + ПолноеИмя + ") КАК Тип, """ + ПолноеИмя + """ КАК Имя" + Символы.ПС;
Если ТекстТаблицыТипов <> "" Тогда
ТекстТаблицыТипов = ТекстТаблицыТипов + "ОБЪЕДИНИТЬ ВСЕ " + Символы.ПС;
Иначе
Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
НоваяСтрока = НоваяСтрока + "ПОМЕСТИТЬ " + ИмяВременнойТаблицы + Символы.ПС;
КонецЕсли;
КонецЕсли;
ТекстТаблицыТипов = ТекстТаблицыТипов + НоваяСтрока;
КонецЦикла;
//ТекстТаблицыТипов = ТекстТаблицыТипов + " ИНДЕКСИРОВАТЬ ПО Тип"; // По такому типу поля нельзя индексировать
Возврат ТекстТаблицыТипов;
КонецФункции
Функция ПолучитьТекстЗапросаДатВДиапазонеЛкс(ИмяВременнойТаблицы = "ДатыДиапазона") Экспорт
Текст = "ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, aa.a * 1000 + bb.a * 100 + cc.a * 10 + dd.a) КАК Период
|";
Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
Текст = Текст + "ПОМЕСТИТЬ " + ИмяВременнойТаблицы + Символы.ПС;
КонецЕсли;
Текст = Текст +
"ИЗ
| (ВЫБРАТЬ 0 КАК a ОБЪЕДИНИТЬ ВЫБРАТЬ 1 ОБЪЕДИНИТЬ ВЫБРАТЬ 2 ОБЪЕДИНИТЬ ВЫБРАТЬ 3 ОБЪЕДИНИТЬ ВЫБРАТЬ 4 ОБЪЕДИНИТЬ ВЫБРАТЬ 5 ОБЪЕДИНИТЬ ВЫБРАТЬ 6 ОБЪЕДИНИТЬ ВЫБРАТЬ 7 ОБЪЕДИНИТЬ ВЫБРАТЬ 8 ОБЪЕДИНИТЬ ВЫБРАТЬ 9) КАК aa
| СОЕДИНЕНИЕ (ВЫБРАТЬ 0 КАК a ОБЪЕДИНИТЬ ВЫБРАТЬ 1 ОБЪЕДИНИТЬ ВЫБРАТЬ 2 ОБЪЕДИНИТЬ ВЫБРАТЬ 3 ОБЪЕДИНИТЬ ВЫБРАТЬ 4 ОБЪЕДИНИТЬ ВЫБРАТЬ 5 ОБЪЕДИНИТЬ ВЫБРАТЬ 6 ОБЪЕДИНИТЬ ВЫБРАТЬ 7 ОБЪЕДИНИТЬ ВЫБРАТЬ 8 ОБЪЕДИНИТЬ ВЫБРАТЬ 9) КАК bb ПО ИСТИНА
| СОЕДИНЕНИЕ (ВЫБРАТЬ 0 КАК a ОБЪЕДИНИТЬ ВЫБРАТЬ 1 ОБЪЕДИНИТЬ ВЫБРАТЬ 2 ОБЪЕДИНИТЬ ВЫБРАТЬ 3 ОБЪЕДИНИТЬ ВЫБРАТЬ 4 ОБЪЕДИНИТЬ ВЫБРАТЬ 5 ОБЪЕДИНИТЬ ВЫБРАТЬ 6 ОБЪЕДИНИТЬ ВЫБРАТЬ 7 ОБЪЕДИНИТЬ ВЫБРАТЬ 8 ОБЪЕДИНИТЬ ВЫБРАТЬ 9) КАК cc ПО ИСТИНА
| СОЕДИНЕНИЕ (ВЫБРАТЬ 0 КАК a ОБЪЕДИНИТЬ ВЫБРАТЬ 1 ОБЪЕДИНИТЬ ВЫБРАТЬ 2 ОБЪЕДИНИТЬ ВЫБРАТЬ 3 ОБЪЕДИНИТЬ ВЫБРАТЬ 4 ОБЪЕДИНИТЬ ВЫБРАТЬ 5 ОБЪЕДИНИТЬ ВЫБРАТЬ 6 ОБЪЕДИНИТЬ ВЫБРАТЬ 7 ОБЪЕДИНИТЬ ВЫБРАТЬ 8 ОБЪЕДИНИТЬ ВЫБРАТЬ 9) КАК dd ПО ИСТИНА
|ГДЕ
| aa.a * 1000 + bb.a * 100 + cc.a * 10 + dd.a <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ)";
Возврат Текст;
КонецФункции
Функция ПолучитьСобственноеВнешнееСоединениеЛкс(ИнициализироватьИнтерфейсИР = Ложь, выхИнтерфейсИР = Неопределено) Экспорт
ИмяПользователяВнешнегоСоединения = "";
ПарольПользователяВнешнегоСоединения = "";
Если ПользователиИнформационнойБазы.ПолучитьПользователей().Количество() > 0 Тогда
ИмяПользователяВнешнегоСоединения = ИмяПользователя() + "_ВнешнееСоединение";
Попытка
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователяВнешнегоСоединения);
Исключение
СообщитьЛкс("Не удалось выполнить поиск служебного пользователя: " + ОписаниеОшибки());
// Разделенная база в неразделенном сеансе
Возврат Неопределено;
КонецПопытки;
Если ПользовательИБ = Неопределено Тогда
ПользовательИБ = ПользователиИнформационнойБазы.СоздатьПользователя();
ПользовательИБ.Имя = ИмяПользователяВнешнегоСоединения;
ПользовательИБ.ПолноеИмя = ИмяПользователяВнешнегоСоединения;
СообщитьЛкс(СтрШаблонИменЛкс("Создан служебный пользователь ИБ с именем %1",, ИмяПользователяВнешнегоСоединения));
КонецЕсли;
ТекущийПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
ЗаполнитьЗначенияСвойств(ПользовательИБ, ТекущийПользовательИБ,, "Имя, ПолноеИмя");
ПользовательИБ.Роли.Очистить();
Для Каждого Роль Из ТекущийПользовательИБ.Роли Цикл
ПользовательИБ.Роли.Добавить(Роль);
КонецЦикла;
ПарольПользователяВнешнегоСоединения = "" + Новый УникальныйИдентификатор;
ПользовательИБ.ПоказыватьВСпискеВыбора = Ложь;
ПользовательИБ.АутентификацияОС = Ложь;
ПользовательИБ.АутентификацияСтандартная = Истина;
ПользовательИБ.Пароль = ПарольПользователяВнешнегоСоединения;
ПользовательИБ.Записать();
КонецЕсли;
Результат = ЗапуститьСеансПодПользователемЛкс(ИмяПользователяВнешнегоСоединения, ПарольПользователяВнешнегоСоединения, "ComConnector");
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
выхИнтерфейсИР = Результат.ВнешниеОбработки.Создать(ирПортативный.ИспользуемоеИмяФайла, Ложь);
Иначе
выхИнтерфейсИР = Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
// Ключи формируются только из данных расшифровки ячеек.
// Параметры:
// ТабличныйДокумент - ТабличныйДокумент
// ДанныеРасшифровки - ДанныеРасшифровкиКомпоновкиДанных
// Поля - Строка(0,П), Массив - Если строка, то через запятую перечисленные имена полей.
// Область - ВыделенныеОбластиТабличногоДокумента, Массив, ОбластьЯчеекТабличногоДокумента - Если не указано, используются выделенные области
//
Функция ТаблицаКлючейИзТабличногоДокументаЛкс(Знач ТабличныйДокумент, Знач ДанныеРасшифровки = Неопределено, Знач Поля = "", Знач Область = Неопределено,
Знач выхКлючТекущейСтроки = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
Если Истина
И ТипЗнч(Поля) = Тип("Строка")
И Не ПустаяСтрока(Поля)
Тогда
МассивИменПолей = ирОбщий.СтрРазделитьЛкс(Поля, ",", Истина);
ИначеЕсли ТипЗнч(Поля) = Тип("Массив") Тогда
МассивИменПолей = Поля;
Иначе
МассивИменПолей = Новый Массив;
КонецЕсли;
ТаблицаРезультата = Неопределено;
МассивСсылок = Новый Массив;
АвтоПоля = МассивИменПолей.Количество() = 0;
Если ТипЗнч(Область) = Тип("Неопределено") Тогда
КоллекцияОбластей = ТабличныйДокумент.ВыделенныеОбласти;
ИначеЕсли ТипЗнч(Область) = Тип("Массив") Тогда
КоллекцияОбластей = Область;
ИначеЕсли ТипЗнч(Область) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда
КоллекцияОбластей = Новый Массив;
КоллекцияОбластей.Добавить(Область);
Иначе
ВызватьИсключение "Некорректный тип параметра ""Область""";
КонецЕсли;
Если ТипЗнч(ДанныеРасшифровки) = Тип("ДанныеРасшифровкиКомпоновкиДанных") Тогда
ЭлементыРасшифровки = ДанныеРасшифровки.Элементы;
КонецЕсли;
НачальноеКоличество = КоллекцияОбластей.Количество();
ЛиПрервать = Ложь;
Для СчетчикВыделенныеОбласти = 1 По НачальноеКоличество Цикл
Область = КоллекцияОбластей[НачальноеКоличество - СчетчикВыделенныеОбласти];
Если Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Колонки Тогда
Лево = Область.Лево;
Право = Область.Право;
Верх = 1;
Низ = ТабличныйДокумент.ВысотаТаблицы;
ИначеЕсли Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Строки Тогда
Лево = 1;
Право = ТабличныйДокумент.ШиринаТаблицы;
Верх = Область.Верх;
Низ = Область.Низ;
ИначеЕсли Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Прямоугольник Тогда
Лево = Область.Лево;
Право = Область.Право;
Верх = Область.Верх;
Низ = Область.Низ;
Иначе // Если Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Таблица Тогда
Лево = 1;
Право = ТабличныйДокумент.ШиринаТаблицы;
Верх = 1;
Низ = ТабличныйДокумент.ВысотаТаблицы;
КонецЕсли;
Для НомерСтроки = Верх по Низ Цикл
КлючПолучен = Ложь;
СтруктураПолей = Новый Структура;
Для НомерКолонки = Лево по Право Цикл
ОбластьЯчейки = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
Если ОбластьЯчейки.Лево <> НомерКолонки Или ОбластьЯчейки.Верх <> НомерСтроки Тогда
// Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой
Продолжить;
КонецЕсли;
Расшифровка = ОбластьЯчейки.Расшифровка;
Если ТипЗнч(Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
Если ЭлементыРасшифровки = Неопределено Тогда
СообщитьЛкс("В табличном документа найден идентификатор расшифровки компоновки, но не переданы данные расшифровки");
ЛиПрервать = Истина;
Прервать;
КонецЕсли;
ЭлементРасшифровкиПоля = ЭлементыРасшифровки[Расшифровка];
Если НомерСтроки = Верх Тогда
Если ТаблицаРезультата = Неопределено Тогда
ТаблицаРезультата = Новый ТаблицаЗначений;
Для Каждого ИмяПоля Из МассивИменПолей Цикл
ТаблицаРезультата.Колонки.Добавить(ИмяПоля);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КлючПолучен = ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(ЭлементРасшифровкиПоля, МассивИменПолей, СтруктураПолей);
Если Истина
И КлючПолучен
И (Ложь
Или НомерКолонки = Право
Или Не АвтоПоля)
Тогда
Прервать;
КонецЕсли;
ИначеЕсли ирОбщий.ЛиСсылкаНаОбъектБДЛкс(Расшифровка, Ложь) Тогда
СтруктураПолей.Вставить("Ссылка", Расшифровка);
КлючПолучен = Истина;
ИначеЕсли ТипЗнч(Расшифровка) = Тип("Структура") Тогда
СкопироватьУниверсальнуюКоллекциюЛкс(Расшифровка, СтруктураПолей);
КонецЕсли;
КонецЦикла;
Если ЛиПрервать Тогда
Прервать;
КонецЕсли;
Если КлючПолучен Тогда
Если ТаблицаРезультата = Неопределено Тогда
ТаблицаРезультата = Новый ТаблицаЗначений;
КонецЕсли;
Для Каждого КлючИЗначение Из СтруктураПолей Цикл
Если ТаблицаРезультата.Колонки.Найти(КлючИЗначение.Ключ) = Неопределено Тогда
ТаблицаРезультата.Колонки.Добавить(КлючИЗначение.Ключ);
КонецЕсли;
КонецЦикла;
Если Ложь
Или МассивИменПолей.Количество() = 0
Или ТаблицаРезультата.НайтиСтроки(СтруктураПолей).Количество() = 0
Тогда
СтрокаРезультата = ТаблицаРезультата.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаРезультата, СтруктураПолей);
Если ТабличныйДокумент.ТекущаяОбласть = Область Тогда
выхКлючТекущейСтроки = СтрокаРезультата;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ЛиПрервать Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если ТаблицаРезультата = Неопределено Тогда
ТаблицаРезультата = Новый ТаблицаЗначений;
КонецЕсли;
Результат = ТаблицаРезультата;
Возврат Результат;
КонецФункции
// Извлекаемые значения помещаются в структуру
// Параметры:
// ЭлементРасшифровкиПоля - ЭлементРасшифровкиКомпоновкиДанныхГруппировка, ЭлементРасшифровкиКомпоновкиДанныхПоля
// Поля - Строка(0,П), Массив
// СтруктураПолей - Структура (если поля заданы), Соответствие
//
Функция ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(Знач ЭлементРасшифровкиПоля, Знач Поля = "", выхСтруктураПолей = Неопределено, ЛиКорневой = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый ДанныеРасшифровкиКомпоновкиДанных;
ЭлементРасшифровкиПоля = Пустышка.Элементы[0];
#КонецЕсли
Если выхСтруктураПолей = Неопределено Тогда
выхСтруктураПолей = Новый Структура;
КонецЕсли;
Если Истина
И ТипЗнч(Поля) = Тип("Строка")
И Не ПустаяСтрока(Поля)
Тогда
МассивИменПолей = ирОбщий.СтрРазделитьЛкс(Поля, ",", Истина);
ИначеЕсли ТипЗнч(Поля) = Тип("Массив") Тогда
МассивИменПолей = Поля;
Иначе
МассивИменПолей = Новый Массив;
КонецЕсли;
Если МассивИменПолей.Количество() > 0 И выхСтруктураПолей.Количество() = МассивИменПолей.Количество() Тогда
Результат = Истина;
Иначе
Результат = Ложь;
Если ТипЗнч(ЭлементРасшифровкиПоля) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
ЗначенияПолей = ЭлементРасшифровкиПоля.ПолучитьПоля();
Если ЗначенияПолей.Количество() > 0 Тогда
Если МассивИменПолей.Количество() > 0 Тогда
Для Каждого ИмяПоля Из МассивИменПолей Цикл
ЗначениеПоля = ЗначенияПолей.Найти(ИмяПоля);
ИмяСвойства = СтрЗаменить(ИмяПоля, ".", "");
Если Истина
И ЗначениеПоля <> Неопределено
И Не выхСтруктураПолей.Свойство(ИмяСвойства)
Тогда
выхСтруктураПолей.Вставить(ИмяСвойства, ЗначениеПоля.Значение);
Если выхСтруктураПолей.Количество() = МассивИменПолей.Количество() Тогда
Результат = Истина;
Прервать
КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе
Для Каждого ЗначениеПоля Из ЗначенияПолей Цикл
Ключ = "" + ЗначениеПоля.Поле;
Если ТипЗнч(выхСтруктураПолей) = Тип("Структура") Тогда
Ключ = СтрЗаменить(Ключ, ".", "_");
КонфликтноеЗначение = Неопределено;
Если Ложь
Или ЛиКорневой
Или (Истина
И выхСтруктураПолей.Свойство(Ключ, КонфликтноеЗначение)
И КонфликтноеЗначение <> ЗначениеПоля.Значение)
Тогда
Ключ = АвтоУникальноеИмяВКоллекцииЛкс(выхСтруктураПолей, Ключ, "Ключ");
КонецЕсли;
Иначе
Если Ложь
Или ЛиКорневой
Или (Истина
И ТипЗнч(выхСтруктураПолей) = Тип("Соответствие")
И выхСтруктураПолей[Ключ] <> ЗначениеПоля.Значение)
Тогда
Ключ = АвтоУникальноеИмяВКоллекцииЛкс(выхСтруктураПолей, Ключ, "Ключ", Ложь);
КонецЕсли;
КонецЕсли;
выхСтруктураПолей.Вставить(Ключ, ЗначениеПоля.Значение);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не Результат Тогда
РодительскиеЭлементыРасшифровки = ЭлементРасшифровкиПоля.ПолучитьРодителей();
Для Каждого РодительскийЭлементРасшифровки Из РодительскиеЭлементыРасшифровки Цикл
Результат = ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(РодительскийЭлементРасшифровки, МассивИменПолей, выхСтруктураПолей, Ложь);
Если Результат И МассивИменПолей.Количество() > 0 Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если Истина
И МассивИменПолей.Количество() = 0
И РодительскиеЭлементыРасшифровки.Количество() = 0
Тогда
Результат = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьСоединениеСУБД(Знач ИмяСервера = "", Знач ИмяБД = "", Знач ИмяПользователя = "", Знач Пароль = "", Асинхронно = Ложь, Знач ТипСУБД = "") Экспорт
Если Не ЗначениеЗаполнено(ИмяСервера) Тогда
ПараметрыСоединения = ПараметрыСоединенияADOЭтойБДЛкс();
ИмяСервера = ПараметрыСоединения.ИмяСервера;
ИмяБД = ПараметрыСоединения.ИмяБД;
ИмяПользователя = ПараметрыСоединения.ИмяПользователя;
Пароль = ПараметрыСоединения.Пароль;
ТипСУБД = ПараметрыСоединения.ТипСУБД;
КонецЕсли;
КонсольЗапросов = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
ИсточникДанных = КонсольЗапросов.ПолучитьСтруктуруИсточникаДанныхADO();
Если ТипСУБД = "MSSQL" Тогда
ИсточникДанных.Платформа = 11; // ADO-SQLOLEDB
Иначе
ИсточникДанных.Платформа = 18; // ADO-PostgreSQL
КонецЕсли;
ИсточникДанных.БазаСервер = ИмяСервера;
ИсточникДанных.БазаИмя = ИмяБД;
ИсточникДанных.АутентификацияОС = Не ЗначениеЗаполнено(ИмяПользователя);
ИсточникДанных.Пользователь = ИмяПользователя;
ИсточникДанных.Пароль = Пароль;
СоединениеADO = Неопределено;
ОшибкиПодключения = Неопределено;
РезультатПодключения = КонсольЗапросов.ConnectADO(ИсточникДанных, СоединениеADO,, ОшибкиПодключения,, Асинхронно);
Если Асинхронно Тогда
Возврат СоединениеADO;
КонецЕсли;
Если Не РезультатПодключения Тогда
СообщениеОбОшибке = "Ошибки подключения к СУБД:";
Для каждого ОшибкаПодключения Из ОшибкиПодключения Цикл
СообщениеОбОшибке = СообщениеОбОшибке + Символы.ПС + ОшибкаПодключения;
КонецЦикла;
СообщитьЛкс(СообщениеОбОшибке);
СоединениеADO = Неопределено;
Иначе
КлючНастроек = "" + Новый УникальныйИдентификатор;
ХранилищеОбщихНастроек.Сохранить(ирКэш.ИмяПродукта(), КлючНастроек, Неопределено);
РезультатЗапроса = ирОбщий.ВыполнитьЗапросКЭтойБазеЧерезADOЛкс("SELECT 1 FROM _CommonSettings WHERE _SettingsKey = '" + КлючНастроек + "'",,,,, Ложь, СоединениеADO);
ХранилищеОбщихНастроек.Удалить(ирКэш.ИмяПродукта(), КлючНастроек, ИмяПользователя());
Если РезультатЗапроса.Количество() = 0 Тогда
Если ТранзакцияАктивна() Тогда
СообщитьЛкс("Невозможно проверить подключение к БД текущей базы 1С внутри открытой транзакции. Закройте транзакцию и повторите проверку.", СтатусСообщения.Внимание);
Иначе
СообщитьЛкс("Указаны параметры подключения к БД, не связанной с текущей базой 1С", СтатусСообщения.Внимание);
КонецЕсли;
СоединениеADO = Неопределено;
КонецЕсли;
КонецЕсли;
Возврат СоединениеADO;
КонецФункции
Функция ОткрытьЗапросСУБДЛкс(ТекстЗапроса, ИмяЗапроса = "Запрос для отладки", Параметры = Неопределено, Автоподключение = Ложь) Экспорт
КонсольЗапросов = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
КонсольЗапросов.ОткрытьЗапросБД(ТекстЗапроса, ИмяЗапроса, Параметры, Автоподключение);
КонецФункции
Функция ОбновитьМодульВнешнейОбработкиДляОтладкиЛкс(БазовоеИмяВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля, ТекстМодуляВКонсолиНеМенялся, ДатаИзмененияВнешнейОбработки,
ИспользоватьБыструюРаспаковку = Ложь) Экспорт
// Из-за негарантированной последовательности изменений одного файла в сетевом ресурсе, проводимых с разных компьютеров, серверное выполнение лишено смысла
//Если НаСервере Тогда
// Результат = ирСервер.ОбновитьМодульВнешнейОбработкиДляОтладкиЛкс(БазовоеИмяВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля, ТекстМодуляВКонсолиНеМенялся, ДатаИзмененияВнешнейОбработки);
// Возврат Результат;
//Иначе
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ИмяФайлаВнешнейОбработки = ФайлВнешнейОбработкиДляОтладкиЛкс(БазовоеИмяВнешнейОбработки);
Если Не ЗначениеЗаполнено(ИмяФайлаВнешнейОбработки) Тогда
Возврат Ложь;
КонецЕсли;
ФайловыйКэшАлгоритмовДопускаетРедактирование = Истина;
ФайлВнешнейОбработки = Новый Файл(ИмяФайлаВнешнейОбработки);
Если ДатаИзмененияВнешнейОбработки <> Неопределено Тогда
Если Ложь
Или (Истина
И ФайлВнешнейОбработки.Существует()
И ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс() > ДатаИзмененияВнешнейОбработки
И ФайловыйКэшАлгоритмовДопускаетРедактирование)
Или (Истина
И ФайлВнешнейОбработки.Существует()
И ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс() = ДатаИзмененияВнешнейОбработки
И ТекстМодуляВКонсолиНеМенялся)
Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
мПлатформа.СформироватьВнешнююОбработку(ФайлВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля,,, ИспользоватьБыструюРаспаковку);
//// 19.01.2019 Для ВерсияАлгоритма в консоли кода
////ДатаИзмененияВнешнейОбработки = ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс();
//Если ЗначениеЗаполнено(ДатаИзмененияВнешнейОбработки) Тогда
// ФайлВнешнейОбработки.УстановитьВремяИзменения(ДатаИзмененияВнешнейОбработки);
//КонецЕсли;
Возврат Истина;
//КонецЕсли;
КонецФункции
// Получает идентификатор из любой строки.
// "3-я Дебиторка По контрагентам с интервалами СНГ (для Руководства)" => "_3_яДебиторкаПоКонтрагентамСИнтерваламиСНГ_дляРуководства_".
//
// Параметры:
// Представление - Строка.
//
// Возвращаемое значение:
// Строка.
//
Функция ИдентификаторИзПредставленияЛкс(Знач Представление = Неопределено, ЗаменаПустойСтроки = "_", ДопРазрешенныеСимволы = "") Экспорт
Если ПустаяСтрока(Представление) Тогда
Представление = ЗаменаПустойСтроки;
КонецЕсли;
Если Истина
И СокрЛП(Представление) = Представление
И Найти(Представление, ",") = 0
Тогда
Попытка
Пустышка = Новый Структура(Представление);
Возврат Представление;
Исключение КонецПопытки;
КонецЕсли;
НовоеПредставление = Представление;
ПервыйСимвол = Сред(Представление, 1, 1);
Если ЛиЦифраЛкс(ПервыйСимвол) Тогда
// Первый символ - цифра
НовоеПредставление = "_" + НовоеПредставление;
КонецЕсли;
ПредыдущийСимвол = " ";
ТекущаяСтрока = "";
ШаблонСимволаИдентификатора = ШаблонСимволаИдентификатораЛкс(ДопРазрешенныеСимволы);
Для Счетчик = 1 По СтрДлина(НовоеПредставление) Цикл
ТекущийСимвол = Сред(НовоеПредставление, Счетчик, 1);
Если ПустаяСтрока(ПредыдущийСимвол) Тогда
// Предыдущий символ - непечатаемый
ТекущийСимвол = ВРег(ТекущийСимвол);
КонецЕсли;
Если Найти(ШаблонСимволаИдентификатора, НРег(ТекущийСимвол)) > 0 Тогда
// Предыдущий символ - непечатаемый
ТекущаяСтрока = ТекущаяСтрока + ТекущийСимвол;
Иначе
Если Не ПустаяСтрока(ТекущийСимвол) Тогда
ТекущаяСтрока = ТекущаяСтрока + "_";
КонецЕсли;
КонецЕсли;
ПредыдущийСимвол = ТекущийСимвол;
КонецЦикла;
Результат = ТекущаяСтрока;
Возврат ТекущаяСтрока;
КонецФункции
Функция ШаблонСимволаИдентификатораЛкс(Знач ДопРазрешенныеСимволы = "") Экспорт
РусскиеБуквы = РусскиеБуквыЛкс();
ШаблонСимволаИдентификатора = НРег("_0123456789" + РусскиеБуквы + "abcdefghijklmnopqrstuvwxyz" + ДопРазрешенныеСимволы); // Русский и Ангийский
Возврат ШаблонСимволаИдентификатора;
КонецФункции
Функция РусскиеБуквыЛкс() Экспорт
РусскиеБуквы = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
Возврат РусскиеБуквы;
КонецФункции
Функция ЛиРусскаяБукваЛкс(Знач Символ)
Возврат Найти(РусскиеБуквыЛкс(), НРег(Символ)) > 0;
КонецФункции
Функция ФайлВнешнейОбработкиДляОтладкиЛкс(Знач ИмяВнешнейОбработки) Экспорт
КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс();
Если Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
СообщитьЛкс("В общих настройках инструментов не задан каталог объектов для отладки! Сохранение внешней обработки не выполнено.", СтатусСообщения.Внимание);
Возврат "";
КонецЕсли;
ИмяФайлаВнешнейОбработки = КаталогОбъектовДляОтладки + ИмяВнешнейОбработки + ".epf";
Возврат ИмяФайлаВнешнейОбработки;
КонецФункции
Процедура ЗаписатьДокументDOMВФайлЛкс(Знач ДокументДом, Знач ИмяФайла) Экспорт
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяФайла);
ЗаписьДом = Новый ЗаписьDOM;
ЗаписьДом.Записать(ДокументДом, ЗаписьXML);
ЗаписьXML.Закрыть();
КонецПроцедуры
Функция ЗаписатьДокументDOMВСтрокуЛкс(Знач ДокументДом) Экспорт
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("");
ЗаписьДом = Новый ЗаписьDOM;
ЗаписьДом.Записать(ДокументДом, ЗаписьXML);
Результат = ЗаписьXML.Закрыть();
Возврат Результат;
КонецФункции
Функция ПрочитатьФайлВДокументDOMЛкс(Знач ИмяФайла, ИгнорироватьПробельныеСимволы = Ложь) Экспорт
ЧтениеXML = Новый ЧтениеXML;
ПараметрыЧтения = Новый ПараметрыЧтенияXML(,,,,,,,, ИгнорироватьПробельныеСимволы);
ЧтениеXML.ОткрытьФайл(ИмяФайла, ПараметрыЧтения);
ПостроительДом = Новый ПостроительDOM();
ДокументДОМ = ПостроительДом.Прочитать(ЧтениеXML);
ЧтениеXML.Закрыть();
Возврат ДокументДОМ;
КонецФункции
Функция ПрочитатьТекстВДокументDOMЛкс(Знач Текст, ИгнорироватьПробельныеСимволы = Ложь) Экспорт
ЧтениеXML = Новый ЧтениеXML;
ПараметрыЧтения = Новый ПараметрыЧтенияXML(,,,,,,,, ИгнорироватьПробельныеСимволы);
ЧтениеXML.УстановитьСтроку(Текст, ПараметрыЧтения);
ПостроительDOM = Новый ПостроительDOM;
ДокументДом = ПостроительDOM.Прочитать(ЧтениеXML);
Возврат ДокументДом;
КонецФункции
Функция ДокументDOMИзСтрокиВнутрЛкс(ТекстФайла, ИгнорироватьПробельныеСимволы = Истина) Экспорт
XMLСтрока = СтрокаВнутрВХМЛТелоЛкс(ТекстФайла);
ДокументDOM = ПрочитатьТекстВДокументDOMЛкс(XMLСтрока, ИгнорироватьПробельныеСимволы);
Возврат ДокументDOM;
КонецФункции
Функция ЭтотРасширениеКонфигурацииЛкс() Экспорт
Результат = Неопределено;
Если Не ирОбщий.РежимСовместимостиМеньше8_3_4Лкс() Тогда
УстановитьПривилегированныйРежим(Истина);
Попытка
ЭтиРасширения = Вычислить("РасширенияКонфигурации").Получить(); // Антибаг платформы 8.3.10- исправлен в 8.3.11 https://partners.v8.1c.ru/forum/t/1607016/m/1607016
Исключение
Возврат Результат;
КонецПопытки;
ОтборРасширений = Новый Структура("Имя", ирОбщий.ИмяПродуктаЛкс());
ЭтиРасширения = Вычислить("РасширенияКонфигурации").Получить(ОтборРасширений);
Если ЭтиРасширения.Количество() > 0 Тогда
Результат = ЭтиРасширения[0];
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция АдаптироватьРасширениеЛкс(ИмяПользователя = "", ПарольПользователя = "", ВключатьНомерСтроки = Истина) Экспорт
#Если ТонкийКлиент Или ВебКлиент Тогда
Результат = ирСервер.АдаптироватьРасширениеЛкс();
Возврат Результат;
#КонецЕсли
ПометкиКоманд = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.ПометкиКоманд",, ирОбщий.ИмяПродуктаЛкс());
ПодключитьОтладкуВнешнихОбработокБСП = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.ПодключитьОтладкуВнешнихОбработокБСП",, ирОбщий.ИмяПродуктаЛкс());
//ПодключитьОтладкуОтчетов = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.ПодключитьОтладкуОтчетов",, ирОбщий.ИмяПродуктаЛкс());
ПодключитьОтладкуОтчетов = Ложь; // Теперь это делается через глобальную команду
//СгенерироватьРольВсеПрава = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.СгенерироватьРольВсеПрава",, ирОбщий.ИмяПродуктаЛкс());
СгенерироватьРольВсеПрава = Ложь; // Давать права на верхние объекты метаданных недостаточно. Поэтому отключил пока этот флажок
НадоДобавитьВсеСсылочныеМетаданнные = СгенерироватьРольВсеПрава;
Для Каждого КлючИЗначение Из ПометкиКоманд Цикл
Если КлючИЗначение.Значение Тогда
НадоДобавитьВсеСсылочныеМетаданнные = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
ЭтотРасширение = ЭтотРасширениеКонфигурацииЛкс();
#Если Сервер И Не Сервер Тогда
ЭтотРасширение = РасширенияКонфигурации.Создать();
#КонецЕсли
ИмяРасширения = ЭтотРасширение.Имя;
ТекстСпискаОбъектовКонфигурации = "";
Если НадоДобавитьВсеСсылочныеМетаданнные Тогда
ТипыСсылок = ирОбщий.ОписаниеТиповВсеСсылкиЛкс(Ложь).Типы();
#Если Сервер И Не Сервер Тогда
ТипыСсылок = Новый Массив;
#КонецЕсли
ТипыСсылокПлановОбмена = ПланыОбмена.ТипВсеСсылки().Типы();
// Сначала выгружаем из конфигурации все метаданные
//ТекстСпискаОбъектовКонфигурации = Метаданные.ПолноеИмя();
ДобавляемыеТипы = СкопироватьУниверсальнуюКоллекциюЛкс(ТипыСсылок);
#Если Сервер И Не Сервер Тогда
ДобавляемыеТипы = Новый Массив;
#КонецЕсли
Если СгенерироватьРольВсеПрава Тогда
ДобавляемыеТипыРегистров = Новый Массив;
ДобавляемыеТипыРегистров.Добавить("РегистрыСведений");
ДобавляемыеТипыРегистров.Добавить("РегистрыНакопления");
ДобавляемыеТипыРегистров.Добавить("РегистрыРасчета");
ДобавляемыеТипыРегистров.Добавить("РегистрыБухгалтерии");
ДобавляемыеТипыРегистров.Добавить("Последовательности");
Для Каждого ИмяКоллекцииРегистров Из ДобавляемыеТипыРегистров Цикл
Для Каждого ОбъектМД Из Метаданные[ИмяКоллекцииРегистров] Цикл
ДобавляемыеТипы.Добавить(Тип(СтрЗаменить(ОбъектМД.ПолноеИмя(), ".", "НаборЗаписей.")));
КонецЦикла;
КонецЦикла;
КонецЕсли;
Для Каждого Тип Из ДобавляемыеТипы Цикл
ОбъектМД = Метаданные.НайтиПоТипу(Тип);
ТекстСпискаОбъектовКонфигурации = ТекстСпискаОбъектовКонфигурации + Символы.ПС + ОбъектМД.ПолноеИмя();
КонецЦикла;
Для Каждого ОбъектМД Из Метаданные.ВнешниеИсточникиДанных Цикл
Если ОбъектМД.РасширениеКонфигурации() <> Неопределено Тогда
Продолжить;
КонецЕсли;
ТекстСпискаОбъектовКонфигурации = ТекстСпискаОбъектовКонфигурации + Символы.ПС + ОбъектМД.ПолноеИмя();
КонецЦикла;
КонецЕсли;
Если ПодключитьОтладкуВнешнихОбработокБСП И ирКэш.НомерВерсииБСПЛкс() >= 204 Тогда
ТекстСпискаОбъектовКонфигурации = ТекстСпискаОбъектовКонфигурации + Символы.ПС + Метаданные.ОбщиеМодули.ДополнительныеОтчетыИОбработки.ПолноеИмя();
КонецЕсли;
ПодключитьОтладкуОтчетов = ПодключитьОтладкуОтчетов И Метаданные.ОсновнаяФормаОтчета <> Неопределено И Метаданные.ОсновнаяФормаОтчета.РасширениеКонфигурации() = Неопределено;
Если ПодключитьОтладкуОтчетов Тогда
ТекстСпискаОбъектовКонфигурации = ТекстСпискаОбъектовКонфигурации + Символы.ПС + Метаданные.ОсновнаяФормаОтчета.ПолноеИмя();
КонецЕсли;
ТекстСпискаОбъектовКонфигурации = Сред(ТекстСпискаОбъектовКонфигурации, 2); // !
ИмяФайлаСпискаВыгрузкиКонфигурации = ПолучитьИмяВременногоФайла("txt");
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ТекстСпискаОбъектовКонфигурации);
ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиКонфигурации);
КаталогВыгрузкиКонфигурации = ПолучитьИмяВременногоФайла();
СоздатьКаталог(КаталогВыгрузкиКонфигурации);
ТекстЛога = "";
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиКонфигурации + """ -listFile """ + ИмяФайлаСпискаВыгрузкиКонфигурации + """ -Format Plain",
СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка конфигурации в файлы",,,, ИмяПользователя, ПарольПользователя);
УдалитьФайлы(ИмяФайлаСпискаВыгрузкиКонфигурации);
Если Не Успех Тогда
УдалитьФайлы(КаталогВыгрузкиКонфигурации);
СообщитьЛкс(ТекстЛога);
Возврат Ложь;
КонецЕсли;
// Выгружаем объекты из расширения
КаталогВыгрузкиРасширения = ПолучитьИмяВременногоФайла();
ИмяФайлаСпискаВыгрузкиРасширения = ПолучитьИмяВременногоФайла("txt");
ТекстЛога = "";
СоздатьКаталог(КаталогВыгрузкиРасширения);
ТекстСпискаОбъектовРасширения = "Конфигурация." + ИмяРасширения;
Для Каждого КлючИЗначение Из ПометкиКоманд Цикл
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + "ОбщаяКоманда." + КлючИЗначение.Ключ;
КонецЦикла;
ТекстовыйДокумент.УстановитьТекст(ТекстСпискаОбъектовРасширения);
ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиРасширения);
// Пришлось отказаться от частичной загрузки из-за непонятной ошибки
// Файл - Configuration.xml: ошибка частичной загрузки - идентификатор 15dc941a-fd9f-4d00-bc7e-3ef077518def загружаемой конфигурации отличается от идентификатора b9c0a797-9739-4c3f-a665-796b3bf92d6a сохраненной конфигурации
//Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -listFile """ + ИмяФайлаСпискаВыгрузкиРасширения + """ -Format Plain",
// СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка расширения в файлы");
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -Format Plain",
СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка расширения в файлы",,,, ИмяПользователя, ПарольПользователя);
Если Не Успех Тогда
УдалитьФайлы(КаталогВыгрузкиРасширения);
СообщитьЛкс(ТекстЛога);
Возврат Ложь;
КонецЕсли;
// Добавим ссылочные объекты в расширение
ИмяФайла = КаталогВыгрузкиРасширения + РазделительПутиКФайлуЛкс() + "Configuration.xml";
ОписаниеРасширения = Новый ТекстовыйДокумент;
ОписаниеРасширения.Прочитать(ИмяФайла);
ОписаниеРасширения = ОписаниеРасширения.ПолучитьТекст();
ДокументДОМ = ирОбщий.ПрочитатьФайлВДокументDOMЛкс(ИмяФайла);
УзелТиповСпискаОбъектов = ДокументДом.ПолучитьЭлементыПоИмени("ChildObjects");
УзелТиповСпискаОбъектов = УзелТиповСпискаОбъектов[0];
Если НадоДобавитьВсеСсылочныеМетаданнные Тогда
Если СгенерироватьРольВсеПрава Тогда
ТекстФайлаПрав = Новый ЗаписьXML;
ТекстФайлаПрав.УстановитьСтроку("");
ТекстФайлаПрав.ЗаписатьБезОбработки("
|
| true
| true
| false ");
КонецЕсли;
ДобавленныеВнешниеИсточникиДанных = Новый Соответствие;
Для Каждого Тип Из ДобавляемыеТипы Цикл
ПолноеИмяМДXML = XMLТип(Тип).ИмяТипа;
Если Ложь
Или Найти(ПолноеИмяМДXML, "RoutePointRef.") > 0
Тогда
Продолжить;
КонецЕсли;
ЭтоТаблицаВИД = Найти(ПолноеИмяМДXML, "ExternalDataSourceTableRef.") > 0;
Если ЭтоТаблицаВИД Тогда
Фрагменты = СтрРазделитьЛкс(ПолноеИмяМДXML);
Фрагменты[0] = "ExternalDataSource";
Фрагменты.Вставить(2, "Table");
МассивТаблицВИД = ДобавленныеВнешниеИсточникиДанных[Фрагменты[1]];
Если МассивТаблицВИД = Неопределено Тогда
МассивТаблицВИД = Новый Массив;
ДобавленныеВнешниеИсточникиДанных.Вставить(Фрагменты[1], МассивТаблицВИД);
КонецЕсли;
ПолноеИмяМДXML = СтрСоединитьЛкс(Фрагменты, ".");
КонецЕсли;
ПолноеИмяМДXML = СтрЗаменить(ПолноеИмяМДXML, "Ref.", ".");
ПолноеИмяМДXML = СтрЗаменить(ПолноеИмяМДXML, "RecordSet.", ".");
// Добавим в описание конфигурации (Configuration.xml)
ОбъектМД = Метаданные.НайтиПоТипу(Тип);
Если Не ЭтоТаблицаВИД Тогда
ИмяКлассаМДXML = ПервыйФрагментЛкс(ПолноеИмяМДXML);
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + ОбъектМД.ПолноеИмя();
Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + ОбъектМД.Имя + "<") > 0 Тогда
Продолжить;
КонецЕсли;
УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML);
УзелОбъекта.ТекстовоеСодержимое = ОбъектМД.Имя;
УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта);
Иначе
МассивТаблицВИД.Добавить(ОбъектМД.Имя);
ИмяКлассаМДXML = "Table";
КонецЕсли;
// Укажем принадлежность объекта в его описании
ФайлИсточник = Новый Файл(КаталогВыгрузкиКонфигурации + РазделительПутиКФайлуЛкс() + ПолноеИмяМДXML + ".xml");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + РазделительПутиКФайлуЛкс() + ФайлИсточник.Имя);
//ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя);
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "", "" + ИмяКлассаМДXML + ">", Ложь, Истина, Истина);
НаЧтоЗаменять =
"
| " + ирОбщий.ПоследнийФрагментЛкс(ФайлИсточник.ИмяБезРасширения) + "
| Adopted
|
|
| " + ИмяКлассаМДXML + ">";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМДXML + " uuid=", ">", Ложь, Истина, Истина);
НаЧтоЗаменять = "<" + ИмяКлассаМДXML + " uuid=""" + Новый УникальныйИдентификатор + """>";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ТекстовыйДокумент.УстановитьТекст(ТекстФайла);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
Если СгенерироватьРольВсеПрава Тогда
Если Истина
И Найти(ПолноеИмяМДXML, "Enum.") = 0
Тогда
// Даем права Просмотр и ПросмотрИстории
ТекстФайлаПрав.ЗаписатьБезОбработки("
| ");
КонецЕсли;
КонецЕсли;
КонецЦикла;
Для Каждого КлючИЗначение Из ДобавленныеВнешниеИсточникиДанных Цикл
ПолноеИмяМДXML = "ExternalDataSource." + КлючИЗначение.Ключ;
ИмяКлассаМДXML = ПервыйФрагментЛкс(ПолноеИмяМДXML);
// Добавим в описание конфигурации (Configuration.xml)
ОбъектМД = Метаданные.ВнешниеИсточникиДанных[КлючИЗначение.Ключ];
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + ОбъектМД.ПолноеИмя();
Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + ОбъектМД.Имя + "<") > 0 Тогда
Продолжить;
КонецЕсли;
УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML);
УзелОбъекта.ТекстовоеСодержимое = ОбъектМД.Имя;
УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта);
// Укажем принадлежность объекта в его описании
ФайлИсточник = Новый Файл(КаталогВыгрузкиКонфигурации + РазделительПутиКФайлуЛкс() + ПолноеИмяМДXML + ".xml");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + РазделительПутиКФайлуЛкс() + ФайлИсточник.Имя);
//ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя);
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "", "" + ИмяКлассаМДXML + ">", Ложь, Истина, Истина);
НаЧтоЗаменять =
"
| " + ирОбщий.ПоследнийФрагментЛкс(ФайлИсточник.ИмяБезРасширения) + "
| Adopted
|
|
| " + ИмяКлассаМДXML + ">";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМДXML + " uuid=", ">", Ложь, Истина, Истина);
НаЧтоЗаменять = "<" + ИмяКлассаМДXML + " uuid=""" + Новый УникальныйИдентификатор + """>";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ДокументДомВИД = ирОбщий.ПрочитатьТекстВДокументDOMЛкс(ТекстФайла);
УзелТиповСпискаДочернихОбъектов = ДокументДомВИД.ПолучитьЭлементыПоИмени("ChildObjects");
УзелТиповСпискаДочернихОбъектов = УзелТиповСпискаДочернихОбъектов[0];
Для Каждого ИмяТаблицы Из КлючИЗначение.Значение Цикл
УзелОбъекта = ДокументДомВИД.СоздатьЭлемент("Table");
УзелОбъекта.ТекстовоеСодержимое = ИмяТаблицы;
УзелТиповСпискаДочернихОбъектов.ДобавитьДочерний(УзелОбъекта);
КонецЦикла;
ирОбщий.ЗаписатьДокументDOMВФайлЛкс(ДокументДомВИД, ФайлПриемник.ПолноеИмя);
КонецЦикла;
Если СгенерироватьРольВсеПрава Тогда
// Добавим в описание конфигурации (Configuration.xml)
ИмяКлассаМДXML = "Role";
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + "Роль.ирВсеПрава";
Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + "ирВсеПрава" + "<") = 0 Тогда
УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML);
УзелОбъекта.ТекстовоеСодержимое = "ирВсеПрава";
УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта);
КонецЕсли;
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + РазделительПутиКФайлуЛкс() + ИмяКлассаМДXML + ".ирВсеПрава.xml");
ТекстФайла = "
|
|
|
| ирВсеПрава
|
|
| ru
| Все права (ИР)
|
|
| Сгенерирована инструментом ""Адаптация расширения"" для доступа на просмотр ко всем данным
|
|
| ";
ТекстовыйДокумент.УстановитьТекст(ТекстФайла);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + РазделительПутиКФайлуЛкс() + ИмяКлассаМДXML + ".ирВсеПрава.Rights.xml");
ТекстФайлаПрав.ЗаписатьБезОбработки("
| ");
ТекстовыйДокумент.УстановитьТекст(ТекстФайлаПрав.Закрыть());
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
КонецЕсли;
КонецЕсли;
Если ПодключитьОтладкуВнешнихОбработокБСП И ирКэш.НомерВерсииБСПЛкс() >= 204 Тогда
ИмяОбъектаОригинала = "ДополнительныеОтчетыИОбработки";
ИмяОбъектаРасширения = "ирДополнительныеОтчетыИОбработкиБСП";
// Добавим в описание конфигурации (Configuration.xml)
ИмяКлассаМДXML = "CommonModule";
ОбъектМД = Метаданные.ОбщиеМодули[ИмяОбъектаОригинала];
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + ОбъектМД.ПолноеИмя();
Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + ОбъектМД.Имя + "<") = 0 Тогда
УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML);
УзелОбъекта.ТекстовоеСодержимое = ОбъектМД.Имя;
УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта);
// Укажем принадлежность объекта в его описании
ФайлИсточник = Новый Файл(КаталогВыгрузкиКонфигурации + РазделительПутиКФайлуЛкс() + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".xml");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + РазделительПутиКФайлуЛкс() + ФайлИсточник.Имя);
//ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя);
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "", "" + ИмяКлассаМДXML + ">", Ложь, Истина, Истина);
НаЧтоЗаменять =
"
| " + ИмяОбъектаОригинала + "
| Adopted
|
| " + ИмяКлассаМДXML + ">";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМДXML + " uuid=", ">", Ложь, Истина, Истина);
НаЧтоЗаменять = "<" + ИмяКлассаМДXML + " uuid=""" + Новый УникальныйИдентификатор + """>";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ТекстовыйДокумент.УстановитьТекст(ТекстФайла);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
КонецЕсли;
ФайлИсточник = Новый Файл(КаталогВыгрузкиРасширения + РазделительПутиКФайлуЛкс() + ИмяКлассаМДXML + "." + ИмяОбъектаРасширения + ".Module.txt");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + РазделительПутиКФайлуЛкс() + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".Module.txt");
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
КонецЕсли;
Если ПодключитьОтладкуОтчетов И Метаданные.ОсновнаяФормаОтчета <> Неопределено Тогда
ИмяОбъектаОригинала = Метаданные.ОсновнаяФормаОтчета.Имя;
ИмяОбъектаРасширения = Метаданные.ОбщиеФормы.ирФормаОтчетаРасширение.Имя;
// Добавим в описание конфигурации (Configuration.xml)
ИмяКлассаМДXML = "CommonForm";
ОбъектМД = Метаданные.ОбщиеФормы[ИмяОбъектаОригинала];
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + ОбъектМД.ПолноеИмя();
Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + ОбъектМД.Имя + "<") = 0 Тогда
УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML);
УзелОбъекта.ТекстовоеСодержимое = ОбъектМД.Имя;
УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта);
// Укажем принадлежность объекта в его описании
ФайлИсточник = Новый Файл(КаталогВыгрузкиКонфигурации + РазделительПутиКФайлуЛкс() + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".xml");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + РазделительПутиКФайлуЛкс() + ФайлИсточник.Имя);
//ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя);
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "", "" + ИмяКлассаМДXML + ">", Ложь, Истина, Истина);
НаЧтоЗаменять =
"
| " + ИмяОбъектаОригинала + "
| Adopted
| Managed
|
| " + ИмяКлассаМДXML + ">";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМДXML + " uuid=", ">", Ложь, Истина, Истина);
НаЧтоЗаменять = "<" + ИмяКлассаМДXML + " uuid=""" + Новый УникальныйИдентификатор + """>";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ТекстовыйДокумент.УстановитьТекст(ТекстФайла);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
КонецЕсли;
// Модуль
ФайлИсточник = Новый Файл(КаталогВыгрузкиРасширения + РазделительПутиКФайлуЛкс() + ИмяКлассаМДXML + "." + ИмяОбъектаРасширения + ".Form.Module.txt");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + РазделительПутиКФайлуЛкс() + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".Form.Module.txt");
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
// Диалог
ФайлИсточник = Новый Файл(КаталогВыгрузкиРасширения + РазделительПутиКФайлуЛкс() + ИмяКлассаМДXML + "." + ИмяОбъектаРасширения + ".Form.xml");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + РазделительПутиКФайлуЛкс() + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".Form.xml");
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
ЧтоЗаменять = "";
НаЧтоЗаменять = "";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ЧтоЗаменять = "";
НаЧтоЗаменять = " ";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять, Истина);
ТекстовыйДокумент.УстановитьТекст(ТекстФайла);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
КонецЕсли;
ирОбщий.ЗаписатьДокументDOMВФайлЛкс(ДокументДом, ИмяФайла);
// Добавим типы ссылочных объектов в общие команды
#Если Сервер И Не Сервер Тогда
ТипыСсылок = Новый ОписаниеТипов;
#КонецЕсли
Для Каждого КлючИЗначение Из ПометкиКоманд Цикл
ИмяКоманды = КлючИЗначение.Ключ;
ИмяФайла = КаталогВыгрузкиРасширения + РазделительПутиКФайлуЛкс() + "CommonCommand." + ИмяКоманды + ".xml";
ДокументДОМ = ирОбщий.ПрочитатьФайлВДокументDOMЛкс(ИмяФайла);
УзелТиповПараметра = ДокументДом.ПолучитьЭлементыПоИмени("CommandParameterType");
УзелТиповПараметра = УзелТиповПараметра[0];
Пока УзелТиповПараметра.ДочерниеУзлы.Количество() > 0 Цикл
УзелТиповПараметра.УдалитьДочерний(УзелТиповПараметра.ПервыйДочерний);
КонецЦикла;
Если КлючИЗначение.Значение Тогда
Если ИмяКоманды = Метаданные.ОбщиеКоманды.ирРедактироватьИзмененияНаУзле.Имя Тогда
ТипыПараметра = ТипыСсылокПлановОбмена;
Иначе
ТипыПараметра = ТипыСсылок;
КонецЕсли;
Для Каждого Тип Из ТипыПараметра Цикл
УзелТипа = ДокументДом.СоздатьЭлемент("v8:Type"); // http://v8.1c.ru/8.1/data/core
УзелТипа.ТекстовоеСодержимое = "cfg:" + XMLТип(Тип).ИмяТипа; // http://v8.1c.ru/8.1/data/enterprise/current-config
УзелТиповПараметра.ДобавитьДочерний(УзелТипа);
КонецЦикла;
КонецЕсли;
ирОбщий.ЗаписатьДокументDOMВФайлЛкс(ДокументДом, ИмяФайла);
КонецЦикла;
ТекстЛога = "";
// Пришлось отказаться от частичной загрузки из-за непонятной ошибки
// Файл - Configuration.xml: ошибка частичной загрузки - идентификатор 15dc941a-fd9f-4d00-bc7e-3ef077518def загружаемой конфигурации отличается от идентификатора b9c0a797-9739-4c3f-a665-796b3bf92d6a сохраненной конфигурации
//ФайлыДляЗагрузки = НайтиФайлы(КаталогВыгрузкиРасширения, "*");
//ТекстовыйДокумент.Очистить();
//Для Каждого Файл Из ФайлыДляЗагрузки Цикл
// ТекстовыйДокумент.ДобавитьСтроку(Файл.ПолноеИмя);
//КонецЦикла;
//ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиРасширения);
//Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadConfigFromFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -listFile """ + ИмяФайлаСпискаВыгрузкиРасширения + """ -Format Plain",
// СтрокаСоединенияИнформационнойБазы(), ТекстЛога,,, "Загрузка расширения из файлов");
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadConfigFromFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -Format Plain",
СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Загрузка расширения из файлов",,,, ИмяПользователя, ПарольПользователя);
УдалитьФайлы(КаталогВыгрузкиРасширения);
Если Не Успех Тогда
СообщитьЛкс(ТекстЛога);
Возврат Ложь;
КонецЕсли;
// Почему то без этого расширение не применялось (оставалась активной кнопка "Обновить конфигурацию БД"
//ЭтотРасширение.Записать();
КонечныйФайл = ПолучитьИмяВременногоФайла();
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpCfg """ + КонечныйФайл + """ -Extension """ + ИмяРасширения + """", СтрокаСоединенияИнформационнойБазы(), ТекстЛога,,,,,, ИмяПользователя, ПарольПользователя);
Если Не Успех Тогда
СообщитьЛкс(ТекстЛога);
Возврат Ложь;
КонецЕсли;
ЭтотРасширение.Записать(Новый ДвоичныеДанные(КонечныйФайл));
Возврат Истина;
КонецФункции
Функция ПредставлениеКлючаСтрокиБДЛкс(Знач КлючСтроки, ПолучатьПредставленияСсылок = Истина) Экспорт
Если ТипЗнч(КлючСтроки) = Тип("Строка") Тогда
ПредставленияКлюча = КлючСтроки;
Иначе
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(КлючСтроки));
Если ОбъектМД = Неопределено Тогда
// https://www.hostedredmine.com/issues/947191
ПредставленияКлюча = КлючСтроки;
Иначе
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
Если ЛиКлючЗаписиРегистраЛкс(КлючСтроки) Тогда
СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяМД, , Ложь, Ложь);
ПредставленияКлюча = "";
Для Каждого ЭлементСписка Из СтруктураКлюча Цикл
Если ПредставленияКлюча <> "" Тогда
ПредставленияКлюча = ПредставленияКлюча + ", ";
КонецЕсли;
ПредставлениеЗначения = КлючСтроки[ЭлементСписка.Представление];
Если Не ПолучатьПредставленияСсылок И ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ПредставлениеЗначения) Тогда
ПредставлениеЗначения = "" + ИдентификаторСсылкиЛкс(ПредставлениеЗначения);
Иначе
ПредставлениеЗначения = "" + ПредставлениеЗначения;
КонецЕсли;
ПредставленияКлюча = ПредставленияКлюча + ЭлементСписка.Представление + " = " + ПредставлениеЗначения;
КонецЦикла;
ИначеЕсли ЛиКорневойТипКонстантыЛкс(ПервыйФрагментЛкс(ПолноеИмяМД)) Тогда
ПредставленияКлюча = ПолноеИмяМД;
Иначе
ПредставленияКлюча = "" + КлючСтроки;
//СтруктураЧтения = Новый Структура("Владелец");
//Попытка
// ЗаполнитьЗначенияСвойств(СтруктураЧтения, КлючСтроки);
//Исключение
// // Нет доступа
//КонецПопытки;
//Если ЗначениеЗаполнено(СтруктураЧтения.Владелец) Тогда
// Если ПолучатьПредставленияСсылок Тогда
// Владелец = Владелец.УникальныйИдентификатор();
// КонецЕсли;
// ПредставленияКлюча = "[" + ПредставлениеКлючаСтрокиБДЛкс(Владелец) + "]" + ПредставленияКлюча;
//КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ПредставленияКлюча;
КонецФункции
Процедура ПроверитьСоздатьКаталогПередСозданиемФайлаЛкс(Знач ИмяКонфигурационногоФайла) Экспорт
Файл = Новый Файл(ИмяКонфигурационногоФайла);
ФайлКаталога = Новый Файл(Файл.Путь);
Если Не ФайлКаталога.Существует() Тогда
СоздатьКаталог(ФайлКаталога.ПолноеИмя);
КонецЕсли;
КонецПроцедуры
Функция КаталогПрограммныхФайловОСЛкс(Знач x64 = Неопределено) Экспорт
ПеременныеОкружения = ирКэш.ПеременныеОкруженияПроцессаЛкс();
Если ирКэш.Это64битнаяОСЛкс() Тогда
Если x64 = Неопределено Тогда
x64 = ирКэш.Это64битныйПроцессЛкс();
КонецЕсли;
Если x64 Тогда
ИмяПеременной = "ProgramW6432";
Иначе
ИмяПеременной = "ProgramFiles(x86)";
КонецЕсли;
Иначе
ИмяПеременной = "ProgramFiles";
КонецЕсли;
КаталогПрограммныхФайлов = ПеременныеОкружения.Item(ИмяПеременной);
Возврат КаталогПрограммныхФайлов;
КонецФункции
Функция КаталогПеремещаемыхДанныхПриложенийЛкс() Экспорт
ПеременныеОкружения = ирКэш.ПеременныеОкруженияПроцессаЛкс();
КаталогПеремещаемыхДанныхПриложений = ПеременныеОкружения.Item("Appdata");
Возврат КаталогПеремещаемыхДанныхПриложений;
КонецФункции
Функция ПараметрыСоединенияADOЭтойБДЛкс(выхСтрокаСвойств = "") Экспорт
выхСтрокаСвойств = "ИмяСервера, ИмяБД, ИмяПользователя, Пароль, НаСервере, СобиратьТрассу, ТипСУБД";
Результат = Новый Структура(выхСтрокаСвойств);
Результат.ИмяСервера = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.ИмяСервера");
Результат.ИмяБД = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.ИмяБД");
Результат.ИмяПользователя = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.ИмяПользователя");
Результат.СобиратьТрассу = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.СобиратьТрассу");
Результат.ТипСУБД = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.ТипСУБД");
Если Результат.ТипСУБД = Неопределено Тогда
Результат.ТипСУБД = "MSSQL";
КонецЕсли;
НовыйПароль = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.Пароль");
Если НовыйПароль <> Неопределено Тогда
Результат.Пароль = НовыйПароль.Получить();
КонецЕсли;
Результат.НаСервере = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.НаСервере");
Возврат Результат;
КонецФункции
Функция ПроверитьСоединениеADOЭтойБДЛкс(Знач ИмяСервера = "", Знач ИмяБД = "", Знач ИмяПользователя = "", Знач Пароль = "", Знач НаСервере = Неопределено, ЗапрашиватьПараметрыПодключения = Истина,
Асинхронно = Ложь, выхСоединение = Неопределено, Знач ТипСУБД = "MSSQL") Экспорт
КоличествоПопыток = 1;
НачальнаяПопытка = 1;
Если ЗапрашиватьПараметрыПодключения Тогда
КоличествоПопыток = 2;
Если Не ЗначениеЗаполнено(ИмяСервера) Тогда
ПараметрыСоединения = ПараметрыСоединенияADOЭтойБДЛкс();
Если Не ЗначениеЗаполнено(ПараметрыСоединения.ИмяСервера) Тогда
НачальнаяПопытка = 2;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Для НомерПопытки = НачальнаяПопытка По КоличествоПопыток Цикл
Если НомерПопытки = 2 Тогда
#Если Клиент Тогда
ФормаПодключения = ОткрытьФормуСоединенияСУБДЛкс(Истина);
Если ФормаПодключения = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Если НаСервере = Неопределено Тогда
НаСервере = ФормаПодключения.НаСервере;
КонецЕсли;
#Иначе
СообщитьЛкс("Необходимо с клиента выполнить проверку установки соединения с СУБД");
Возврат Ложь;
#КонецЕсли
Иначе
Если НаСервере = Неопределено Тогда
Если ПараметрыСоединения = Неопределено Тогда
ПараметрыСоединения = ПараметрыСоединенияADOЭтойБДЛкс();
КонецЕсли;
НаСервере = ПараметрыСоединения.НаСервере;
КонецЕсли;
КонецЕсли;
Если НомерПопытки = 2 И Не ЗначениеЗаполнено(ИмяСервера) Тогда
ЛиСоединениеУстановлено = Ложь;
ИначеЕсли НаСервере = Истина Тогда
ЛиСоединениеУстановлено = ирСервер.ПроверитьСоединениеADOЭтойБДЛкс(ИмяСервера, ИмяБД, ИмяПользователя, Пароль, Асинхронно, ТипСУБД);
Если ЛиСоединениеУстановлено Тогда
выхСоединение = "Готов";
КонецЕсли;
Иначе
выхСоединение = ПолучитьСоединениеСУБД(ИмяСервера, ИмяБД, ИмяПользователя, Пароль, Асинхронно, ТипСУБД);
ЛиСоединениеУстановлено = выхСоединение <> Неопределено;
КонецЕсли;
Если ЛиСоединениеУстановлено Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Возврат ЛиСоединениеУстановлено;
КонецФункции
Функция ВыполнитьЗапросКЭтойБазеЧерезADOЛкс(Знач ТекстЗапроса, Знач РежимОтладки = Ложь, Знач ПредставлениеЗапроса = "", Знач СмещениеГода = 2000, Знач ИспользованиеGWF = Истина,
Знач НаСервере = Неопределено, СоединениеADO = Неопределено, БинарныеВСтроку = Истина) Экспорт
ТребоватьТипЛкс(ТекстЗапроса, "ТекстЗапроса", Тип("Строка"));
Если РежимОтладки Тогда
ирОбщий.ОткрытьЗапросСУБДЛкс(ТекстЗапроса, ПредставлениеЗапроса);
Возврат Неопределено;
КонецЕсли;
#Если Клиент Тогда
Если Истина
И СоединениеADO = Неопределено
И НаСервере = Неопределено
Тогда
НаСервере = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.НаСервере");
КонецЕсли;
#КонецЕсли
Если НаСервере = Истина Тогда
Таблица = ирСервер.ВыполнитьЗапросКЭтойБазеЧерезADOЛкс(ТекстЗапроса, СмещениеГода, ИспользованиеGWF);
Иначе
Если СоединениеADO = Неопределено Тогда
СоединениеADO = ПолучитьСоединениеСУБД();
Если СоединениеADO = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
//КомандаADO = Новый COMОбъект("ADODB.Command");
//КомандаADO.CommandTimeout = 30; // секунд
//КомандаADO.CommandText = ТекстЗапроса;
//КомандаADO.CommandType = 1;
//КомандаADO.ActiveConnection = мСоединениеADO;
//Если РежимОтладки = 1 Тогда
// ирОбщий.ОтладитьЛкс(КомандаADO);
// Возврат Неопределено;
//КонецЕсли;
//РезультатЗапроса = КомандаADO.Execute();
РезультатЗапроса = Новый COMОбъект("ADODB.Recordset");
adOpenStatic = 3;
adLockOptimistic = 3;
adCmdText = 1;
РезультатЗапроса.Open(ТекстЗапроса, СоединениеADO, adOpenStatic, adLockOptimistic, adCmdText);
Если РезультатЗапроса.State = 1 Тогда
Таблица = ирОбщий.РезультатЗапросаADOВТаблицуЗначенийОбщийЛкс(РезультатЗапроса, , БинарныеВСтроку, , СмещениеГода, ИспользованиеGWF);
КонецЕсли;
КонецЕсли;
Возврат Таблица;
КонецФункции
//Функция получает на вход текст html, из которого создает COM объект HtmlFile
//Параметры
// ТекстHtml - Строка. Текст в формате HTML
// ПереопределятьБазу - используется только при УстановитьБазу = Истина
//Возвращаемое значение
//COM объект с типом HtmlFile
Функция ПолучитьHtmlFileИзТекстаHtmlЛкс(ТекстHtml = "", Результат = Неопределено) Экспорт
Если Результат = Неопределено Тогда
Результат = Новый COMОбъект("HtmlFile");
КонецЕсли;
Результат.open("text/html");
Результат.write(ТекстHtml);
Результат.close();
Возврат Результат;
КонецФункции
Функция ПолучитьHtmlТекстВыделенияЛкс(ДокументHtml) Экспорт
Результат = "";
Если ДокументHtml.getSelection() <> Неопределено Тогда
Выделение = ДокументHtml.getSelection();
Если Выделение.rangeCount > 0 Тогда
ЭлементDiv = ДокументHtml.createElement("div");
Для Счетчик = 0 по Выделение.rangeCount - 1 Цикл
ЭлементDiv.appendChild(Выделение.getRangeAt(Счетчик).cloneContents());
КонецЦикла;
Результат = ЭлементDiv.innerHTML;
КонецЕсли;
ИначеЕсли ДокументHtml.selection <> Неопределено Тогда
//Если ДокументHtml.selection.type = "Text" Тогда
// Результат = ДокументHtml.selection.createRange().htmlText;
//КонецЕсли;
Результат = ДокументHtml.selection.CreateRange().htmlText;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОбработатьПорциюСтрокТаблицыЛкс(АдресТаблицыЗначений, НачальныйНомерСтроки, РазмерПорции, МодальныйРежим = Ложь, ПропускатьОшибки = Ложь, ТекстАлгоритма, ПараметраАлгоритмы = Неопределено, ПерейтиНаСервер = Ложь) Экспорт
Если ПерейтиНаСервер Тогда
ирСервер.ОбработатьПорциюСтрокТаблицыЛкс(АдресТаблицыЗначений, НачальныйНомерСтроки, РазмерПорции, МодальныйРежим, ПропускатьОшибки, ТекстАлгоритма, ПараметраАлгоритмы);
Возврат Неопределено;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
ТаблицаЗначений = ПолучитьИзВременногоХранилища(АдресТаблицыЗначений);
КоличествоСтрокТаблицы = ТаблицаЗначений.Количество();
Для НомерСтроки = НачальныйНомерСтроки По Мин(НачальныйНомерСтроки + РазмерПорции - 1, ТаблицаЗначений.Количество()) Цикл
СтрокаТаблицы = ТаблицаЗначений[НомерСтроки - 1];
Попытка
ирОбщий.ВыполнитьАлгоритм(ТекстАлгоритма,,, ПараметраАлгоритмы, СтрокаТаблицы, НомерСтроки = 1, НомерСтроки = КоличествоСтрокТаблицы);
Исключение
Если Не ПропускатьОшибки Тогда
ВызватьИсключение
КонецЕсли;
ирОбщий.СообщитьСУчетомМодальностиЛкс("Строка результата №" + НомерСтроки + ": " + ОписаниеОшибки(), МодальныйРежим);
КонецПопытки;
КонецЦикла;
КонецФункции
Процедура ПаузаЛкс(ЧислоСекунд) Экспорт
ПаузаМиллисекундЛкс(ЧислоСекунд*1000);
КонецПроцедуры
Процедура ПаузаМиллисекундЛкс(Число) Экспорт
Попытка
ВК = ирОбщий.ВКОбщаяЛкс();
ВК.Sleep(Число);
Исключение
// Антибаг платформы 8.3 https://www.hostedredmine.com/issues/889213
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
Функция ФоновыеЗаданияПотоковЛкс()
Отбор = Новый Структура;
Отбор.Вставить("Состояние", СостояниеФоновогоЗадания.Активно);
#Если Сервер И Не Сервер Тогда
ирОбщий.ОбработатьПорциюОбъектовЛкс();
#КонецЕсли
Отбор.Вставить("ИмяМетода", "ирОбщий.ОбработатьПорциюОбъектовЛкс");
Найденные = ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор);
Возврат Найденные;
КонецФункции
// Используется иногда долгая функция ПолучитьСеансыИнформационнойБазы()
Функция СеансКонфигуратора() Экспорт
Сеансы = ПолучитьСеансыИнформационнойБазы(); // Иногда выполняется долго
Для Каждого Сеанс Из Сеансы Цикл
Если СтрокиРавныЛкс(Сеанс.ИмяПриложения, "Designer") Тогда
Возврат Сеанс;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Функция ПростойРезультатЗапросаЛкс(ТекстЗапроса, АдресХранилища = Неопределено) Экспорт
Если ЗначениеЗаполнено(ТекстЗапроса) Тогда
ЗапросКоличестваСтрок = Новый Запрос(ТекстЗапроса);
Результат = ЗапросКоличестваСтрок.Выполнить().Выгрузить()[0][0];
Иначе
Результат = 0;
КонецЕсли;
Если ЗначениеЗаполнено(АдресХранилища) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресХранилища);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция КоличествоСтрокВТаблицеМДЛкс(ПолноеИмяМД, АдресВременногоХранилища = "") Экспорт
Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда
Возврат "";
КонецЕсли;
ПолноеИмяТаблицы = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,,, Истина);
Если Не ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда
Возврат Неопределено;
КонецЕсли;
КоличествоСтрок = КоличествоСтрокВТаблицеБДЛкс(ПолноеИмяТаблицы);
Если ЗначениеЗаполнено(АдресВременногоХранилища) Тогда
ПоместитьВоВременноеХранилище(КоличествоСтрок, АдресВременногоХранилища);
КонецЕсли;
Возврат КоличествоСтрок;
КонецФункции
// Функция - Количество строк в таблице БДЛкс
//
// Параметры:
// ПолноеИмяТаблицыИлиЗапрос - Текст, Запрос - имя таблицы или запрос
// Отбор - Отбор - Используется только когда передано имя таблицы
//
// Возвращаемое значение:
// - Запрос
//
Функция КоличествоСтрокВТаблицеБДЛкс(Знач ПолноеИмяТаблицыИлиЗапрос, Знач Отбор = Неопределено) Экспорт
Если ТипЗнч(ПолноеИмяТаблицыИлиЗапрос) = Тип("Строка") Тогда
ПолноеИмяТаблицы = ПолноеИмяТаблицыИлиЗапрос;
Если Отбор = Неопределено Тогда
ЗапросКоличестваСтрок = Новый Запрос("ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ " + ПолноеИмяТаблицы);
КоличествоСтрок = ЗапросКоличестваСтрок.Выполнить().Выгрузить()[0][0];
Иначе
ИмяСлужебногоПоля = "СлужебноеПоле" + СуффиксСлужебногоСвойстваЛкс();
ТекстЗапроса = "ВЫБРАТЬ Т.*, 0 КАК " + ИмяСлужебногоПоля + " ИЗ " + ПолноеИмяТаблицы + " КАК Т";
СхемаКомпоновки = ирОбщий.СоздатьСхемуКомпоновкиПоЗапросу(ТекстЗапроса);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, Отбор);
//ирОбщий.СкопироватьПорядокЛюбойЛкс(НастройкаКомпоновки.Порядок, НастройкиСписка.Порядок);
ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ИмяСлужебногоПоля);
Запрос = ЗапросИзКомпоновкиЛкс(СхемаКомпоновки, НастройкаКомпоновки,,,,, Ложь);
#Если Сервер И Не Сервер Тогда
Запрос = Новый Запрос;
#КонецЕсли
Запрос.Текст = СтрЗаменитьЛкс(Запрос.Текст, "0 КАК " + ИмяСлужебногоПоля, "РАЗРЕШЕННЫЕ КОЛИЧЕСТВО(*) КАК КоличествоСтрок");
КоличествоСтрок = Запрос.Выполнить().Выгрузить()[0][0];
КонецЕсли;
Иначе
Запрос = ПолноеИмяТаблицыИлиЗапрос;
КоличествоСтрок = КоличествоСтрокВРезультатеЗапросаЛкс(Запрос);
КонецЕсли;
Возврат КоличествоСтрок;
КонецФункции
Процедура ВыделитьПервыеСтрокиДинамическогоСпискаЛкс(Знач ТабличноеПоле, Знач Количество, Знач НастройкиСписка = Неопределено) Экспорт
ДинамическийСписок = ирОбщий.ДанныеЭлементаФормыЛкс(ТабличноеПоле);
ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле);
СхемаКомпоновки = ирОбщий.СоздатьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицы,,,,,,, Количество);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
Если НастройкиСписка = Неопределено Тогда
НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДинамическийСписок);
КонецЕсли;
ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, НастройкиСписка.Отбор);
ирОбщий.СкопироватьПорядокЛюбойЛкс(НастройкаКомпоновки.Порядок, НастройкиСписка.Порядок);
СтруктураКлюча = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы,, Ложь);
Для Каждого ЭлементСписка Из СтруктураКлюча Цикл
ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ЭлементСписка.Представление);
КонецЦикла;
КлючиСтрок = ирОбщий.СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки);
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КлючиСтрок.Количество(), "Выделение");
Для Каждого КлючСтроки Из КлючиСтрок Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
ВыделенныеСтроки.Добавить(ирОбщий.КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, КлючСтроки));
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Если КлючиСтрок.Количество() <> Количество Тогда
СообщитьЛкс(СтрШаблонИменЛкс("Выделены все отобранные элементы, но меньшим количеством %1",, КлючиСтрок.Количество()));
КонецЕсли;
#Если Клиент Тогда
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
ТабличноеПоле.ОбновитьСтроки();
КонецЕсли;
#КонецЕсли
КонецПроцедуры
// Если в текущей строке не достаточно полей для заполнения ключа записи регистра, то всегда возвращается набор записей, не смотря на параметр ДляРегистровСоздатьНаборЗаписей.
// Параметры:
// СтруктураКлюча - Структура - для ускорения в циклах;
// ОбъектМД - ОбъектМетаданных - для ускорения в циклах;
Функция КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, Знач ТекущаяСтрока, ДляНабораЗаписейРегистраСведений = Ложь, выхСтруктураЛокальногоКлючаСтроки = Неопределено,
ОбъектыНаСервере = Неопределено, СтруктураКлюча = Неопределено, ОбъектМД = Неопределено) Экспорт
ИмяПоляСсылка = ирОбщий.ПеревестиСтроку("Ссылка");
ИмяПоляНомерСтроки = ирОбщий.ПеревестиСтроку("НомерСтроки");
ИмяПоляПериод = ирОбщий.ПеревестиСтроку("Период");
ТипТаблицы = ТипТаблицыБДЛкс(ПолноеИмяТаблицы);
Если СтруктураКлюча = Неопределено Тогда
СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы,,, ДляНабораЗаписейРегистраСведений);
КонецЕсли;
#Если Сервер И Не Сервер Тогда
СтруктураКлюча = Новый Структура;
#КонецЕсли
Если СтруктураКлюча.Свойство(ИмяПоляНомерСтроки) Тогда
выхСтруктураЛокальногоКлючаСтроки = Новый Структура(ИмяПоляНомерСтроки);
ИначеЕсли СтруктураКлюча.Свойство(ИмяПоляПериод) Тогда
выхСтруктураЛокальногоКлючаСтроки = Новый Структура(ИмяПоляПериод);
Иначе
выхСтруктураЛокальногоКлючаСтроки = Неопределено;
КонецЕсли;
Если выхСтруктураЛокальногоКлючаСтроки <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(выхСтруктураЛокальногоКлючаСтроки, ТекущаяСтрока);
КонецЕсли;
ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы);
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.ВнешниеИсточникиДанных.ВнешнийИсточникДанных1.Таблицы.Таблица1;
#КонецЕсли
Если Ложь
Или ирОбщий.ЛиМетаданныеСсылочногоОбъектаЛкс(ОбъектМД)
Или ЛиКорневойТипЖурналаДокументовЛкс(ТипТаблицы)
Тогда
Если ирОбщий.ЛиТипСсылкиБДЛкс(ТипЗнч(ТекущаяСтрока), Ложь) Тогда
КлючОбъекта = ТекущаяСтрока;
Иначе
КлючОбъекта = ТекущаяСтрока[ИмяПоляСсылка];
КонецЕсли;
ПолноеИмяТаблицы = Метаданные.НайтиПоТипу(ТипЗнч(КлючОбъекта)).ПолноеИмя();
ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
КлючОбъекта = ТекущаяСтрока[ИмяПоляСсылка];
ИначеЕсли ирОбщий.ЛиМетаданныеРегистраЛкс(ОбъектМД, Ложь) Тогда
Если Не ДляНабораЗаписейРегистраСведений Тогда
НайденыВсеПоляКлючаЗаписи = Истина;
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
Попытка
Пустышка = ТекущаяСтрока[КлючИЗначение.Ключ];
Исключение
НайденыВсеПоляКлючаЗаписи = Ложь;
Прервать;
КонецПопытки;
КонецЦикла;
КонецЕсли;
ЗаполнитьЗначенияСвойств(СтруктураКлюча, ТекущаяСтрока);
Если Ложь
Или ДляНабораЗаписейРегистраСведений
Или Не НайденыВсеПоляКлючаЗаписи
Тогда
//КлючОбъекта = ПолучитьНаборЗаписейПоКлючуЛкс(ПолноеИмяТаблицы, ТекущаяСтрока);
УдаляемыеКлючи = Новый Массив;
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
Если ТипЗнч(КлючИЗначение.Значение) = Тип("ОписаниеТипов") Тогда
УдаляемыеКлючи.Добавить(КлючИЗначение.Ключ);
КонецЕсли;
КонецЦикла;
Для Каждого УдаляемыйКлюч Из УдаляемыеКлючи Цикл
СтруктураКлюча.Удалить(УдаляемыйКлюч);
КонецЦикла;
КлючОбъекта = ОбъектБДПоКлючуЛкс(ПолноеИмяТаблицы, СтруктураКлюча,, Ложь, ОбъектыНаСервере);
Иначе
Если ОбъектМД = Неопределено Тогда
ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы);
КонецЕсли;
МенеджерРегистра = Новый (ИмяТипаИзПолногоИмениМДЛкс(ОбъектМД.ПолноеИмя(), "Менеджер"));
КлючОбъекта = МенеджерРегистра.СоздатьКлючЗаписи(СтруктураКлюча);
КонецЕсли;
ИначеЕсли ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы) Тогда
ЗаполнитьЗначенияСвойств(СтруктураКлюча, ТекущаяСтрока);
КлючОбъекта = Новый Структура("ПолноеИмяТаблицы, Структура", ПолноеИмяТаблицы, СтруктураКлюча);
Иначе
КлючОбъекта = Неопределено;
КонецЕсли;
Возврат КлючОбъекта;
КонецФункции
Функция СообщенияПользователюОтФоновогоЗаданияЛкс(Знач ФоновоеЗадание, УдалятьПолученные = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ФоновоеЗадание = ФоновыеЗадания.Выполнить();
#КонецЕсли
СообщенияПользователю = ФоновоеЗадание.ПолучитьСообщенияПользователю(УдалятьПолученные);
// Антибаг платформы 8.2.14
Если СообщенияПользователю = Неопределено Тогда
СообщенияПользователю = Новый Массив;
КонецЕсли;
Возврат СообщенияПользователю;
КонецФункции
Функция СоединитьСообщенияПользователюЛкс(Знач СообщенияОбъекта) Экспорт
СообщенияОбработки = Новый ЗаписьXML;
СообщенияОбработки.УстановитьСтроку("");
Для Каждого СообщениеОбъекта Из СообщенияОбъекта Цикл
#Если Сервер И Не Сервер Тогда
СообщениеОбъекта = Новый СообщениеПользователю;
#КонецЕсли
СообщенияОбработки.ЗаписатьБезОбработки(СообщениеОбъекта.Текст + Символы.ПС);
КонецЦикла;
ТекстСообщений = СообщенияОбработки.Закрыть();
Возврат ТекстСообщений;
КонецФункции
Функция ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание, ЭтаФорма = Неопределено, ПодключитьОбработчикОтменыЗадания = Истина, ФормаЗадания = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору();
#КонецЕсли
ИдентификаторФоновогоЗадания = ФоновоеЗадание.УникальныйИдентификатор;
#Если Клиент Тогда
Если ПодключитьОбработчикОтменыЗадания Тогда
#Если Сервер И Не Сервер Тогда
ОтменитьФоновоеЗаданиеОтложенноЛкс();
#КонецЕсли
ПодключитьОбработчикОжиданияСПараметрамиЛкс("ОтменитьФоновоеЗаданиеОтложенноЛкс", Новый Структура("ИдентификаторФоновогоЗадания", ИдентификаторФоновогоЗадания));
КонецЕсли;
СостояниеЛкс("Выполняем фоновое задание", Истина);
#КонецЕсли
Если ЭтаФорма <> Неопределено Тогда
ПрефиксКлючаПотока = ПрефиксКлючаПотокаЛкс(ЭтаФорма);
КонецЕсли;
ПериодОбновленияФормы = 2;
МоментОбновления = ТекущаяДата() - ПериодОбновленияФормы;
Пока Истина Цикл
#Если Клиент Тогда
ОбработкаПрерыванияПользователя();
#КонецЕсли
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторФоновогоЗадания);
Если ТекущаяДата() - МоментОбновления >= ПериодОбновленияФормы Тогда
ОбработатьСообщенияФоновогоЗаданияЛкс(ФоновоеЗадание, ФормаЗадания, ПрефиксКлючаПотока, Ложь);
Если ФормаЗадания <> Неопределено Тогда
ФормаЗадания.ОбновитьСостояниеЗадания(ФоновоеЗадание);
КонецЕсли;
МоментОбновления = ТекущаяДата();
КонецЕсли;
Если ФоновоеЗадание.Состояние <> СостояниеФоновогоЗадания.Активно Тогда
Прервать;
КонецЕсли;
ПаузаМиллисекундЛкс(100);
КонецЦикла;
#Если Клиент Тогда
ОтлючитьГлобальныйОбработчикОжиданияСПараметрамиЛкс();
#КонецЕсли
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда
ИнформацияОбОшибке = ФоновоеЗадание.ИнформацияОбОшибке;
ТекстСообщения = "Фоновое задание завершено аварийно! Описание ошибки получить не удалось";
#Если Клиент Тогда
Если ИнформацияОбОшибке <> Неопределено Тогда
ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке);
Иначе
СообщитьЛкс(ТекстСообщения, СтатусСообщения.Внимание);
КонецЕсли;
#Иначе
Если ИнформацияОбОшибке <> Неопределено Тогда
ВызватьИсключение ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке);
Иначе
ВызватьИсключение ТекстСообщения;
КонецЕсли;
#КонецЕсли
Результат = Ложь;
Иначе
Результат = Истина;
КонецЕсли;
Возврат Результат;
КонецФункции
// Функция - Обработать сообщения фонового задания лкс
//
// Параметры:
// ФоновоеЗадание - -
//
// Возвращаемое значение:
// - Булево - был ли изменен текст состояния
//
Функция ОбработатьСообщенияФоновогоЗаданияЛкс(Знач ФоновоеЗадание, ФормаЗадания = Неопределено, ПрефиксКлючаПотока = "", АсинхронныйРежим = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору();
#КонецЕсли
Результат = Ложь;
СообщенияПользователю = СообщенияПользователюОтФоновогоЗаданияЛкс(ФоновоеЗадание, Истина);
Если СообщенияПользователю <> Неопределено Тогда
ТекстСостояния = "";
МаркерПотока = "#Поток ";
РазделительМаркера = ": ";
Для Каждого СообщениеПользователю Из СообщенияПользователю Цикл
#Если Сервер И Не Сервер Тогда
СообщениеПользователю = Новый СообщениеПользователю;
#КонецЕсли
ТекстСообщения = СообщениеПользователю.Текст;
НомерПотока = Неопределено;
Если СтрНачинаетсяСЛкс(ТекстСообщения, МаркерПотока) Тогда
НомерПотока = СтрокаМеждуМаркерамиЛкс(ТекстСообщения, МаркерПотока, РазделительМаркера, Ложь,, Истина);
ТекстСообщения = Сред(ТекстСообщения, Найти(ТекстСообщения, РазделительМаркера) + СтрДлина(РазделительМаркера));
КонецЕсли;
МассивИндикаторов = Неопределено;
Если СтрНачинаетсяСЛкс(ТекстСообщения, "#Индикатор-") Тогда
МассивИндикаторов = ЗначениеИзСтрокиВнутрЛкс(ирОбщий.СтрокаМеждуМаркерамиЛкс(СообщениеПользователю.Текст, "#Индикатор-"));
КонецЕсли;
Если МассивИндикаторов = Неопределено Тогда
Если ФормаЗадания <> Неопределено Тогда
ТекстовыйДокумент = ФормаЗадания.ЭлементыФормы.ПолеТекста;
ТекстовыйДокумент.ДобавитьСтроку(СообщениеПользователю.Текст);
ПолеТекста = ирОбщий.ОболочкаПоляТекстаЛкс(ТекстовыйДокумент);
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ПолеТекста.ПоказатьПоследнююСтроку();
Иначе
СообщитьЛкс(СообщениеПользователю.Текст,, Истина);
СообщениеПользователю.Сообщить();
КонецЕсли;
Иначе
Индикатор = ОбновитьТекстСостоянияВсехИндикаторовЛкс(МассивИндикаторов);
Если НомерПотока = Неопределено Тогда
ТекстСостояния = Индикатор.ТекстСостояния;
ИначеЕсли ФормаЗадания <> Неопределено Тогда
СтрокаПотока = ФормаЗадания.Потоки.Найти(НомерПотока, "НомерПотока");
Если СтрокаПотока = Неопределено Тогда
СтрокаПотока = ФормаЗадания.Потоки.Добавить();
СтрокаПотока.НомерПотока = НомерПотока;
КонецЕсли;
СтрокаПотока.Состояние = Индикатор.ТекстСостояния;
КонецЕсли;
КонецЕсли;
КонецЦикла;
#Если Сервер И Не Сервер Тогда
ирОбщий.ОбработатьПорциюОбъектовЛкс()
#КонецЕсли
Если ЗначениеЗаполнено(ТекстСостояния) Тогда
Если АсинхронныйРежим И ФормаЗадания <> Неопределено Тогда
ФормаЗадания.Заголовок = ТекстСостояния;
//ФормаЗадания.Обновить(); // Не дает эффекта в синхронном режиме
Иначе
СостояниеЛкс(ТекстСостояния, Истина);
КонецЕсли;
Результат = Истина;
КонецЕсли;
КонецЕсли;
Если Истина
И ФормаЗадания <> Неопределено
И ФормаЗадания.Потоки.Количество() > 0
Тогда
ФоновыеПотоки = ФоновыеЗаданияПотоковЛкс();
НачальноеКоличество = ФормаЗадания.Потоки.Количество();
Для Счетчик = 1 По НачальноеКоличество Цикл
СтрокаПотока = ФормаЗадания.Потоки[НачальноеКоличество - Счетчик];
ФоновоеЗаданиеПотокаАктивно = Ложь;
Для Каждого ФоновыйПоток Из ФоновыеПотоки Цикл
#Если Сервер И Не Сервер Тогда
ФоновыйПоток = ФоновыеЗадания.Выполнить();
#КонецЕсли
Если ФоновыйПоток.Ключ = ПрефиксКлючаПотока + "." + СтрокаПотока.НомерПотока Тогда
ФоновоеЗаданиеПотокаАктивно = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ФоновоеЗаданиеПотокаАктивно Тогда
ФормаЗадания.Потоки.Удалить(СтрокаПотока);
КонецЕсли;
КонецЦикла;
ФормаЗадания.Обновить();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПредставлениеПериодаЛкс(НачалоПериода, КонецПериода) Экспорт
ПредставлениеОтбора = "";
Если ЗначениеЗаполнено(НачалоПериода) Тогда
ПредставлениеОтбора = ПредставлениеОтбора + " с " + НачалоПериода;
КонецЕсли;
Если ЗначениеЗаполнено(КонецПериода) Тогда
Если Формат(НачалоПериода, "ДФ=dd.MM.yyyy") = Формат(КонецПериода, "ДФ=dd.MM.yyyy") Тогда
Строка = Формат(КонецПериода, "ДЛФ=T");
Иначе
Строка = "" + КонецПериода;
КонецЕсли;
ПредставлениеОтбора = ПредставлениеОтбора + " по " + Строка;
КонецЕсли;
Возврат ПредставлениеОтбора;
КонецФункции
Функция СтруктураХраненияОсновнойТаблицыМДЛкс(Знач ПолноеИмяМД)
//СтруктураХраненияПолей = ирКэш.СтруктураХраненияБДЛкс().НайтиСтроки(Новый Структура("Назначение, Метаданные", "Основная", ПолноеИмяМД))[0].Поля;
ФильтрМетаданных = Новый Массив;
ФильтрМетаданных.Добавить(ПолноеИмяМД);
СтруктураХраненияТаблиц = ПолучитьСтруктуруХраненияБазыДанных(ФильтрМетаданных);
ПеревестиКолонкиСтруктурыХраненияБДТаблицыЛкс(СтруктураХраненияТаблиц);
СтруктураХраненияТаблицы = СтруктураХраненияТаблиц.НайтиСтроки(Новый Структура("Назначение, Метаданные", ПеревестиСтроку("Основная"), ПолноеИмяМД))[0];
ПеревестиКолонкиСтруктурыХраненияБДПоляЛкс(СтруктураХраненияТаблицы.Поля);
Возврат СтруктураХраненияТаблицы;
КонецФункции
Функция ОсновнойПорядокТаблицыБДЛкс(Знач ПолноеИмяТаблицы, Знач СтрокаПорядка = "", Знач НастройкаПорядка = Неопределено, Знач СтруктураХраненияТаблицы = Неопределено,
Знач СортироватьДатыПоУбыванию = Ложь) Экспорт
Построитель = Новый ПостроительЗапроса("ВЫБРАТЬ * ИЗ " + ПолноеИмяТаблицы + " КАК Т");
ТипТаблицы = ирОбщий.ТипТаблицыБДЛкс(ПолноеИмяТаблицы);
Если СтруктураХраненияТаблицы = Неопределено Тогда
ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы);
Если ОбъектМД = Неопределено Или ТипТаблицы = "Внешняя" Или ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
Возврат Построитель;
КонецЕсли;
СтруктураХраненияТаблицы = СтруктураХраненияОсновнойТаблицыМДЛкс(ОбъектМД.ПолноеИмя());
КонецЕсли;
выхСортировкаПоДате = Ложь;
Построитель.ЗаполнитьНастройки();
ПорядокТаблицы = Построитель.Порядок;
Если Не ЗначениеЗаполнено(СтрокаПорядка) Тогда
ПредопределенныеПоля = Новый Массив();
Если ТипТаблицы = "ПланСчетов" Тогда
ПредопределенныеПоля.Добавить(ПеревестиСтроку("Код"));
КонецЕсли;
ПредопределенныеПоля.Добавить(ПеревестиСтроку("Наименование"));
ПредопределенныеПоля.Добавить(ПеревестиСтроку("Дата"));
ПредопределенныеПоля.Добавить(ПеревестиСтроку("Период"));
ПредопределенныеПоля.Добавить("ДатаИзменения");
ПредопределенныеПоля.Добавить("ДатаСоздания");
ПредопределенныеПоля.Добавить(ПеревестиСтроку("Номер"));
ПредопределенныеПоля.Добавить(ПеревестиСтроку("Код"));
ПеревестиКолонкиСтруктурыХраненияБДИндексыЛкс(СтруктураХраненияТаблицы.Индексы);
Для Каждого ПредопределенноеПоле Из ПредопределенныеПоля Цикл
Если НастройкаПорядка <> Неопределено Тогда
ЭлементПорядка = НастройкаПорядка.Найти(ПредопределенноеПоле);
Если ЭлементПорядка = Неопределено Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Для Каждого ИндексТаблицыБД Из СтруктураХраненияТаблицы.Индексы Цикл
ПеревестиКолонкиСтруктурыХраненияБДПоляЛкс(ИндексТаблицыБД.Поля);
Если ИндексТаблицыБД.Поля[0].ИмяПоля = ПредопределенноеПоле Тогда
Если ЭлементПорядка <> Неопределено Тогда
ЭлементПорядка.Доступность = Истина;
КонецЕсли;
СтрокаПорядка = ПредопределенноеПоле;
Прервать;
КонецЕсли;
КонецЦикла;
Если Истина
И ЗначениеЗаполнено(СтрокаПорядка)
И (НастройкаПорядка = Неопределено Или ЭлементПорядка.Доступность)
Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЗначениеЗаполнено(СтрокаПорядка) Тогда
ПорядокТаблицы.Установить(СтрокаПорядка);
Если СортироватьДатыПоУбыванию Тогда
ЭлементПорядкаТипаДата = ЭлементПорядкаТипаДатаЛкс(ПолноеИмяТаблицы, ПорядокТаблицы);
Если ЭлементПорядкаТипаДата <> Неопределено Тогда
ЭлементПорядкаТипаДата.Направление = НаправлениеСортировки.Убыв;
КонецЕсли;
КонецЕсли;
КонецЕсли;
//Возврат ПорядокТаблицы; // Так возвращается пустой порядок всегда
Возврат Построитель;
КонецФункции
Функция ЭлементПорядкаТипаДатаЛкс(Знач ПолноеИмяТаблицы, Знач ПорядокТаблицы) Экспорт
#Если Сервер И Не Сервер Тогда
ПорядокТаблицы = Новый ПостроительЗапроса;
ПорядокТаблицы = ПорядокТаблицы.Порядок;
#КонецЕсли
Если Истина
И ПорядокТаблицы.Количество() > 0
И ирКэш.ПоляТаблицыБДЛкс(ПолноеИмяТаблицы).Найти(ПорядокТаблицы[0].Имя, "Имя").ТипЗначения.СодержитТип(Тип("Дата"))
Тогда
ЭлементПорядкаТипаДата = ПорядокТаблицы[0];
КонецЕсли;
Возврат ЭлементПорядкаТипаДата;
КонецФункции
Процедура ПоместитьПереданныйКэшВоВременноеХранищеЛкс(Знач ОбщиеПараметрыОбработки)
#Если Сервер И Не Сервер Тогда
ОбщиеПараметрыОбработки = Новый Структура;
#КонецЕсли
Если ОбщиеПараметрыОбработки.Свойство("_Кэш") Тогда
ирКэш.ПараметрыСеансаЛкс().ПереданныйКэш = ПоместитьВоВременноеХранилище(ОбщиеПараметрыОбработки._Кэш, Новый УникальныйИдентификатор);
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьПереданныйКэшВСтруктуруЛкс(Знач Структура)
#Если Сервер И Не Сервер Тогда
Структура = Новый Структура;
#КонецЕсли
ТаблицаВсехТаблицБД = ирОбщий.ТаблицаВсехТаблицБДБезОжиданияЛкс();
Если ТаблицаВсехТаблицБД <> Неопределено Тогда
Структура.Вставить("_Кэш", Новый Структура("ТаблицаВсехТаблицБД", ТаблицаВсехТаблицБД));
КонецЕсли;
КонецПроцедуры
////////////////////////////////////////////////
// Многопоточность
Функция НоваяСтруктураМногопоточнойОбработкиЛкс(Знач ИмяОбработчикаОбъекта, Знач МодульОбработчика, Знач ИмяОбработчикаРезультатаОбъекта, Знач КоличествоОбъектовВПорции,
Знач КоличествоПотоков, Знач ОбщиеПараметрыОбработкиОдногоОбъекта = Неопределено, Знач ВыводитьСообщения = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
МодульОбработчика = Обработки.ирПодборИОбработкаОбъектов.Создать();
#КонецЕсли
ПотокиОбработки = Новый ТаблицаЗначений;
ПотокиОбработки.Колонки.Добавить("АдресРезультата");
ПотокиОбработки.Колонки.Добавить("СтрокиРезультатовОбъектов");
ПотокиОбработки.Колонки.Добавить("УникальныйИдентификатор");
ДоступностьМногопоточности = Истина
И ирКэш.ЭтоФоновоеЗаданиеЛкс()
И Не ирКэш.ЛиФайловаяБазаЛкс()
И Не ирКэш.ЛиПортативныйРежимЛкс();
Для Счетчик = 1 По Макс(1, КоличествоПотоков) Цикл
Если Счетчик > 1 И Не ДоступностьМногопоточности Тогда
Прервать;
КонецЕсли;
ПотокиОбработки.Добавить();
КонецЦикла;
Если ОбщиеПараметрыОбработкиОдногоОбъекта = Неопределено Тогда
ОбщиеПараметрыОбработкиОдногоОбъекта = Новый Структура();
Для Каждого МетаРеквизит Из МодульОбработчика.Метаданные().Реквизиты Цикл
ЗначениеРеквизита = МодульОбработчика[МетаРеквизит.Имя];
Если Ложь
Или ТипЗнч(ЗначениеРеквизита) = Тип("Строка")
Или ТипЗнч(ЗначениеРеквизита) = Тип("Булево")
Или ТипЗнч(ЗначениеРеквизита) = Тип("Дата")
Или ТипЗнч(ЗначениеРеквизита) = Тип("Число")
Тогда
ОбщиеПараметрыОбработкиОдногоОбъекта.Вставить(МетаРеквизит.Имя, ЗначениеРеквизита);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Статистика = Новый ТаблицаЗначений;
Статистика.Колонки.Добавить("Длительность");
СтруктураПотоков = Новый Структура;
СтруктураПотоков.Вставить("ПорцияОбъектов", Неопределено);
СтруктураПотоков.Вставить("ПотокиОбработки", ПотокиОбработки);
СтруктураПотоков.Вставить("Статистика", Статистика);
СтруктураПотоков.Вставить("ФактическоеКоличествоПотоков", ПотокиОбработки.Количество());
СтруктураПотоков.Вставить("КоличествоОбъектовВПорции", КоличествоОбъектовВПорции);
СтруктураПотоков.Вставить("МодульОбработчика", МодульОбработчика);
СтруктураПотоков.Вставить("ОбщиеПараметрыОбработкиОдногоОбъекта", ОбщиеПараметрыОбработкиОдногоОбъекта);
СтруктураПотоков.Вставить("ИмяОбработчикаРезультатаОбъекта", ИмяОбработчикаРезультатаОбъекта);
СтруктураПотоков.Вставить("ИмяОбработчикаОбъекта", ИмяОбработчикаОбъекта);
СтруктураПотоков.Вставить("ВыводитьСообщения", ВыводитьСообщения);
Возврат СтруктураПотоков;
КонецФункции
// Добавить объект в очередь многопоточной обработки
//
// Параметры:
// СтруктураПотоков - -
// ПараметрыОбработкиОбъекта - Структура - передавайте сюда защищенные экземпляры (копии) коллекций, чтобы при возвращении результата порции они остались неизменными
// СтрокиРезультатовОбъекта - -
// ПринудительноВОсновномПотоке - -
//
Процедура ДобавитьОбъектВОчередьМногопоточнойОбработкиЛкс(СтруктураПотоков, ПараметрыОбработкиОбъекта, СтрокиРезультатовОбъекта = Неопределено, ПринудительноВОсновномПотоке = Ложь) Экспорт
МодульОбработчика = СтруктураПотоков.МодульОбработчика;
Если Ложь
Или СтруктураПотоков.ФактическоеКоличествоПотоков = 1
Или ПринудительноВОсновномПотоке
Тогда
РезультатОбработки = Вычислить("МодульОбработчика." + СтруктураПотоков.ИмяОбработчикаОбъекта + "(ПараметрыОбработкиОбъекта)");
Выполнить("МодульОбработчика." + СтруктураПотоков.ИмяОбработчикаРезультатаОбъекта + "(РезультатОбработки, СтрокиРезультатовОбъекта)");
Возврат;
КонецЕсли;
ПорцияОбъектов = СтруктураПотоков.ПорцияОбъектов;
Если ПорцияОбъектов = Неопределено Тогда
ПорцияОбъектов = Новый Структура("ПараметрыОбработкиОбъектов, СтрокиРезультатовОбъектов", Новый Массив, Новый Массив);
СтруктураПотоков.ПорцияОбъектов = ПорцияОбъектов;
КонецЕсли;
ПорцияОбъектов.ПараметрыОбработкиОбъектов.Добавить(ПараметрыОбработкиОбъекта);
ПорцияОбъектов.СтрокиРезультатовОбъектов.Добавить(СтрокиРезультатовОбъекта);
Если ПорцияОбъектов.ПараметрыОбработкиОбъектов.Количество() < СтруктураПотоков.КоличествоОбъектовВПорции Тогда
Возврат;
КонецЕсли;
ЗапуститьПотокОбработкиПорцииЛкс(СтруктураПотоков);
КонецПроцедуры
Процедура ОжидатьЗавершенияВсехПотоковОбработкиЛкс(СтруктураПотоков) Экспорт
Если СтруктураПотоков.ПорцияОбъектов <> Неопределено Тогда
ЗапуститьПотокОбработкиПорцииЛкс(СтруктураПотоков);
КонецЕсли;
Пока ОбновитьПотокиОбработкиОбъектовЛкс(СтруктураПотоков, Ложь).Количество() < СтруктураПотоков.ПотокиОбработки.Количество() Цикл
ПаузаМиллисекундЛкс(100);
КонецЦикла;
Если СтруктураПотоков.ВыводитьСообщения И СтруктураПотоков.ПотокиОбработки.Количество() > 1 Тогда
СообщитьСтатистикуПорцийСРекомендациями(СтруктураПотоков, Истина);
КонецЕсли;
КонецПроцедуры
Процедура СообщитьСтатистикуПорцийСРекомендациями(Знач СтруктураПотоков, ВыводитьСтатистикуОбязательно = Ложь)
Статистика = СтруктураПотоков.Статистика;
Если Статистика.Количество() = 0 Тогда
// Все потоки завершились неуспешно
СуммарнаяДлительность = 0;
СредняяДлительностьПорции = 0;
Иначе
СуммарнаяДлительность = Статистика.Итог("Длительность");
СредняяДлительностьПорции = Окр(СуммарнаяДлительность / Статистика.Количество(), 1);
КонецЕсли;
ТекстСообщения = СтрШаблонИменЛкс("Обработано %1 порций в %2 потоков. Средняя длительность порции - %3с",
1, Статистика.Количество(), 2, СтруктураПотоков.ФактическоеКоличествоПотоков, 3, СредняяДлительностьПорции);
Если СтруктураПотоков.КоличествоОбъектовВПорции > 1 И СредняяДлительностьПорции > 5 Тогда
ТекстСообщения = ТекстСообщения + ". Рекомендуется уменьшить количество объектов в порции.";
ИначеЕсли СуммарнаяДлительность > 1 И СредняяДлительностьПорции < 1 Тогда
ТекстСообщения = ТекстСообщения + ". Рекомендуется увеличить количество объектов в порции.";
ИначеЕсли СуммарнаяДлительность = 0 Или Не ВыводитьСтатистикуОбязательно Тогда
Возврат;
КонецЕсли;
ирОбщий.СообщитьЛкс(ТекстСообщения);
КонецПроцедуры
Процедура ЗапуститьПотокОбработкиПорцииЛкс(Знач СтруктураПотоков)
//ФоновыеЗадания.ОжидатьЗавершенияВыполнения() // Не позволяет ждать одного из
Пока Истина Цикл
НомераСвободныхПотоков = ОбновитьПотокиОбработкиОбъектовЛкс(СтруктураПотоков);
Если НомераСвободныхПотоков.Количество() > 0 Тогда
Прервать;
КонецЕсли;
ПаузаМиллисекундЛкс(5);
КонецЦикла;
ПорцияОбъектов = СтруктураПотоков.ПорцияОбъектов;
НомерСвободногоПотока = НомераСвободныхПотоков[0];
ПотокиОбработки = СтруктураПотоков.ПотокиОбработки;
ПотокиОбработки[НомерСвободногоПотока].СтрокиРезультатовОбъектов = ПорцияОбъектов.СтрокиРезультатовОбъектов;
АдресРезультата = ПоместитьВоВременноеХранилище(Null);
ПараметрыЗадания = Новый Массив(5);
ПолноеИмяМодуля = СтруктураПотоков.МодульОбработчика.Метаданные().ПолноеИмя();
ПараметрыЗадания[0] = ПолноеИмяМодуля;
ПараметрыЗадания[1] = СтруктураПотоков.ИмяОбработчикаОбъекта;
ПараметрыЗадания[2] = СтруктураПотоков.ОбщиеПараметрыОбработкиОдногоОбъекта;
ПараметрыЗадания[3] = ПорцияОбъектов.ПараметрыОбработкиОбъектов;
ПараметрыЗадания[4] = АдресРезультата;
//ДобавитьПереданныйКэшВСтруктуруЛкс(СтруктураПотоков.ОбщиеПараметрыОбработкиОдногоОбъекта);
#Если Сервер И Не Сервер Тогда
ирОбщий.ОбработатьПорциюОбъектовЛкс();
#КонецЕсли
ДобавитьТекущемуПользователюРолиИРЛкс();
ПрефиксКлючаПотока = ПрефиксКлючаПотокаЛкс(СтруктураПотоков.МодульОбработчика);
ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ОбработатьПорциюОбъектовЛкс", ПараметрыЗадания, ПрефиксКлючаПотока + "." + НомерСвободногоПотока, "Поток обработки объектов " + НомерСвободногоПотока);
ПотокиОбработки[НомерСвободногоПотока].АдресРезультата = АдресРезультата;
ПотокиОбработки[НомерСвободногоПотока].УникальныйИдентификатор = ФоновоеЗадание.УникальныйИдентификатор;
СтруктураПотоков.ПорцияОбъектов = Неопределено;
КонецПроцедуры
Функция ПрефиксКлючаПотокаЛкс(Знач ОбработкаОбъект)
Возврат ОбработкаОбъект.Метаданные().ПолноеИмя() + ".";
КонецФункции
Процедура ОбработатьПорциюОбъектовЛкс(ПолноеИмяМД, ИмяОбработчикаОбъекта, ОбщиеПараметрыОбработки, ПараметрыМетода, АдресРезультата) Экспорт
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = СоздатьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД);
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирПодборИОбработкаОбъектов.Создать()
#КонецЕсли
ЗагрузитьРеквизитыОбработкиЛкс(Обработка, ОбщиеПараметрыОбработки);
РезультатПорции = Новый Массив;
Для Каждого ПараметрыВызова Из ПараметрыМетода Цикл
РезультатПорции.Добавить(Вычислить("Обработка." + ИмяОбработчикаОбъекта + "(ПараметрыВызова)"));
КонецЦикла;
ПоместитьВоВременноеХранилище(РезультатПорции, АдресРезультата);
КонецПроцедуры
Функция ОбновитьПотокиОбработкиОбъектовЛкс(СтруктураПотоков, ОбновлятьДоПервогоСвободного = Истина)
ПотокиОбработки = СтруктураПотоков.ПотокиОбработки;
Статистика = СтруктураПотоков.Статистика;
НомераСвободныхПотоков = Новый Массив;
МодульОбработчика = СтруктураПотоков.МодульОбработчика;
Для Каждого ПотокОбработки Из СтруктураПотоков.ПотокиОбработки Цикл
Если ЗначениеЗаполнено(ПотокОбработки.УникальныйИдентификатор) Тогда
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ПотокОбработки.УникальныйИдентификатор);
Если СтруктураПотоков.ВыводитьСообщения Тогда
СообщенияПользователю = СообщенияПользователюОтФоновогоЗаданияЛкс(ФоновоеЗадание, Истина);
Для Каждого СообщениеПользователю Из СообщенияПользователю Цикл
#Если Сервер И Не Сервер Тогда
СообщениеПользователю = Новый СообщениеПользователю;
#КонецЕсли
СообщениеПользователю.Текст = "#Поток " + ирОбщий.ПоследнийФрагментЛкс(ФоновоеЗадание.Ключ) + ": " + СообщениеПользователю.Текст;
//СообщитьЛкс(СообщениеПользователю.Текст,, Истина); // Теперь это всегда только на сервере
СообщениеПользователю.Сообщить();
КонецЦикла;
КонецЕсли;
Если ФоновоеЗадание.Состояние <> СостояниеФоновогоЗадания.Активно Тогда
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Завершено Тогда
РезультатПорции = ПолучитьИзВременногоХранилища(ПотокОбработки.АдресРезультата);
Если Статистика <> Неопределено Тогда
СтрокаСтатистики = Статистика.Добавить();
СтрокаСтатистики.Длительность = ФоновоеЗадание.Конец - ФоновоеЗадание.Начало;
Если Статистика.Количество() = 4 Тогда
СообщитьСтатистикуПорцийСРекомендациями(СтруктураПотоков);
КонецЕсли;
КонецЕсли;
Иначе
РезультатОбработки = "Фоновое задание отменено";
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда
РезультатОбработки = ПодробноеПредставлениеОшибкиЛкс(ФоновоеЗадание.ИнформацияОбОшибке);
КонецЕсли;
ВызватьИсключение РезультатОбработки;
//РезультатПорции = Новый Массив;
//ТекстСообщений = ирОбщий.СоединитьСообщенияПользователюЛкс(СообщенияПользователю);
//Для Счетчик = 1 По ПотокОбработки.СтрокиРезультатовОбъектов.Количество() Цикл
// РезультатПорции.Добавить(Новый Структура("Результат, ТекстСообщений", РезультатОбработки, ТекстСообщений));
//КонецЦикла;
КонецЕсли;
Для ИндексОбъектаПорции = 0 По ПотокОбработки.СтрокиРезультатовОбъектов.ВГраница() Цикл
РезультатОбработки = РезультатПорции[ИндексОбъектаПорции];
СтрокиРезультатов = ПотокОбработки.СтрокиРезультатовОбъектов[ИндексОбъектаПорции];
Выполнить("МодульОбработчика." + СтруктураПотоков.ИмяОбработчикаРезультатаОбъекта + "(РезультатОбработки, СтрокиРезультатов)");
ПотокОбработки.СтрокиРезультатовОбъектов[ИндексОбъектаПорции] = СтрокиРезультатов;
КонецЦикла;
ПотокОбработки.УникальныйИдентификатор = Неопределено;
КонецЕсли;
КонецЕсли;
Если ПотокОбработки.УникальныйИдентификатор = Неопределено Тогда
НомерСвободногоПотока = СтруктураПотоков.ПотокиОбработки.Индекс(ПотокОбработки);
НомераСвободныхПотоков.Добавить(НомерСвободногоПотока);
КонецЕсли;
КонецЦикла;
Возврат НомераСвободныхПотоков;
КонецФункции
Процедура ДобавитьТекущемуПользователюРолиИРЛкс() Экспорт
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
Возврат;
КонецЕсли;
ТекущийПользовательЗапуска = ПользователиИнформационнойБазы.ТекущийПользователь();
Если СтрКончаетсяНаЛкс(ТекущийПользовательЗапуска.ПолноеИмя, МаркерВременныхРолейЛкс()) Тогда
Возврат;
КонецЕсли;
ТекущийПользовательБД = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователя());
Если Ложь
Или ТекущийПользовательБД.Роли.Содержит(Метаданные.Роли.ирРазработчик)
Или Не ЗначениеЗаполнено(ИмяПользователя())
Или Не ПравоДоступа("Администрирование", Метаданные)
Тогда
Возврат;
КонецЕсли;
ТекущийПользовательБД.Роли.Добавить(Метаданные.Роли.ирРазработчик);
ТекущийПользовательБД.Роли.Добавить(Метаданные.Роли.ирПользователь);
Если Метаданные.Роли.Найти("ирВсеПрава") <> Неопределено Тогда
ТекущийПользовательБД.Роли.Добавить(Метаданные.Роли.ирВсеПрава);
КонецЕсли;
ТекущийПользовательБД.Записать();
#Если Клиент Тогда
ирОбщий.ОповеститьОЗаписиОбъектаЛкс(Тип("ПользовательИнформационнойБазы"));
#КонецЕсли
КонецПроцедуры
Функция МаркерВременныхРолейЛкс()
Результат = " (временные роли ИР)";
Возврат Результат;
КонецФункции
////////////////////////////////////////////////
#КонецЕсли
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент И Клиент Тогда
Функция ТабличноеПолеИлиТаблицаФормы_СколькоСтрокЛкс(ТабличноеПоле, Знач НастройкиСписка = Неопределено) Экспорт
ЗначениеЭУ = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
Если ЗначениеЭУ <> Неопределено Тогда
Количество = Неопределено;
Попытка
Количество = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле,, Истина).Количество();
Исключение
КонецПопытки;
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
Отбор = "?";
Иначе
Попытка
Отбор = ТабличноеПоле.ОтборСтрок;
Исключение
КонецПопытки;
КонецЕсли;
Если Количество = Неопределено Тогда
Попытка
//Коллекция компоновки
Количество = ЗначениеЭУ.Элементы.Количество();
//Суффикс = "*";
Исключение
Попытка
//Или ИмяОбщегоТипа = "ДеревоЗначений"
Количество = ЗначениеЭУ.Строки.Количество();
Суффикс = "*";
Исключение
КонецПопытки;
КонецПопытки;
КонецЕсли;
Если Количество = Неопределено Тогда
// ДинамическийСписок
Если НастройкиСписка = Неопределено Тогда
НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ЗначениеЭУ);
КонецЕсли;
Отбор = НастройкиСписка.Отбор;
ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле);
ЗапросСписка = ЗапросДинамическогоСпискаЛкс(ТабличноеПоле, ПолноеИмяТаблицы);
Если ЗначениеЗаполнено(ЗапросСписка.Текст) Тогда
Количество = КоличествоСтрокВТаблицеБДЛкс(ЗапросСписка);
Иначе
Количество = КоличествоСтрокВТаблицеБДЛкс(ПолноеИмяТаблицы, Отбор);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Текст = "Количество строк ";
Если Отбор <> Неопределено Тогда
Текст = Текст + "отобрано ";
КонецЕсли;
Текст = Текст + "- " + Формат(Количество, "ЧН=; ЧГ=") + Суффикс;
Если ТабличноеПоле.ВыделенныеСтроки.Количество() > 1 Тогда
Текст = Текст + ", выделено - " + Формат(ТабличноеПоле.ВыделенныеСтроки.Количество(), "ЧН=; ЧГ=");
КонецЕсли;
Если Отбор <> Неопределено Тогда
Текст = Текст + ". Отбор - """ + Отбор + """ ";
КонецЕсли;
СообщитьЛкс(Текст,,, Истина);
// Тексты подвала
Результат = Количество;
МассивПодвалов = Новый Массив;
#Если Клиент Тогда
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
Для Каждого КолонкаТП Из ТабличноеПоле.Колонки Цикл
ТекстПодвала = ПоследнийФрагментЛкс(КолонкаТП.ТекстПодвала, "Σ");
Если ЗначениеЗаполнено(ТекстПодвала) Тогда
МассивПодвалов.Добавить(КолонкаТП.ТекстШапки + " = " + ТекстПодвала);
КонецЕсли;
КонецЦикла;
КонецЕсли;
#КонецЕсли
Если МассивПодвалов.Количество() > 0 Тогда
СообщитьЛкс(СтрСоединитьЛкс(МассивПодвалов, "; "));
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле, Знач Строка = Неопределено) Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
ДанныеСтроки = Неопределено;
Если Строка = Неопределено Тогда
Строка = ТабличноеПоле.ТекущаяСтрока;
КонецЕсли;
Если Строка <> Неопределено Тогда
//ДанныеТаблицы = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
//#Если Сервер И Не Сервер Тогда
// ДанныеТаблицы = Новый ТаблицаЗначений;
//#КонецЕсли
//ДанныеСтроки = ДанныеТаблицы.НайтиПоИдентификатору(Строка);
ДанныеСтроки = ТабличноеПоле.ДанныеСтроки(Строка);
Если ДанныеСтроки = Неопределено Тогда
// Ключ записи регистра без ресурсов и измерений (ШтрихкодыНоменклатуры) иногда почему то дает Неопределено
ДанныеСтроки = Строка;
КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
ДанныеСтроки = Строка;
Если Ложь
Или ДанныеСтроки = Неопределено
Или ЛиКлючЗаписиРегистраЛкс(ДанныеСтроки)
Тогда
Попытка
ДанныеСтроки = ТабличноеПоле.ТекущиеДанные;
Исключение
// Удаленное из формы табличное поле, например вызов из Обработка.ирПлатформа.Форма.СтрокаТаблицы
ТабличноеПоле = Неопределено;
КонецПопытки;
КонецЕсли;
КонецЕсли;
Возврат ДанныеСтроки;
КонецФункции
Процедура ИсследоватьВерсиюОбъектаДанныхЛкс(Знач Данные, Знач НомерВерсии) Экспорт
#Если ВебКлиент Тогда
СообщитьЛкс("Команда недоступна в вебклиенте");
#Иначе
ИсторияДанныхМоя = Вычислить("ИсторияДанных");
#Если Сервер И Не Сервер Тогда
ИсторияДанныхМоя = ИсторияДанных;
#КонецЕсли
Структура = ИсторияДанныхМоя.ПолучитьДанныеВерсии(Данные, НомерВерсии);
ИсследоватьЛкс(Структура);
#КонецЕсли
КонецПроцедуры
Функция ОткрытьСистемнуюФормуОтчетПоВерсииЛкс(Данные, НомерВерсии) Экспорт
Попытка
ОткрытьФорму("sysForm:DataHistoryVersionDataRuForm", Новый Структура("Данные, НомерВерсии", Данные, НомерВерсии));
Исключение
ОписаниеОшибки = ОписаниеОшибки();
ИсследоватьВерсиюОбъектаДанныхЛкс(Данные, НомерВерсии);
КонецПопытки;
КонецФункции
// Функция - Открыть системную форму список версий лкс
//
// Параметры:
// Данные - -
// НомерВерсии - Число - пока не реализовано
//
// Возвращаемое значение:
// -
//
Функция ОткрытьСистемнуюФормуСписокВерсийОбъектаЛкс(Данные, НомерВерсии) Экспорт
ОткрытьФорму("sysForm:DataHistoryVersions", Новый Структура("Data", Данные));
КонецФункции
Функция ОткрытьСистемнуюФормуСравнениеВерсийЛкс(Данные, НомерВерсииПослеИзменения, НомерВерсииДоИзменения) Экспорт
ОткрытьФорму("sysForm:DataHistoryVersionDifferenecesRuForm", Новый Структура("Данные, НомерВерсииПослеИзменения, НомерВерсииДоИзменения", Данные, НомерВерсииПослеИзменения, НомерВерсииДоИзменения));
КонецФункции
Функция ОткрытьСистемнуюФормуНастройкаОтбораВерсийЛкс(Знач КлючОбъекта, Знач ОтборВерсий, Знач Оповещение) Экспорт
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Filter", ОтборВерсий);
ПараметрыФормы.Вставить("Data", КлючОбъекта);
ПолноеИмяФормы = "sysForm:DataHistoryVersionsFilterDialog";
Выполнить("ОткрытьФорму(ПолноеИмяФормы, ПараметрыФормы,,,,, Оповещение)"); // Параметра "Оповещение" в 8.2 нет
КонецФункции
Процедура ИсследоватьСравнениеВерсийЛкс(Знач Данные, Знач НомерВерсииПослеИзменения, Знач НомерВерсииДоИзменения) Экспорт
#Если ВебКлиент Тогда
СообщитьЛкс("Команда недоступна в вебклиенте");
#Иначе
ИсторияДанныхМоя = Вычислить("ИсторияДанных");
#Если Сервер И Не Сервер Тогда
ИсторияДанныхМоя = ИсторияДанных;
#КонецЕсли
Структура = ИсторияДанныхМоя.ПолучитьРазличияВерсий(Данные, НомерВерсииПослеИзменения, НомерВерсииДоИзменения);
ИсследоватьЛкс(Структура);
#КонецЕсли
КонецПроцедуры
Функция НоваяФормаРезультатаФоновогоЗаданияЛкс() Экспорт
// Управляемые формы так создавать нельзя!
// http://www.hostedredmine.com/issues/874998
//мПлатформа = ирКэш.Получить();
//#Если Сервер И Не Сервер Тогда
// мПлатформа = Обработки.ирПлатформа.Создать();
//#КонецЕсли
//ФормаРезультатФоновогоЗадания = мПлатформа.ПолучитьФорму("РезультатФоновогоЗадания");
ФормаРезультатФоновогоЗадания = ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.РезультатФоновогоЗадания",,, Новый УникальныйИдентификатор);
Возврат ФормаРезультатФоновогоЗадания;
КонецФункции
Функция ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(Знач ЭтаФорма, Знач ОписаниеЗадания, Знач Перезапустить = Ложь) Экспорт
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ЭтаФорма);
#Если Сервер И Не Сервер Тогда
СлужебныеДанные = Новый Структура;
ОписаниеЗадания = ОписаниеФоновогоЗаданияФормыЛкс();
#КонецЕсли
Если Не МетодРеализованЛкс(ЭтаФорма, ОписаниеЗадания.ОбработчикЗавершения) Тогда
ВызватьИсключение "У формы " + СсылкаНаМодульКонфигурацииЛкс(СлужебныеДанные.ИмяФормы) + " не обнаружен экспортный метод " + ОписаниеЗадания.ОбработчикЗавершения;
КонецЕсли;
МаркерОтмены = "Отменить фоновое задание";
ЗаданияФормы = СлужебныеДанные.Задания;
Если ЗаданияФормы.Свойство(ОписаниеЗадания.Имя) Тогда
ОписаниеЗаданияСтарое = ЗаданияФормы[ОписаниеЗадания.Имя];
Если ОписаниеЗаданияСтарое.УникальныйИдентификатор <> Неопределено Тогда
Если Ложь
Или ОписаниеЗадания.Кнопка = Неопределено
Или ОписаниеЗадания.Кнопка.Картинка <> ирКэш.КартинкаПоИмениЛкс("ирОстановить")
Тогда
Перезапустить = Истина;
КонецЕсли;
ОтменитьЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗаданияСтарое);
Если Не Перезапустить Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ОписаниеЗадания.НачалоВыполнения = ТекущаяДата();
ДобавитьТекущемуПользователюРолиИРЛкс();
ФоновоеЗадание = ФоновыеЗадания.Выполнить(ОписаниеЗадания.Метод, ОписаниеЗадания.Параметры, , ЭтаФорма.Метаданные().Представление() + ". " + ОписаниеЗадания.Представление);
ОписаниеЗадания.УникальныйИдентификатор = ФоновоеЗадание.УникальныйИдентификатор;
ЗаданияФормы.Вставить(ОписаниеЗадания.Имя, ОписаниеЗадания);
ФормаЗадания = ФормаЗаданияФормыЛкс(ОписаниеЗадания, ЭтаФорма);
Если ФормаЗадания <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ФормаЗадания = ПолучитьОбщуюФорму();
#КонецЕсли
ФормаЗадания.ЭлементыФормы.ПолеТекста.Очистить();
ФормаЗадания.ЭлементыФормы.Отменить.Доступность = Истина;
ФормаЗадания.ЗакрыватьПриЗакрытииВладельца = ЭтаФорма.Открыта();
ФормаЗадания.Отменить = Ложь;
ФормаЗадания.ИдентификаторЗадания = ФоновоеЗадание.УникальныйИдентификатор;
ФормаЗадания.ОбновитьСостояниеЗадания(ФоновоеЗадание);
КонецЕсли;
ОжидатьЗавершения = ОписаниеЗадания.Кнопка = Неопределено;
Если Не ОжидатьЗавершения Тогда
// Завершаем основной поток
Если ОписаниеЗадания.БлокируемыеЭлементыФормы <> Неопределено Тогда
Для Каждого КлючИЗначение Из ОписаниеЗадания.БлокируемыеЭлементыФормы Цикл
КлючИЗначение.Значение.Вставить("Доступность");
КлючИЗначение.Значение.Вставить("ТолькоПросмотр");
БлокируемыйЭлемент = КлючИЗначение.Ключ;
#Если Сервер И Не Сервер Тогда
БлокируемыйЭлемент = Новый ТабличноеПоле;
#КонецЕсли
ЗаполнитьЗначенияСвойств(КлючИЗначение.Значение, БлокируемыйЭлемент);
Если ТипЗнч(БлокируемыйЭлемент) = Тип("ПолеHTMLДокумента") Тогда
ПолеТекста = ирОбщий.ОболочкаПоляТекстаЛкс(БлокируемыйЭлемент);
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ПолеТекста.ТолькоПросмотр(Истина);
Иначе
Попытка
БлокируемыйЭлемент.ТолькоПросмотр = Истина;
Исключение
БлокируемыйЭлемент.Доступность = Ложь;
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ТипЗнч(ОписаниеЗадания.Кнопка) = Тип("КнопкаКоманднойПанели") Тогда
ИменаСвойств = "Доступность, Подсказка, Картинка, Отображение";
Иначе
ИменаСвойств = "Доступность, Подсказка, Картинка";
КонецЕсли;
СвойстваКнопки = Новый Структура(ИменаСвойств);
ЗаполнитьЗначенияСвойств(СвойстваКнопки, ОписаниеЗадания.Кнопка, ИменаСвойств);
ОписаниеЗадания.СвойстваКнопки = СвойстваКнопки;
ОписаниеЗадания.Кнопка.Доступность = Истина;
ОписаниеЗадания.Кнопка.Картинка = ирКэш.КартинкаПоИмениЛкс("ирОстановить");
ОписаниеЗадания.Кнопка.Подсказка = МаркерОтмены + " - " + ОписаниеЗадания.Представление;
Если СвойстваКнопки.Свойство("Отображение") Тогда
ОписаниеЗадания.Кнопка.Отображение = ОтображениеКнопкиКоманднойПанели.НадписьКартинка;
КонецЕсли;
Иначе
// Удерживаем основной поток
Если ОписаниеЗадания.Многопоточное Тогда
ФормаЗадания.Открыть();
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОтменитьЗаданиеФормыОтложенноЛкс();
#КонецЕсли
ПодключитьОбработчикОжиданияСПараметрамиЛкс("ОтменитьЗаданиеФормыОтложенноЛкс", Новый Структура("ЭтаФорма, ОписаниеЗадания", ЭтаФорма, ОписаниеЗадания));
ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание, ЭтаФорма, Ложь, ФормаЗадания);
КонецЕсли;
Результат = Неопределено;
ПроверитьЗавершениеФоновыхЗаданийФормыЛкс(ЭтаФорма, ОписаниеЗадания, Результат);
Возврат Результат;
КонецФункции
Функция ОписаниеФоновогоЗаданияФормыЛкс(Имя = "", Метод = "", Параметры = Неопределено, Знач Представление = "", Кнопка = Неопределено, ОбработчикЗавершения = "", АдресРезультата = "",
ОповещатьПользователяОбУспехе = Истина, БлокируемыеЭлементыФормы = Неопределено, Многопоточное = Ложь, ПрефиксыОповещений = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(Представление) Тогда
Представление = ПредставлениеИзИдентификатораЛкс(Имя);
КонецЕсли;
ОписаниеЗадания = Новый Структура("Имя, Параметры, Метод, Представление, Кнопка, ОбработчикЗавершения, АдресРезультата, УникальныйИдентификатор, НачалоВыполнения, Состояние, СвойстваКнопки,
|ОповещатьПользователяОбУспехе, БлокируемыеЭлементыФормы, ФормаЗадания, Многопоточное, ПрефиксыОповещений");
ОписаниеЗадания.Имя = Имя;
ОписаниеЗадания.Параметры = Параметры;
ОписаниеЗадания.Метод = Метод;
ОписаниеЗадания.Представление = Представление;
ОписаниеЗадания.Кнопка = Кнопка;
ОписаниеЗадания.ОбработчикЗавершения = ОбработчикЗавершения;
ОписаниеЗадания.АдресРезультата = АдресРезультата;
ОписаниеЗадания.ОповещатьПользователяОбУспехе = ОповещатьПользователяОбУспехе;
ОписаниеЗадания.Многопоточное = Многопоточное;
ОписаниеЗадания.ПрефиксыОповещений = ПрефиксыОповещений;
Если БлокируемыеЭлементыФормы <> Неопределено Тогда
СтруктураБлокировки = Новый Соответствие;
Для Каждого ЭлементФормы Из БлокируемыеЭлементыФормы Цикл
Если Истина
И Типзнч(ЭлементФормы) = Тип("КнопкаКоманднойПанели")
И ЭлементФормы.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю
Тогда
Для Каждого КнопкаПодменю Из ЭлементФормы.Кнопки Цикл
Если КнопкаПодменю.Доступность Тогда
СтруктураБлокировки.Вставить(КнопкаПодменю, Новый Структура());
КонецЕсли;
КонецЦикла;
Иначе
СтруктураБлокировки.Вставить(ЭлементФормы, Новый Структура());
КонецЕсли;
КонецЦикла;
ОписаниеЗадания.БлокируемыеЭлементыФормы = СтруктураБлокировки;
КонецЕсли;
Возврат ОписаниеЗадания;
КонецФункции
Функция НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(Знач ЭтаФорма) Экспорт
ФормаРезультатовЗаданий = ФормаРезультатовЗаданийФормыЛкс(ЭтаФорма);
АдресРезультата = ПоместитьВоВременноеХранилище(Null, ФормаРезультатовЗаданий.УникальныйИдентификатор);
Возврат АдресРезультата;
КонецФункции
Функция ФормаРезультатовЗаданийФормыЛкс(Знач ЭтаФорма) Экспорт
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ЭтаФорма);
#Если Сервер И Не Сервер Тогда
СлужебныеДанные = Новый Структура;
#КонецЕсли
Результат = Неопределено;
Если Не СлужебныеДанные.Свойство("ФормаРезультатовЗаданий", Результат) Тогда
Результат = ирОбщий.НоваяФормаРезультатаФоновогоЗаданияЛкс();
СлужебныеДанные.Вставить("ФормаРезультатовЗаданий", Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
// Функция - Проверить завершение фоновых заданий формы лкс
//
// Параметры:
// ЭтаФорма - -
//
// Возвращаемое значение:
// - Булево - активные задания отсутствуют
//
Функция ПроверитьЗавершениеФоновыхЗаданийФормыЛкс(Знач ЭтаФорма, Знач ОписаниеЗаданияОтбора = Неопределено, Результат = Неопределено) Экспорт
//Если Не ЭтаФорма.Открыта() Тогда
// Возврат Истина;
//КонецЕсли;
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ЭтаФорма);
#Если Сервер И Не Сервер Тогда
ЭтаФорма = ПолучитьОбщуюФорму();
СлужебныеДанные = Новый Структура;
#КонецЕсли
ЗадержкаВызова = 100;
ДлительностьДляЗаголовка = 0;
РазделительДлительности = "-";
ПозицияРазделителя = Найти(ЭтаФорма.Заголовок, РазделительДлительности);
Если Истина
И ПозицияРазделителя < 10
И Найти(Лев(ЭтаФорма.Заголовок, ПозицияРазделителя), ":") > 0
Тогда
ЧистыйЗаголовокФормы = Сред(ЭтаФорма.Заголовок, ПозицияРазделителя + СтрДлина(РазделительДлительности));
Иначе
ЧистыйЗаголовокФормы = ЭтаФорма.Заголовок;
КонецЕсли;
ФормаРезультата = ФормаРезультатовЗаданийФормыЛкс(ЭтаФорма);
Завершенные = Новый Массив;
ЛиАктивныеЗаданияОтсутствуют = Истина;
Для Каждого КлючИЗначение Из СлужебныеДанные.Задания Цикл
ОписаниеЗадания = КлючИЗначение.Значение;
Если Истина
И ОписаниеЗаданияОтбора <> Неопределено
И ОписаниеЗаданияОтбора <> ОписаниеЗадания
Тогда
Продолжить;
КонецЕсли;
Если ОписаниеЗадания.УникальныйИдентификатор = Неопределено Тогда
// Уже обработано. Защита от зацикливания
Продолжить;
КонецЕсли;
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ОписаниеЗадания.УникальныйИдентификатор);
ФормаЗадания = ФормаЗаданияФормыЛкс(ОписаниеЗадания, ЭтаФорма);
Если ФормаЗадания <> Неопределено Тогда
Если ФормаЗадания.Отменить Тогда
ОтменитьЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания);
КонецЕсли;
КонецЕсли;
ДлительностьЗадания = ТекущаяДата() - ОписаниеЗадания.НачалоВыполнения;
СостояниеЗадания = ФоновоеЗадание.Состояние;
Если ОписаниеЗадания.Многопоточное Тогда
ПрефиксКлючаПотока = ПрефиксКлючаПотокаЛкс(ЭтаФорма);
КонецЕсли;
ЭтаИлиФормаЗаданияАктивна = Ложь
Или ФормаЗадания = Неопределено
Или Форма_ВводДоступенЛкс(ЭтаФорма)
Или Форма_ВводДоступенЛкс(ФормаЗадания);
Если СостояниеЗадания = СостояниеФоновогоЗадания.Активно Тогда
Если ДлительностьДляЗаголовка < ДлительностьЗадания Тогда
ДлительностьДляЗаголовка = ДлительностьЗадания;
КонецЕсли;
Если ДлительностьЗадания > 20 Тогда
ЗадержкаВызова = Мин(ЗадержкаВызова, 4);
ИначеЕсли ДлительностьЗадания > 10 Тогда
ЗадержкаВызова = Мин(ЗадержкаВызова, 2);
ИначеЕсли ДлительностьЗадания > 5 Тогда
ЗадержкаВызова = Мин(ЗадержкаВызова, 1);
ИначеЕсли ДлительностьЗадания > 2 Тогда
ЗадержкаВызова = Мин(ЗадержкаВызова, 0.5);
Иначе
ЗадержкаВызова = Мин(ЗадержкаВызова, 0.2);
КонецЕсли;
Если ЭтаИлиФормаЗаданияАктивна Тогда
ИзменилиТекстСостояния = ОбработатьСообщенияФоновогоЗаданияЛкс(ФоновоеЗадание, ФормаЗадания, ПрефиксКлючаПотока);
Если ФормаЗадания <> Неопределено Тогда
Если Ложь
Или ИзменилиТекстСостояния И ДлительностьЗадания > 2
Или ДлительностьЗадания > 4
Тогда
Если Не ФормаЗадания.Открыта() Тогда
ФормаЗадания.Открыть();
ЭтаФорма.Открыть();
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Если ФормаЗадания.Открыта() Тогда
ФормаЗадания.Закрыть();
КонецЕсли;
КонецЕсли;
ЛиАктивныеЗаданияОтсутствуют = Ложь;
Результат = Тип("ФоновоеЗадание");
Иначе
ОписаниеЗадания.Состояние = СостояниеЗадания;
Если СостояниеЗадания = СостояниеФоновогоЗадания.Завершено И ЗначениеЗаполнено(ОписаниеЗадания.АдресРезультата) Тогда
Результат = ПрочитатьРезультатФоновогоЗаданияЛкс(ОписаниеЗадания.АдресРезультата, ФормаРезультата);
Иначе
Результат = Неопределено;
КонецЕсли;
ПараметрыЗадания = ОписаниеЗадания.Параметры;
ДлительностьЗадания = ФоновоеЗадание.Конец - ФоновоеЗадание.Начало;
ДлительностьСтрока = ирОбщий.ПредставлениеДлительностиЛкс(ДлительностьЗадания);
Если СостояниеЗадания = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда
СообщитьЛкс(СтрШаблонИменЛкс("Ошибка через %1 фонового задания %2: " + ПодробноеПредставлениеОшибкиЛкс(ФоновоеЗадание.ИнформацияОбОшибке),
1, ДлительностьСтрока, 2, ФоновоеЗадание.Наименование), СтатусСообщения.Внимание);
Результат = ФоновоеЗадание.ИнформацияОбОшибке;
ИначеЕсли Не ЭтаИлиФормаЗаданияАктивна И ОписаниеЗадания.ОповещатьПользователяОбУспехе Тогда
СообщитьЛкс(СтрШаблонИменЛкс("Завершено через %1 фоновое задание %2",, ДлительностьСтрока, 2, ФоновоеЗадание.Наименование));
КонецЕсли;
ОбработатьЗавершениеЗаданияФормыЛкс(ОписаниеЗадания, ЭтаФорма, ФоновоеЗадание);
Если ФормаЗадания <> Неопределено Тогда
ФормаЗадания.ПолноеПредставление = ЧистыйЗаголовокФормы + ". " + ФормаЗадания.КраткоеПредставление;
КонецЕсли;
Выполнить("ЭтаФорма." + ОписаниеЗадания.ОбработчикЗавершения + "(СостояниеЗадания, Результат)");
Завершенные.Добавить(КлючИЗначение.Ключ);
КонецЕсли;
КонецЦикла;
Для Каждого Ключ Из Завершенные Цикл
СлужебныеДанные.Задания.Удалить(Ключ);
КонецЦикла;
Если ЗадержкаВызова <> 100 Тогда
ЭтаФорма.Заголовок = ирОбщий.ПредставлениеДлительностиЛкс(ДлительностьДляЗаголовка) + РазделительДлительности + ЧистыйЗаголовокФормы;
ЭтаФорма.ПодключитьОбработчикОжидания("ПроверкаЗавершенияФоновыхЗаданий", ЗадержкаВызова, Истина);
Иначе
ЭтаФорма.Заголовок = ЧистыйЗаголовокФормы;
КонецЕсли;
Возврат ЛиАктивныеЗаданияОтсутствуют;
КонецФункции
Процедура ОбработатьЗавершениеЗаданияФормыЛкс(Знач ОписаниеЗадания, Знач ЭтаФорма, Знач ФоновоеЗадание = Неопределено, Знач ПоЗапросуПользователя = Ложь, Знач ЗакрытьФормуЗадания = Ложь)
Если ФоновоеЗадание = Неопределено Тогда
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ОписаниеЗадания.УникальныйИдентификатор);
КонецЕсли;
Если ОписаниеЗадания.Кнопка <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(ОписаниеЗадания.Кнопка, ОписаниеЗадания.СвойстваКнопки);
КонецЕсли;
Если ОписаниеЗадания.БлокируемыеЭлементыФормы <> Неопределено Тогда
Для Каждого КлючИЗначение Из ОписаниеЗадания.БлокируемыеЭлементыФормы Цикл
ЗаполнитьЗначенияСвойств(КлючИЗначение.Ключ, КлючИЗначение.Значение);
КонецЦикла;
КонецЕсли;
ФормаЗадания = ФормаЗаданияФормыЛкс(ОписаниеЗадания, ЭтаФорма);
ОбработатьСообщенияФоновогоЗаданияЛкс(ФоновоеЗадание, ФормаЗадания);
ОписаниеЗадания.УникальныйИдентификатор = Неопределено; // Защита от зацикливания
ОписаниеЗадания.ФормаЗадания = Неопределено;
Если ФормаЗадания = Неопределено Тогда
Возврат;
КонецЕсли;
ПолеСообщений = ФормаЗадания.ЭлементыФормы.ПолеТекста;
Если ПустаяСтрока(ПолеСообщений.ПолучитьТекст()) Тогда
Если ФормаЗадания.Открыта() Тогда
ФормаЗадания.Закрыть();
КонецЕсли;
Иначе
Если ПоЗапросуПользователя Тогда
ПолеСообщений.ДобавитьСтроку("Выполнение прервано пользователем!");
КонецЕсли;
Если Истина
И ЭтаФорма.Открыта()
И Не ФормаЗадания.Открыта()
Тогда
ФормаЗадания.Открыть();
КонецЕсли;
ЕстьОбычныеСообщения = Истина;
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если ОписаниеЗадания.ПрефиксыОповещений <> Неопределено Тогда
ТекстОповещения = Новый Массив;
ЕстьОбычныеСообщения = Ложь;
Для Счетчик = 1 По ПолеСообщений.КоличествоСтрок() Цикл
СтрокаСообщения = ПолеСообщений.ПолучитьСтроку(Счетчик);
ЛиОповещение = Ложь;
Для Каждого ПрефиксОповещения Из ОписаниеЗадания.ПрефиксыОповещений Цикл
Если СтрНачинаетсяСЛкс(СтрокаСообщения, ПрефиксОповещения, Истина) Тогда
ЛиОповещение = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ЛиОповещение Тогда
ТекстОповещения.Добавить(СтрокаСообщения);
Иначе
ЕстьОбычныеСообщения = Истина;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Не ЕстьОбычныеСообщения Тогда
ОписаниеОповещения = Новый ОписаниеОповещения("ОповещениеОткрытьФормуЛкс", ирОбщий, Новый Структура("Форма", ФормаЗадания));
ПоказатьОповещениеПользователя(, ОписаниеОповещения, СтрСоединитьЛкс(ТекстОповещения, Символы.ПС));
Форма_АктивироватьОткрытьЛкс(ЭтаФорма);
КонецЕсли;
#КонецЕсли
КонецЕсли;
Если ЗакрытьФормуЗадания Тогда
Если ФормаЗадания.Открыта() Тогда
ФормаЗадания.Закрыть();
КонецЕсли;
КонецЕсли;
Если ФормаЗадания.Открыта() Тогда
ФормаЗадания.ОбновитьСостояниеЗадания(ФоновоеЗадание);
КонецЕсли;
КонецПроцедуры
Процедура ОповещениеОткрытьФормуЛкс(ДопПараметры) Экспорт
ДопПараметры.Форма.Открыть();
КонецПроцедуры
Функция ФормаЗаданияФормыЛкс(Знач ОписаниеЗадания, Знач ФормаВладелец)
ФормаЗадания = ОписаниеЗадания.ФормаЗадания;
Если Истина
И ФормаЗадания = Неопределено
И (Ложь
// Запрещаем использовать форму для однопоточного задания с ожиданием
Или ОписаниеЗадания.Кнопка <> Неопределено
Или ОписаниеЗадания.Многопоточное)
Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаЗадания = мПлатформа.ПолучитьФорму("ФоновоеЗаданиеФормы", ФормаВладелец, ОписаниеЗадания.Имя);
ФормаЗадания.КраткоеПредставление = ОписаниеЗадания.Представление;
ФормаЗадания.ПолноеПредставление = ОписаниеЗадания.Представление;
ОписаниеЗадания.ФормаЗадания = ФормаЗадания;
КонецЕсли;
Возврат ФормаЗадания;
КонецФункции
// Функция - Прочитать результат фонового задания лкс
//
// Параметры:
// АдресРезультата - -
// ФормаРезультата - УправляемаяФорма - Обработка.ирПлатформа.Форма.РезультатФоновогоЗадания, с ее идентификатором создавался адрес временного хранилища
//
// Возвращаемое значение:
// -
//
Функция ПрочитатьРезультатФоновогоЗаданияЛкс(Знач АдресРезультата, Знач ФормаРезультата = Неопределено) Экспорт
Результат = ПолучитьИзВременногоХранилища(АдресРезультата);
Если Результат = Null И ФормаРезультата <> Неопределено Тогда
// Антибаг платформы https://www.hostedredmine.com/issues/884756
ФормаРезультата.ОбновитьВременноеХранилище(АдресРезультата); // Тяжелая операция
Результат = ПолучитьИзВременногоХранилища(АдресРезультата);
Если Результат = Null Тогда
ирОбщий.СообщитьЛкс("Не удалось получить результат фонового задания вероятно из-за ошибки платформы https://www.hostedredmine.com/issues/884756. Асинхронность отключена до конца сеанса.", СтатусСообщения.Внимание);
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
мПлатформа.АсинхронностьЗапрещена = Истина;
КонецЕсли;
КонецЕсли;
УдалитьИзВременногоХранилища(АдресРезультата);
Возврат Результат
КонецФункции
Процедура ОтменитьФоновоеЗаданиеОтложенноЛкс(Параметры) Экспорт
ОтменитьФоновоеЗаданиеЛкс(Параметры.ИдентификаторФоновогоЗадания);
КонецПроцедуры
Процедура ОтменитьФоновоеЗаданиеЛкс(Знач ИдентификаторИлиФоновоеЗадание) Экспорт
Если ТипЗнч(ИдентификаторИлиФоновоеЗадание) = Тип("ФоновоеЗадание") Тогда
ФоновоеЗадание = ИдентификаторИлиФоновоеЗадание;
Иначе
Если Не ЗначениеЗаполнено(ИдентификаторИлиФоновоеЗадание) Тогда
Возврат;
КонецЕсли;
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторИлиФоновоеЗадание);
КонецЕсли;
Если Истина
И ФоновоеЗадание <> Неопределено
И ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Активно
Тогда
ФоновоеЗадание.Отменить();
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
ПроверитьОтмененныеФоновыеЗаданияОтложенноЛкс();
#КонецЕсли
мПлатформа.ОтмененныеФоновыеЗадания.Добавить(ФоновоеЗадание.УникальныйИдентификатор);
ПодключитьГлобальныйОбработчикОжиданияЛкс("ПроверитьОтмененныеФоновыеЗаданияОтложенноЛкс", 2);
КонецЕсли;
КонецПроцедуры
Функция ЗагрузитьТабличныйДокументИнтерактивноЛкс(Знач ТабличныйДокумент = Неопределено, выхПолноеИмяФайла = "") Экспорт
Если ТабличныйДокумент = Неопределено Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
КонецЕсли;
ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДиалогВыбораФайла.Заголовок = "Прочитать табличный документ из файла";
СписокРасширений = Новый СписокЗначений;
СписокРасширений.Добавить("mxl", "Табличный документ");
СписокРасширений.Добавить("xls", "Лист Excel");
СписокРасширений.Добавить("xlsx", "Лист Excel");
СписокРасширений.Добавить("ods", "Open document");
СписокРасширений.Добавить("txt", "Текстовый документ");
СписокРасширений.Добавить("csv", "Текстовый документ");
СписокРасширений.Добавить("dbf", "dBase III");
Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда
СписокРасширений.Добавить("htm", "HTML документ");
СписокРасширений.Добавить("html", "HTML документ");
КонецЕсли;
ДиалогВыбораФайла.Фильтр = ФильтрДляВыбораФайлаЛкс(СписокРасширений,, Ложь);
Если ДиалогВыбораФайла.Выбрать() Тогда
выхПолноеИмяФайла = ДиалогВыбораФайла.ПолноеИмяФайла;
ФайлНаДиске = Новый Файл(выхПолноеИмяФайла);
Если Ложь
Или ирОбщий.СтрокиРавныЛкс(ФайлНаДиске.Расширение, ".txt")
Или ирОбщий.СтрокиРавныЛкс(ФайлНаДиске.Расширение, ".csv")
Тогда
ПрочитатьТабличныйДокументИзТекстаЛкс(ТабличныйДокумент, выхПолноеИмяФайла);
ИначеЕсли нРег(ФайлНаДиске.Расширение) = ".dbf" Тогда
ПрочитатьТабличныйДокументИзDBFЛкс(ТабличныйДокумент, выхПолноеИмяФайла);
ИначеЕсли нРег(ФайлНаДиске.Расширение) = ".mxl" Тогда
ТабличныйДокумент.Прочитать(выхПолноеИмяФайла);
ИначеЕсли СтрНачинаетсяСЛкс(ФайлНаДиске.Расширение, ".htm") Тогда
СостояниеЛкс("Запускаем EXCEL");
ИмяФайлаТаблицы = ПолучитьИмяВременногоФайла("xlsx");
Эксель = Новый COMОбъект("Excel.Application");
Эксель.Visible = 1; // Иначе могут появляться невидимые модальные окна
//Эксель.DisplayAlerts = 0;
// https://docs.microsoft.com/ru-ru/office/vba/api/excel.workbooks.open
// (FileName, UpdateLinks, ReadOnly, Format, Password, WriteResPassword, IgnoreReadOnlyRecommended, Origin, Delimiter, Editable, Notify, Converter, AddToMru, Local, CorruptLoad)
Книга = Эксель.WorkBooks.Open(выхПолноеИмяФайла, Ложь);
Книга.SaveAs(ИмяФайлаТаблицы, 51); // 51 - xlsx, 56 - xls, 44 - html
Книга.Close();
Эксель.Quit();
ТабличныйДокумент.Прочитать(ИмяФайлаТаблицы);
УдалитьФайлы(ИмяФайлаТаблицы);
СостояниеЛкс("");
Иначе
ТабличныйДокумент.Очистить();
ТабличныйДокументЧтение = Новый ТабличныйДокумент;
ТабличныйДокументЧтение.Прочитать(выхПолноеИмяФайла);
РезультатВыбора = Неопределено;
Если ТабличныйДокументЧтение.Области.Количество() > 1 Тогда
СписокВыбора = Новый СписокЗначений;
Для Каждого Область Из ТабличныйДокументЧтение.Области Цикл
СписокВыбора.Добавить(Область.Имя);
КонецЦикла;
РезультатВыбора = СписокВыбора.ВыбратьЭлемент("Выберите лист файла");
КонецЕсли;
Если РезультатВыбора <> Неопределено Тогда
ТабличныйДокумент.Вывести(ТабличныйДокументЧтение.ПолучитьОбласть(РезультатВыбора.Значение));
Иначе
ТабличныйДокумент.Вывести(ТабличныйДокументЧтение);
КонецЕсли;
КонецЕсли;
Иначе
ТабличныйДокумент = Неопределено;
КонецЕсли;
Возврат ТабличныйДокумент;
КонецФункции
Функция СохранитьТабличныйДокументИнтерактивноЛкс(Знач ПолеИлиТабличныйДокумент, выхПолноеИмяФайла = "", Знач СразуОткрыть = Ложь, Знач УстанавливатьПризнакСодержитЗначение = Ложь,
Знач ЭтаФорма = Неопределено) Экспорт
Если ЭтаФорма <> Неопределено И ТипЗнч(ПолеИлиТабличныйДокумент) = Тип("ПолеТабличногоДокумента") Тогда
ПолеТабличногоДокументаВосстановитьОформлениеТекущихСтрокЛкс(ЭтаФорма, ПолеИлиТабличныйДокумент);
КонецЕсли;
Если Не ЗначениеЗаполнено(выхПолноеИмяФайла) Тогда
ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
ДиалогВыбораФайла.Заголовок = "Записать табличный документ в файл";
СписокРасширений = Новый СписокЗначений;
СписокРасширений.Добавить("mxl", "Табличный документ");
СписокРасширений.Добавить("xls", "Лист Excel");
СписокРасширений.Добавить("xlsx", "Лист Excel");
СписокРасширений.Добавить("ods", "Open document");
СписокРасширений.Добавить("txt", "Текстовый документ");
ДиалогВыбораФайла.Фильтр = ФильтрДляВыбораФайлаЛкс(СписокРасширений,, Ложь);
Если Не ДиалогВыбораФайла.Выбрать() Тогда
Возврат Ложь;
КонецЕсли;
выхПолноеИмяФайла = ДиалогВыбораФайла.ПолноеИмяФайла;
КонецЕсли;
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.ВставитьОбласть(ПолеИлиТабличныйДокумент.Область(),,, Ложь);
Файл = Новый файл(выхПолноеИмяФайла);
ТипФайла = ТипФайлаТабличногоДокумента.MXL;
Если ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".xls") Тогда
ТипФайла = ТипФайлаТабличногоДокумента.XLS;
Если УстанавливатьПризнакСодержитЗначение Тогда
УстановитьПризнакСодержитЗначение(ТабличныйДокумент);
КонецЕсли;
ИначеЕсли ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".xlsx") Тогда
ТипФайла = ТипФайлаТабличногоДокумента.XLSX;
Если УстанавливатьПризнакСодержитЗначение Тогда
УстановитьПризнакСодержитЗначение(ТабличныйДокумент);
КонецЕсли;
ИначеЕсли ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".ods") Тогда
ТипФайла = ТипФайлаТабличногоДокумента.ODS;
ИначеЕсли ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".txt") Тогда
ТипФайла = ТипФайлаТабличногоДокумента.TXT;
КонецЕсли;
Попытка
ТабличныйДокумент.Записать(выхПолноеИмяФайла, ТипФайла);
Исключение
СообщитьЛкс(ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;
Если Не СразуОткрыть И Не ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".mxl") Тогда
Ответ = Вопрос("Хотите сразу открыть сохраненный файл в сопоставленном приложении?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Да);
СразуОткрыть = Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если СразуОткрыть Тогда
ЗапуститьПриложение(выхПолноеИмяФайла);
КонецЕсли;
Возврат Истина;
КонецФункции
Процедура УстановитьПризнакСодержитЗначение(ТабличныйДокумент)
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
// Проставим свойство СодержитЗначение, чтобы при открытии в EXCEL в строках типа "000534235" не устанавливался формат "Почтовый"
// и не пропадали лидирующие нули при входе в режим редактирования ячейки
Для ТекущаяКолонка = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Для ТекущаяСтрока = 1 По ТабличныйДокумент.ВысотаТаблицы Цикл
ОбластьЯчейки = ТабличныйДокумент.Область(ТекущаяСтрока, ТекущаяКолонка);
ОбластьЯчейки.СодержитЗначение = Истина;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция ПодтверждениеОперацииСУБДЛкс() Экспорт
Если ПолучитьСоединениеСУБД() = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
ИмяБД = ПараметрыСоединенияADOЭтойБДЛкс().ИмяБД;
Возврат Вопрос("Вы осознаете риски и ответственность за использование прямого доступа к данным базы """ + ИмяБД + """ и нарушение лицензионного соглашения 1С?", РежимДиалогаВопрос.ДаНет) = КодВозвратаДиалога.Да;
КонецФункции
// РежимИмяСиноним - Булево - Истина - Имя
Процедура НастроитьАвтоТабличноеПолеДинамическогоСпискаЛкс(ОсновнойЭУ, РежимИмяСиноним = Ложь, РазрешитьСортировку = Истина, ПредельноеКоличествоВидимыхКолонок = 30) Экспорт
#Если Сервер И Не Сервер Тогда
ОсновнойЭУ = Новый ТабличноеПоле;
#КонецЕсли
// Антибаг платформы 8.2-8.3 для регистра бухгалтерии https://partners.v8.1c.ru/forum/t/1372055/m/1372055
ДинамическийСписок = ирОбщий.ДанныеЭлементаФормыЛкс(ОсновнойЭУ);
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ДинамическийСписок));
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ПолноеИмяТаблицы = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
ТипТаблицы = ирОбщий.ТипТаблицыБДЛкс(ПолноеИмяТаблицы);
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ПолноеИмяМД);
КорневойТип = ПеревестиВРусский(КорневойТип);
СтруктураХраненияТаблицы = СтруктураХраненияОсновнойТаблицыМДЛкс(ПолноеИмяМД);
ИмяПроведен = ПеревестиСтроку("Проведен");
ИмяСсылка = ПеревестиСтроку("Ссылка");
ИмяАктивность = ПеревестиСтроку("Активность");
ИмяПометкаУдаления = ПеревестиСтроку("ПометкаУдаления");
ИмяПредопределенный = ПеревестиСтроку("Предопределенный");
ИмяКартинка = ПеревестиСтроку("Картинка");
ВерсияПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
Если КорневойТип <> "РегистрБухгалтерии" Тогда
ОсновнойЭУ.СоздатьКолонки();
КонецЕсли;
Попытка
КолонкиСписка = ОсновнойЭУ.Значение.Колонки;
Исключение
// Перечисление
КонецПопытки;
КолонкиТП = ОсновнойЭУ.Колонки;
КолонкаТП = КолонкиТП.Найти(ИмяКартинка);
// Антибаг платформы. Почему то платформа локализует имя этой колонки "Картинка" в зависимости от кода языка интерфейса.
Если КолонкаТП = Неопределено Тогда
КолонкаТП = КолонкиТП.Найти("Picture");
КонецЕсли;
Если КолонкаТП = Неопределено Тогда
КолонкаТП = КолонкиТП.Найти("Картинка");
КонецЕсли;
Если КолонкаТП = Неопределено Тогда
КолонкаКартинки = КолонкиТП.Добавить(ИмяКартинка);
КолонкаКартинки.ОтображатьСтандартнуюКартинку = Истина;
КолонкаКартинки.Ширина = МинимальнаяШиринаКолонкиЛкс();
КолонкаКартинки.ИзменениеРазмера = ИзменениеРазмераКолонки.НеИзменять;
КолонкаКартинки.ТекстШапки = "";
КонецЕсли;
Попытка
НастройкаПорядка = ОсновнойЭУ.НастройкаПорядка;
Исключение
НастройкаПорядка = Неопределено;
КонецПопытки;
МинимальнаяШиринаКолонки = МинимальнаяШиринаКолонкиЛкс();
КоличествоВидимыхКолонок = 0;
Если КолонкиСписка <> Неопределено Тогда
// Здесь добавляется колонка "Предопределенный", т.к. в отборе она отсутствует
Для Каждого КолонкаСписка Из ОсновнойЭУ.Значение.Колонки Цикл
КолонкаТП = КолонкиТП.Найти(КолонкаСписка.Имя);
Если КолонкаТП = Неопределено Тогда
КолонкаТП = КолонкиТП.Добавить(КолонкаСписка.Имя);
Попытка
КолонкаТП.Данные = КолонкаСписка.Имя;
Исключение
// Например поле "Ссылка" почему то является недопустимым
КолонкиТП.Удалить(КолонкаТП);
Продолжить;
КонецПопытки;
КонецЕсли;
КолонкаТП.ТекстШапки = КолонкаСписка.Имя;
ЭлементОтбора = ОсновнойЭУ.Значение.Отбор.Найти(КолонкаСписка.Имя);
Если Истина
И КолонкаСписка.Имя = ИмяПредопределенный
И ЭлементОтбора = Неопределено
Тогда
КолонкаТП.КартинкаШапки = ирКэш.КартинкаПоИмениЛкс("ирПредопределенный");
НастроитьКолонкуКартинкиЛкс(КолонкаТП);
КонецЕсли;
Если ЭлементОтбора <> Неопределено И ЛиОписаниеТиповБулевоЛкс(ЭлементОтбора.ТипЗначения) Тогда // https://www.hostedredmine.com/issues/905911
Если КолонкаСписка.Имя = ИмяПометкаУдаления Тогда
КолонкаТП.КартинкаШапки = ирКэш.КартинкаПоИмениЛкс("ПометитьНаУдаление");
НастроитьКолонкуКартинкиЛкс(КолонкаТП);
КонецЕсли;
Если КолонкаСписка.Имя = ИмяПроведен Тогда
КолонкаТП.КартинкаШапки = ирКэш.КартинкаПоИмениЛкс("Провести");
НастроитьКолонкуКартинкиЛкс(КолонкаТП);
КонецЕсли;
Если КолонкаСписка.Имя = ИмяАктивность Тогда
КолонкаТП.КартинкаШапки = ирКэш.КартинкаПоИмениЛкс("ПереключитьАктивность");
НастроитьКолонкуКартинкиЛкс(КолонкаТП);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Попытка
ЛиРедактированиеВСписке = ОсновнойЭУ.СпособРедактирования = СпособРедактированияСписка.ВСписке;
Исключение
ЛиРедактированиеВСписке = Ложь;
КонецПопытки;
Для Каждого ЭлементОтбора Из ОсновнойЭУ.Значение.Отбор Цикл
#Если Сервер И Не Сервер Тогда
ЭлементОтбора = Новый ПостроительЗапроса;
ЭлементОтбора = ЭлементОтбора.Отбор.Добавить();
#КонецЕсли
// Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1002521#1002521
Если Истина
И ЛиКорневойТипРегистраБухгалтерииЛкс(КорневойТип)
И (Ложь
Или Найти(ЭлементОтбора.Имя, "ВидСубконтоДт") = 1
Или Найти(ЭлементОтбора.Имя, "ВидСубконтоКт") = 1)
Тогда
Продолжить;
КонецЕсли;
Если Истина
И ЛиКорневойТипСсылкиЛкс(КорневойТип)
И ЭлементОтбора.Имя = ИмяСсылка
Тогда
// Добавить для него колонку можно, но платформа не будет выводить в нее данные и потому она будет просто занимать площадь
Продолжить;
КонецЕсли;
Если КолонкиСписка <> Неопределено Тогда
АвтоудалениеКолонки = ЛиОписаниеТиповНеограниченнойСтрокиЛкс(ЭлементОтбора.ТипЗначения);
Попытка
КолонкиСписка.Добавить(ЭлементОтбора.Имя, АвтоудалениеКолонки);
Исключение
// Сюда попадает например элемент отбора от критерия отбора
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
Продолжить;
КонецПопытки;
КонецЕсли;
КолонкаТП = КолонкиТП.Найти(ЭлементОтбора.Имя);
Если КолонкаТП = Неопределено Тогда
КолонкаТП = КолонкиТП.Добавить();
КонецЕсли;
//Колонка.ТекстШапки = ЭлементОтбора.Представление;
Если КорневойТип <> "Перечисление" Тогда
Если ЛиРедактированиеВСписке Тогда
КолонкаТП.УстановитьЭлементУправления(Тип("ПолеВвода"));
КонецЕсли;
ДанныеПодключены = Ложь;
Попытка
КолонкаТП.Данные = ЭлементОтбора.Имя;
ДанныеПодключены = Истина;
Исключение
// Например поле "Ссылка" почему то является недопустимым
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
КонецПопытки;
Если Не ДанныеПодключены Тогда
КолонкаТП.Видимость = Ложь;
КонецЕсли;
КонецЕсли;
Если КоличествоВидимыхКолонок > ПредельноеКоличествоВидимыхКолонок Тогда
КолонкаТП.Видимость = Ложь;
Иначе
КоличествоВидимыхКолонок = КоличествоВидимыхКолонок + 1;
КонецЕсли;
КолонкаТП.Имя = ЭлементОтбора.Имя;
// Антибаг платформы 8.2-8.3.6 https://partners.v8.1c.ru/forum/t/1337995/m/1337995
Если Истина
И ВерсияПлатформы < 803008
И ЭлементОтбора.ТипЗначения.СодержитТип(Тип("УникальныйИдентификатор"))
Тогда
СообщитьЛкс(СтрШаблонИменЛкс("Колонка %1 типа УникальныйИдентификатор не будет отображаться из-за ошибки платформы",, ЭлементОтбора.Имя));
КолонкиТП.Удалить(КолонкаТП);
Продолжить;
КонецЕсли;
Если РазрешитьСортировку И НастройкаПорядка <> Неопределено Тогда
ЭлементУправленияПорядком = НастройкаПорядка.Найти(ЭлементОтбора.Имя);
Если ЭлементУправленияПорядком <> Неопределено Тогда
ЭлементУправленияПорядком.Доступность = Истина;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если КолонкиСписка <> Неопределено Тогда
Для Каждого ЭлементНастройкиОтбора Из ОсновнойЭУ.НастройкаОтбора Цикл
ЭлементНастройкиОтбора.Доступность = Истина;
КонецЦикла;
ПостроительПорядка = ОсновнойПорядокТаблицыБДЛкс(ПолноеИмяТаблицы, ирОбщий.ПорядокВСтрокуЛкс(ДинамическийСписок.Порядок), ОсновнойЭУ.НастройкаПорядка, СтруктураХраненияТаблицы);
НовыйПорядок = ПорядокВСтрокуЛкс(ПостроительПорядка.Порядок);
Если ЗначениеЗаполнено(НовыйПорядок) Тогда
// Обязательную установку делаем, чтобы в шапках появились индикаторы сортировки (антибаг платформы)
ДинамическийСписок.Порядок.Установить(НовыйПорядок);
КонецЕсли;
КонецЕсли;
Если ЛиКорневойТипСсылкиЛкс(КорневойТип) Тогда
КолонкаИдентификатора = КолонкиТП.Добавить("ИдентификаторСсылкиЛкс");
КолонкаИдентификатора.ТекстШапки = "Идентификатор ссылки";
КонецЕсли;
Если ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда
КолонкаИдентификатора = КолонкиТП.Добавить("ИмяПредопределенныхДанных");
КолонкаИдентификатора.ТекстШапки = "Имя предопределенных данных";
КолонкаИдентификатора.Видимость = Ложь;
КонецЕсли;
НастроитьЗаголовкиАвтоТабличногоПоляДинамическогоСпискаЛкс(ОсновнойЭУ, РежимИмяСиноним);
КонецПроцедуры
Процедура Форма_ОбработкаОповещенияЛкс(ЭтаФорма, ИмяСобытия, Параметр, Источник) Экспорт
Если ИмяСобытия = "ЗакрытьВсеФормыИнструментовРазработчика" Тогда
Если ЭтаФорма.Открыта() Тогда
ЭтаФорма.Закрыть();
Если ЭтаФорма.Открыта() Тогда
Параметр.Отказ = Истина;
КонецЕсли;
КонецЕсли;
ИначеЕсли ИмяСобытия = "ЕстьОткрытыеФормыИнструментовРазработчика" Тогда
Если ЭтаФорма.Открыта() Тогда
Параметр.Ответ = Истина;
КонецЕсли;
ИначеЕсли ИмяСобытия = "ОбнаружитьСебя" Тогда
ИмяФормы = ИмяФормыИзФормыЛкс(ЭтаФорма);
Если Не ЗначениеЗаполнено(ИмяФормы) Тогда
Попытка
ИмяФормы = ЭтаФорма.ЭтотОбъект.Метаданные().ПолноеИмя();
Исключение
КонецПопытки;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяФормы) Тогда
ИмяФормы = "Неизвестная форма";
КонецЕсли;
СообщитьЛкс(ИмяФормы);
ИначеЕсли ИмяСобытия = "ОбнаружитьАктивную" Тогда
Если Форма_ВводДоступенЛкс(ЭтаФорма) Тогда
Параметр.Результат = ЭтаФорма;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Умеет определять активную форму инструментов и управляемую форму в управляемом приложении
Функция АктивнаяФормаЛкс() Экспорт
Результат = АктивнаяУправляемаяФормаЛкс();
Если Результат = Неопределено Тогда
Структура = Новый Структура("Результат");
Структура.Вставить("ПроверятьПолеHTML", Ложь);
ОповеститьФормыПодсистемыЛкс("ОбнаружитьАктивную", Структура);
Если Структура.Результат = Неопределено Тогда
Структура.Вставить("ПроверятьПолеHTML", Истина);
ОповеститьФормыПодсистемыЛкс("ОбнаружитьАктивную", Структура);
КонецЕсли;
Результат = Структура.Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОткрытьФайлСПредупреждениемЛкс(ИмяФайла, СтандартнаяОбработка = Неопределено) Экспорт
СтандартнаяОбработка = Ложь;
Ответ = Вопрос("Вы уверены, что хотите открыть """ + ИмяФайла + """?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
ЗапуститьПриложение(ИмяФайла);
КонецЕсли;
КонецПроцедуры
// Создает новый экземпляр обработки и открывает его форму.
//
// Параметры:
// Объект - ОбработкаОбъект, ОтчетОбъект.
//
// Возвращаемое значение:
// Форма.
//
Функция ОткрытьНовоеОкноФормыЛкс(ЭтотОбъект) Экспорт
Если Ложь
Или ТипЗнч(ЭтотОбъект) = Тип("Форма")
Или ТипЗнч(ЭтотОбъект) = Тип("УправляемаяФорма")
Тогда
СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтотОбъект);
Если СлужебныеДанныеФормы.Свойство("МенеджерСохраненияНастроек") Тогда
ирОбщий.СохранитьНастройкуФормыЛкс(ЭтотОбъект);
КонецЕсли;
Результат = ПолучитьФормуЛкс(ИмяФормыИзФормыЛкс(ЭтотОбъект),,, Новый УникальныйИдентификатор);
Иначе
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
НовыйОбъект = ПолучитьМенеджерЛкс(ЭтотОбъект).Создать();
Иначе
ПолноеИмяОбъекта = ЭтотОбъект.Метаданные().ПолноеИмя();
НовыйОбъект = СоздатьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяОбъекта);
КонецЕсли;
Результат = НовыйОбъект.ПолучитьФорму();
КонецЕсли;
Результат.Открыть();
Возврат Результат;
КонецФункции
Функция ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры = Неопределено, Владелец = Неопределено, Уникальность = Неопределено, Окно = Неопределено, ТолькоВнешниеФормы = Ложь) Экспорт
Фрагменты = СтрРазделитьЛкс(ПолноеИмяФормы);
#Если Сервер И Не Сервер Тогда
Фрагменты = Новый Массив;
#КонецЕсли
Если Истина
И Фрагменты.Количество() = 4
И СтрокиРавныЛкс(Фрагменты[2], "Форма")
Тогда
ИмяФормы = Фрагменты[3];
Иначе
ИмяФормы = Неопределено;
КонецЕсли;
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
//ирПортативный #Если Сервер И Не Сервер Тогда
// Такой прием нужен для обхода ошибка компиляции в портативном режиме
#Если Сервер И Не Сервер Тогда
Фрагменты = Новый Массив;
#КонецЕсли
// http://www.hostedredmine.com/issues/883626
Если Истина
И (Фрагменты[0] = "Обработка" Или Фрагменты[0] = "Отчет")
И Фрагменты.Количество() > 2
И Найти(Фрагменты[1], "ир") = 1
И Фрагменты[1] <> Метаданные.Обработки.ирДинамическийСписок.Имя
Тогда
Если Не ТолькоВнешниеФормы Тогда
ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(Фрагменты[0] + "." + Фрагменты[1]);
КонецЕсли;
Если ОбъектМД = Неопределено Тогда
ВызватьИсключение "Не найден объект метаданных " + ПолноеИмяФормы;
КонецЕсли;
Если ОбъектМД = Метаданные.Обработки.ирПлатформа Тогда
Менеджер = ирКэш.Получить(); // Так управляемые формы нельзя получать
Иначе
Менеджер = Новый (ПеревестиСтроку(Фрагменты[0]) + ПеревестиСтроку("Менеджер") + "." + Фрагменты[1]);
КонецЕсли;
Результат = Менеджер.ПолучитьФорму(ИмяФормы, Владелец, Уникальность);
КонецЕсли;
Если Результат = Неопределено Тогда
// Форма не инструмента или управляемая форма инструмента
Результат = ПолучитьФорму(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
КонецЕсли;
//Если Найти(ПолноеИмяФормы, "Обработка.ирПлатформа.") = 1 Тогда
// Попытка
// ЭтоЗапрещено = Результат.ЭтотОбъект.Метаданные().ПолноеИмя() = ПеревестиСтроку("Обработка") + ".ирПлатформа";
// Исключение
// ЭтоЗапрещено = Ложь;
// КонецПопытки;
// Если ЭтоЗапрещено Тогда
// СообщитьЛкс("Создан лишний экземпляр обработки ирПлатформа");
// КонецЕсли;
//КонецЕсли;
//ирПортативный #КонецЕсли
Иначе
Если Не ТолькоВнешниеФормы Тогда
ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(Фрагменты[0] + "." + Фрагменты[1]);
КонецЕсли;
Если ОбъектМД = Неопределено Тогда
Если Фрагменты[1] = "ирПортативный" Тогда
Результат = ирПортативный.ПолучитьФорму(ИмяФормы, Владелец, Уникальность);
Иначе
ТипМетаданных = Фрагменты[0];
Менеджер = ирПортативный.ПолучитьМенеджерТипаМетаданныхЛкс(ТипМетаданных);
ПолноеИмяФайла = ирПортативный.ПолноеИмяФайлаПортативногоОбъектаМетаданныхЛкс(Фрагменты[1], ТипМетаданных);
Результат = Менеджер.ПолучитьФорму(ПолноеИмяФайла, ИмяФормы, Владелец, Уникальность);
КонецЕсли;
Иначе
Результат = ирПортативный.ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПараметрыБыстрогоСозданияФормыЛкс() Экспорт
Возврат Новый Структура("АвтоТест");
КонецФункции
Функция ОписаниеОповещенияЛкс(ИмяМетода, Модуль) Экспорт
ОписаниеОповещения = Вычислить("Новый ОписаниеОповещения(ИмяМетода, Модуль)"); // В 8.2 нет типа ОписаниеОповещения
Возврат ОписаниеОповещения;
КонецФункции
Процедура ЗаполнитьСписокВыбораПоляСортировкиТабличногоПоляЛкс(Знач СписокВыбора, Знач ТабличноеПоле) Экспорт
#Если Сервер И Не Сервер Тогда
СписокВыбора = Новый СписокЗначений;
#КонецЕсли
СписокВыбора.Очистить();
Для Каждого КолонкаТП Из ТабличноеПоле.Колонки Цикл
Если Истина
И ЗначениеЗаполнено(КолонкаТП.Данные)
И (КолонкаТП.Видимость Или КолонкаТП.ИзменятьВидимость)
//И Не (КолонкаТП.ТипЗначения.СодержитТип(Тип("УникальныйИдентификатор")) И КолонкаТП.ТипЗначения.Типы() = 1)
Тогда
СписокВыбора.Добавить(КолонкаТП.Данные + " Убыв", КолонкаТП.ТекстШапки + " Убыв");
СписокВыбора.Добавить(КолонкаТП.Данные + " Возр", КолонкаТП.ТекстШапки + " Возр");
КонецЕсли;
КонецЦикла;
СписокВыбора.СортироватьПоПредставлению();
КонецПроцедуры
Функция СсылкаОсновногоОбъектаФормыЛкс(Знач ТекущаяФорма) Экспорт
ИмяОсновногоРеквизита = "Объект";
Попытка
Ссылка = ТекущаяФорма[ИмяОсновногоРеквизита].Ссылка;
Исключение
ИмяОсновногоРеквизита = ирОбщий.ПеревестиСтроку(ИмяОсновногоРеквизита);
Ссылка = Неопределено;
КонецПопытки;
Если Ссылка = Неопределено Тогда
Попытка
Ссылка = ТекущаяФорма[ИмяОсновногоРеквизита].Ссылка;
Исключение
Ссылка = Неопределено;
КонецПопытки;
КонецЕсли;
Возврат Ссылка;
КонецФункции
Функция ПолучитьЦветСтиляЛкс(ИмяЦвета) Экспорт
//Результат = ирПортативный.ПолучитьЦветСтиляЛкс(Имя);
Если ИмяЦвета = "ирТекстИнформационнойНадписи" Тогда
Возврат Новый Цвет(83, 106, 194);
ИначеЕсли ИмяЦвета = "ирЦветФонаЧередованияСтрок" Тогда
//Возврат WebЦвета.МятныйКрем;
Возврат Новый Цвет(240, 255, 225);
ИначеЕсли ИмяЦвета = "ирЦветФонаВычисляемогоЗначения" Тогда
Возврат WebЦвета.ГолубойСКраснымОттенком;
ИначеЕсли ИмяЦвета = "ирЦветФонаОшибки" Тогда
Возврат Новый Цвет(255, 235, 235);
ИначеЕсли ИмяЦвета = "ирЦветФонаРасширенногоПредставленияЗначения" Тогда
Возврат Новый Цвет(255, 255, 180);
Иначе
Результат = ЦветаСтиля[ИмяЦвета];
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЧислоHEXВЦветЛкс(ЧислоHEX) Экспорт
Красный = СтрокаHEXtoINTЛкс(Лев(ЧислоHEX, 2));
Зеленый = СтрокаHEXtoINTЛкс(Сред(ЧислоHEX, 3, 2));
Синий = СтрокаHEXtoINTЛкс(Сред(ЧислоHEX, 5, 2));
Результат = Новый Цвет(Красный, Зеленый, Синий);
Возврат Результат;
КонецФункции
// Параметры:
// Значение -
// ОчиститьПередУстановкой - Булево
// УстановитьТекст - Булево
// УстановитьЗначение - Булево
//
Функция БуферОбменаПриложения_УстановитьЗначениеЛкс(Знач Значение) Экспорт
//ФорматБуфераОбмена1С = ирКэш.ФорматБуфераОбмена1СЛкс();
Если ЛиСсылкаНаОбъектБДЛкс(Значение, Ложь) Тогда
ДобавитьСсылкуВИсториюРаботыЛкс(Значение);
КонецЕсли;
Значение = ОбъектВСтрокуXMLЛкс(Значение,,, Ложь);
ВнутреннийБуферОбмена = БуферОбменаПриложенияЛкс();
ВнутреннийБуферОбмена.Значение = Значение;
Если ЛиСсылкаНаОбъектБДЛкс(Значение) Тогда
ДобавитьОбъектВБуферСравненияЛкс(Значение);
КонецЕсли;
КонецФункции
Функция БуферОбменаПриложения_ЗначениеЛкс() Экспорт
//ФорматБуфераОбмена1С = ирКэш.ФорматБуфераОбмена1СЛкс();
ВнутреннийБуферОбмена = БуферОбменаПриложенияЛкс();
Результат = ВнутреннийБуферОбмена.Значение;
Результат = ОбъектИзСтрокиXMLЛкс(Результат,,, Ложь);
Возврат Результат;
КонецФункции
Функция БуферОбменаПриложенияЛкс()
ВнутреннийБуферОбмена = ирКэш.Получить().ВнутреннийБуферОбмена;
Если ВнутреннийБуферОбмена = Неопределено Тогда
ВнутреннийБуферОбмена = Новый Структура("Значение");
ирКэш.Получить().ВнутреннийБуферОбмена = ВнутреннийБуферОбмена;
КонецЕсли;
Возврат ВнутреннийБуферОбмена;
КонецФункции
Функция ЗначениеИзБуфераОбменаЛкс() Экспорт
ТекстИзБуфера = ТекстИзБуфераОбменаОСЛкс();
ЗначениеСсылки = НавигационнаяСсылкаВЗначениеЛкс(ТекстИзБуфера);
Если ЗначениеСсылки = Неопределено Тогда
ЗначениеСсылки = БуферОбменаПриложения_ЗначениеЛкс();
КонецЕсли;
Возврат ЗначениеСсылки;
КонецФункции
// Параметры:
// ПолеВвода - ПолеВвода
// Значение -
// Текст - Строка(0,П)
//
Функция ВставитьЗначениеВПолеВводаЛкс(Знач ПолеВвода, Знач НовоеЗначение) Экспорт
Результат = Ложь;
Если Истина
И НовоеЗначение <> Неопределено
И Не ПолеВвода.ТолькоПросмотр
Тогда
ТипНовогоЗначения = ТипЗнч(НовоеЗначение);
ТекущееЗначение = ДанныеЭлементаФормыЛкс(ПолеВвода);
Если Ложь
Или ТипЗнч(ТекущееЗначение) = ТипНовогоЗначения
Или ПолеВвода.ОграничениеТипа.Типы().Количество() = 0
Или ПолеВвода.ОграничениеТипа.СодержитТип(ТипНовогоЗначения)
Тогда
Результат = ИнтерактивноЗаписатьВЭлементУправленияЛкс(ПолеВвода, НовоеЗначение,, Истина);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ЭтаФорма - Форма - для управляемой формы можно не передавать, она определится автоматически
//
Функция БуферОбмена_ВставитьЛкс(Знач ЭтаФорма = Неопределено) Экспорт
Если ЭтаФорма = Неопределено Тогда
ЭтаФорма = ирОбщий.АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если ЭтаФорма = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Значение = ЗначениеИзБуфераОбменаЛкс();
Если Значение = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ВставитьЗначениеВФормуЛкс(ЭтаФорма, Значение);
КонецФункции
Процедура ВставитьЗначениеВФормуЛкс(Знач ЭтаФорма, Знач Значение) Экспорт
ТекущийЭлементФормы = ЭтаФорма.ТекущийЭлемент;
ПродолжитьОбработку = Истина;
ТипЗначения = ТипЗнч(Значение);
ПутьКДанным = "";
Если Ложь
Или ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеВвода")
Или ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеФормы")
Тогда
Если Не ЭтаФорма.ТолькоПросмотр Тогда
Если ТипЗначения = Тип("Массив") Тогда
Значение = Значение[0];
КонецЕсли;
Если ЛиОписаниеТиповСодержитТипЛкс(ТекущийЭлементФормы.ОграничениеТипа, ТипЗнч(Значение)) Тогда
ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ТекущийЭлементФормы, Значение);
КонецЕсли;
//Если ПродолжитьОбработку И ЗначениеЗаполнено(ТекущийЭлементФормы.Данные) Тогда
// // Например ссылка таблицы внешнего источника в поле ввода не может быть установлена через оповещение выбора
// Попытка
// ЭтаФорма[ТекущийЭлементФормы.Данные] = Значение;
// Исключение
// КонецПопытки;
//КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле")
Или ТипЗнч(ТекущийЭлементФормы) = Тип("ТаблицаФормы")
Тогда
Попытка
РедактированиеВДиалоге = ТекущийЭлементФормы.СпособРедактирования = СпособРедактированияСписка.ВДиалоге;
Исключение
РедактированиеВДиалоге = Ложь;
КонецПопытки;
ЭлементУправления = Неопределено;
КолонкаТП = Неопределено;
Если Истина
И Не РедактированиеВДиалоге
И Не ЭтаФорма.ТолькоПросмотр
И Не ТекущийЭлементФормы.ТолькоПросмотр
Тогда
ДобавитьСтроку = Истина
И ТекущийЭлементФормы.ТекущиеДанные = Неопределено
И ТекущийЭлементФормы.ИзменятьСоставСтрок;
ДоступноРедактирование = Истина;
Если Не ДобавитьСтроку Или ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено Тогда
КолонкаТП = ТабличноеПоле_ТекущаяКолонкаЛкс(ТекущийЭлементФормы, ЭлементУправления, ДоступноРедактирование);
КонецЕсли;
Если Истина
И Значение <> Неопределено
И ТекущийЭлементФормы.ИзменятьСоставСтрок
И Не ДобавитьСтроку
И ДоступноРедактирование
Тогда
Ответ = Вопрос("Выполнить вставку значения в новую строку (иначе будет выполнена вставка в текущую)?", РежимДиалогаВопрос.ДаНет, ,
КодВозвратаДиалога.Нет);
ДобавитьСтроку = Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если ДобавитьСтроку Тогда
ТекущийЭлементФормы.ДобавитьСтроку();
Если КолонкаТП = Неопределено Тогда
КолонкаТП = ТабличноеПоле_ТекущаяКолонкаЛкс(ТекущийЭлементФормы, ЭлементУправления, ДоступноРедактирование); // Текущая колонка могла измениться в ПриНачалеРедактированияСтроки
Иначе
ТабличноеПоле_УстановитьТекущуюКолонкуЛкс(ТекущийЭлементФормы, КолонкаТП);
КонецЕсли;
КонецЕсли;
Если ЭлементУправления <> Неопределено Тогда
Если ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено Тогда
ТекущийЭлементФормы.ИзменитьСтроку(); // Нужно делать, т.к. табличное поле выходит из режима редактирования строки при вызове команды и иногда установке текущей колонки
КонецЕсли;
Если ТекущийЭлементФормы.ТекущиеДанные <> Неопределено Тогда
ОграничениеТипа = ЭлементУправления.ОграничениеТипа;
ПродолжитьОбработку = Истина;
Если ЛиОписаниеТиповСодержитТипЛкс(ОграничениеТипа, ТипЗначения) Тогда
ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ЭлементУправления, Значение);
КонецЕсли;
Если ПродолжитьОбработку Тогда
Если ТипЗначения = Тип("Массив") И Значение.Количество() > 0 Тогда
Значение = Значение[0];
ЗначениеИзменено = Истина;
ИначеЕсли ТипЗначения = Тип("СписокЗначений") И Значение.Количество() > 0 Тогда
Значение = Значение[0].Значение;
ЗначениеИзменено = Истина;
Иначе
ЗначениеИзменено = Ложь;
КонецЕсли;
Если Истина
И ЗначениеИзменено
И ЛиОписаниеТиповСодержитТипЛкс(ОграничениеТипа, ТипЗнч(Значение))
Тогда
ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ЭлементУправления, Значение);
КонецЕсли;
КонецЕсли;
ИмяКолонкиДанных = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТекущийЭлементФормы);
Если Истина
И ПродолжитьОбработку
И ЗначениеЗаполнено(ИмяКолонкиДанных)
И ЛиВКолонкеДоступнаЭмуляцияИнтерактивногоИзмененияЛкс(КолонкаТП)
И ЛиОписаниеТиповСодержитТипЛкс(ОграничениеТипа, ТипЗнч(Значение))
Тогда
// Например ссылка таблицы внешнего источника в поле ввода не может быть установлена через оповещение выбора
Если ТипЗнч(ТекущийЭлементФормы.ТекущиеДанные) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
ИмяКолонкиДанных = ПервыйФрагментЛкс(ИмяКолонкиДанных, "Для");
КонецЕсли;
Попытка
ТекущийЭлементФормы.ТекущиеДанные[ИмяКолонкиДанных] = Значение;
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ЛиОписаниеТиповСодержитТипЛкс(Знач ОграничениеТипа, Знач Тип) Экспорт
Возврат Ложь
Или ОграничениеТипа.Типы().Количество() = 0
Или ОграничениеТипа.СодержитТип(Тип);
КонецФункции
Процедура НайтиСсылкуИзБуфераВТаблицеФормыЛкс(ЭтаФорма) Экспорт
#Если Сервер И Не Сервер Тогда
ЭтаФорма = ПолучитьОбщуюФорму();
#КонецЕсли
ИскомоеЗначение = ЗначениеИзБуфераОбменаЛкс();
Если ИскомоеЗначение = Неопределено Тогда
Возврат;
КонецЕсли;
ТаблицаФормы = ЭтаФорма.ТекущийЭлемент;
ПродолжитьОбработку = Истина;
ТипЗначения = ТипЗнч(ИскомоеЗначение);
Если ОбщийТипДанныхТабличногоПоляЛкс(ТаблицаФормы) = "Список" Тогда
ДинамическийСписокУстановитьТекущуюСтрокуСКонтролемЛкс(ТаблицаФормы, ИскомоеЗначение, ЭтаФорма);
Иначе
ИмяКолонкиДанных = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТаблицаФормы);
ДанныеТаблицы = ДанныеЭлементаФормыЛкс(ТаблицаФормы,,, Истина);
ТаблицаИлиДеревоЗначений = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТаблицаФормы,, Истина, Ложь,,, ЭтаФорма);
Если ТипЗнч(ТаблицаИлиДеревоЗначений) = Тип("ДеревоЗначений") Тогда
#Если Сервер И Не Сервер Тогда
ТаблицаИлиДеревоЗначений = Новый ДеревоЗначений;
#КонецЕсли
НайденнаяСтрока = ТаблицаИлиДеревоЗначений.Строки.Найти(ИскомоеЗначение, ИмяКолонкиДанных, Истина);
Если НайденнаяСтрока = Неопределено Тогда
СообщитьЛкс("Значение в колонке не найдено");
Иначе
ПутьКСтроке = Дерево_ПутьСтрокойЛкс(НайденнаяСтрока, "",,, ТаблицаИлиДеревоЗначений);
СтрокаТаблицыФормы = Дерево_НайтиПоПутиСтрокойЛкс(ДанныеТаблицы, "", ПутьКСтроке);
Если ТипЗнч(ТаблицаФормы) = Тип("ТаблицаФормы") Тогда
Если СтрокаТаблицыФормы <> Неопределено Тогда
ТаблицаФормы.ТекущаяСтрока = СтрокаТаблицыФормы.ПолучитьИдентификатор();
КонецЕсли;
Иначе
ТаблицаФормы.ТекущаяСтрока = СтрокаТаблицыФормы;
КонецЕсли;
КонецЕсли;
Иначе
НайденнаяСтрока = ТаблицаИлиДеревоЗначений.Найти(ИскомоеЗначение, ИмяКолонкиДанных);
Если НайденнаяСтрока = Неопределено Тогда
СообщитьЛкс("Значение в колонке не найдено");
Иначе
СтрокаТаблицыФормы = ДанныеТаблицы[ТаблицаИлиДеревоЗначений.Индекс(НайденнаяСтрока)];
Если ТипЗнч(ТаблицаФормы) = Тип("ТаблицаФормы") Тогда
ТаблицаФормы.ТекущаяСтрока = СтрокаТаблицыФормы.ПолучитьИдентификатор();
Иначе
ТаблицаФормы.ТекущаяСтрока = СтрокаТаблицыФормы;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура КопироватьСсылкуАктивнойСтрокиФормыЛкс(Форма) Экспорт
КлючТекущейСтроки = Неопределено;
ирОбщий.КлючиСтрокБДИзТаблицыФормыЛкс(Форма, КлючТекущейСтроки);
Если КлючТекущейСтроки <> Неопределено Тогда
ирОбщий.БуферОбменаПриложения_УстановитьЗначениеЛкс(КлючТекущейСтроки);
КонецЕсли;
КонецПроцедуры
// Параметры:
// ЭтаФорма - Форма - для управляемой формы можно не передавать, она определится автоматически
//
Функция БуферОбмена_КопироватьЛкс(Знач ЭтаФорма = Неопределено) Экспорт
Если ЭтаФорма = Неопределено Тогда
ЭтаФорма = ирОбщий.АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если ЭтаФорма = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Значение = Форма_ЗначениеТекущегоПоляЛкс(ЭтаФорма, Истина);
Если Значение <> Неопределено Тогда
БуферОбменаПриложения_УстановитьЗначениеЛкс(Значение);
Иначе
КопироватьСсылкуАктивнойСтрокиФормыЛкс(ЭтаФорма);
КонецЕсли;
КонецФункции
Функция Форма_ЗначениеТекущегоПоляЛкс(ЭтаФорма, ДляКопирования = Ложь) Экспорт
Значение = ирОбщий.СсылкиИзТекущейКолонкиВыделенныхСтрокТаблицыЛкс(ЭтаФорма,, Истина);
ЕстьСсылкиВТекущемПоле = Значение.Количество() > 0;
Если Значение.Количество() = 1 Тогда
Значение = Значение[0];
КонецЕсли;
Если Не ЕстьСсылкиВТекущемПоле Тогда
Значение = Неопределено;
ТекущийЭлементФормы = ЭтаФорма.ТекущийЭлемент;
Если ЛиПолеФормыИмеетТипЛкс(ТекущийЭлементФормы, Тип("ПолеВвода")) Тогда
Значение = ДанныеЭлементаФормыЛкс(ТекущийЭлементФормы);
//Текст = "" + ТекущийЭлементФормы.ВыделенныйТекст;
Если ДляКопирования И ТипЗнч(Значение) = Тип("Строка") Тогда
Значение = Неопределено;
КонецЕсли;
ИначеЕсли Ложь
Или ЛиПолеФормыИмеетТипЛкс(ТекущийЭлементФормы, Тип("ПолеТекстовогоДокумента"))
Или ЛиПолеФормыИмеетТипЛкс(ТекущийЭлементФормы, Тип("ПолеHTMLДокумента"))
Тогда
Если ДляКопирования Тогда
Если Истина
И ирКэш.НомерВерсииПлатформыЛкс() >= 803015
И ирКэш.НомерВерсииПлатформыЛкс() <= 803017
И ЛиПолеФормыИмеетТипЛкс(ТекущийЭлементФормы, Тип("ПолеHTMLДокумента"))
Тогда
ПолеТекста = ОболочкаПоляТекстаЛкс(ТекущийЭлементФормы);
// Антибаг платформы. Копирование в буфер обмена не выполняется платформой
ВыделенныйТекст = ПолеТекста.ВыделенныйТекст();
Если ВыделенныйТекст <> ТекстИзБуфераОбменаОСЛкс() Тогда
// Теряем оформление
ТекстВБуферОбменаОСЛкс(ВыделенныйТекст);
КонецЕсли;
КонецЕсли;
Иначе
ПолеТекста = ОболочкаПоляТекстаЛкс(ТекущийЭлементФормы);
Значение = ПолеТекста.ПолучитьТекст();
КонецЕсли;
ИначеЕсли ЛиПолеФормыИмеетТипЛкс(ТекущийЭлементФормы, Тип("ПолеТабличногоДокумента")) Тогда
#Если Сервер И Не Сервер Тогда
ТекущийЭлементФормы = Новый ТабличныйДокумент;
#КонецЕсли
Попытка
ДанныеРасшифровки = ЭтаФорма.ДанныеРасшифровки;
Исключение
ДанныеРасшифровки = Неопределено;
КонецПопытки;
Если ТекущийЭлементФормы.ТекущаяОбласть <> Неопределено Тогда
Если ДляКопирования Тогда
// Так будем терять оформление
//Значение = ТекущийЭлементФормы.ТекущаяОбласть.Текст;
//Если ПустаяСтрока(Прав(Значение, 1)) Тогда
// ТекстВБуферОбменаОСЛкс(Значение, "");
//КонецЕсли;
Если Истина
И ТипЗнч(ДанныеРасшифровки) = Тип("ДанныеРасшифровкиКомпоновкиДанных")
И ТекущийЭлементФормы.ТекущаяОбласть.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Прямоугольник
И ТипЗнч(ТекущийЭлементФормы.ТекущаяОбласть.Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных")
Тогда
ЭлементРасшифровки = ДанныеРасшифровки.Элементы[ТекущийЭлементФормы.ТекущаяОбласть.Расшифровка];
Для каждого ЗначениеПоля Из ЭлементРасшифровки.ПолучитьПоля() Цикл
Если Не ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение, Ложь) Тогда
Продолжить;
КонецЕсли;
Значение = ЗначениеПоля.Значение;
Прервать;
КонецЦикла;
КонецЕсли;
Иначе
Значение = ТекущийЭлементФормы.ТекущаяОбласть.Текст;
КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле") Тогда
//:ТекущийЭлементФормы = Новый ("ТабличноеПоле")
Если Истина
И ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено
И ТекущийЭлементФормы.ТекущаяКолонка <> Неопределено
Тогда
ТипСтрокиТаблицы = ТипЗнч(ТекущийЭлементФормы.ТекущаяСтрока);
Если Ложь
Или ТипСтрокиТаблицы = Тип("ДоступноеПолеКомпоновкиДанных")
Или ТипСтрокиТаблицы = Тип("ДоступноеПолеОтбораКомпоновкиДанных")
Тогда
Значение = ТекущийЭлементФормы.ТекущаяСтрока.Поле;
Иначе
Ячейка = ТекущийЭлементФормы.ОформлениеСтроки(ТекущийЭлементФормы.ТекущаяСтрока).Ячейки[ТекущийЭлементФормы.ТекущаяКолонка.Имя];
Если ДляКопирования Тогда
Значение = Ячейка.Значение;
Если ТипЗнч(Значение) = Тип("Строка") Тогда
Если ПустаяСтрока(Прав(Значение, 1)) Тогда
// https://www.hostedredmine.com/issues/910752
Массив = Новый Массив;
Массив.Добавить(ТекущийЭлементФормы.ТекущаяСтрока);
ПолноеИмяТаблицыБД = "";
ТипИсточника = ОбщийТипДанныхТабличногоПоляЛкс(ТекущийЭлементФормы,,, ПолноеИмяТаблицыБД);
Если Истина
И ТипИсточника = "Список"
И ЗначениеЗаполнено(ПолноеИмяТаблицыБД)
Тогда
ТаблицаЗначений = ПустаяТаблицаЗначенийИзТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Иначе
ТаблицаЗначений = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТекущийЭлементФормы, Массив);
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
Если ТаблицаЗначений <> Неопределено Тогда
КолонкаТаблицы = ТаблицаЗначений.Колонки.Найти(ПутьКДаннымКолонкиТабличногоПоляЛкс(ТекущийЭлементФормы));
Если Ложь
Или КолонкаТаблицы = Неопределено
Или КолонкаТаблицы.ТипЗначения.КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная
Тогда
ТекстВБуферОбменаОСЛкс(Значение, "");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Значение = Неопределено;
КонецЕсли;
Иначе
Значение = Ячейка.Текст;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Значение;
КонецФункции
Функция ОткрытьРазличныеЗначенияКолонкиЛкс(Знач ТабличноеПоле, Знач НастройкиСписка = Неопределено, Знач _АдресСхемыКомпоновки = Неопределено, ЭтаФорма = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Обработки.ирРазличныеЗначенияКолонки;
#КонецЕсли
Форма = ирОбщий.ПолучитьФормуЛкс("Обработка.ирРазличныеЗначенияКолонки.Форма",, ТабличноеПоле);
Форма.НастройкиСписка = НастройкиСписка;
Форма.АдресСхемыКомпоновки = _АдресСхемыКомпоновки;
Форма.Форма = ЭтаФорма;
РезультатФормы = Форма.ОткрытьМодально();
КонецФункции
Функция ОткрытьГруппировкуТабличногоПоляЛкс(Знач ТабличноеПоле, Знач НастройкиСписка = Неопределено, ИменаКлючевыхКолонок = "") Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Форма = мПлатформа.ПолучитьФорму("ГруппировкаТаблицы", ТабличноеПоле);
Форма.ПараметрНастройкаКомпоновки = НастройкиСписка;
Форма.ПараметрИменаКлючевыхКолонок = ИменаКлючевыхКолонок;
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Форма.ОткрытьМодально();
#Иначе
Форма.Открыть();
#КонецЕсли
КонецФункции
Процедура ПоказатьСсылкуНаМодульКонфигурацииЛкс(ПолноеИмяМодуля) Экспорт
Ссылка = СсылкаНаМодульКонфигурацииЛкс(ПолноеИмяМодуля);
ПоказатьСсылкуНаСтрокуМодуляЛкс(Ссылка);
КонецПроцедуры
Функция СсылкаНаМодульКонфигурацииЛкс(Знач ПолноеИмяМодуля) Экспорт
Возврат "{" + ПолноеИмяМодуля + "(1)}";
КонецФункции
Процедура ПоказатьСсылкуНаСтрокуМодуляЛкс(Знач Ссылка) Экспорт
Текст = //""
"
|" + Ссылка + "
|Запустите программу ClipAngel, скопируйте эту ссылку и откройте ее в конфигураторе через эту программу через ALT+клик
|"
//""
;
Форма = ФормаПросмотраHTMLЛкс(Текст);
Форма.ОткрытьМодально();
КонецПроцедуры
Функция ОписаниеМодуляПоИмениЛкс(Знач ИмяМодуля) Экспорт
ОписаниеМодуля = Новый Структура("Метаданные, ИмяФайлаМодуля");
Фрагменты = СтрРазделитьЛкс(ИмяМодуля);
#Если Сервер И Не Сервер Тогда
Фрагменты = Новый Массив;
#КонецЕсли
ТипМодуля = Фрагменты[Фрагменты.ВГраница()];
Если ТипМодуля = "Форма" Тогда
ТипМодуля = "Форма.Модуль";
КонецЕсли;
Фрагменты.Удалить(Фрагменты.ВГраница());
ИмяОбъектаМодуля = СтрСоединитьЛкс(Фрагменты, ".");
Если ЗначениеЗаполнено(ИмяОбъектаМодуля) Тогда
ОписаниеМодуля.Метаданные = ирКэш.ОбъектМДПоПолномуИмениЛкс(ирОбщий.ПоследнийФрагментЛкс(ИмяОбъектаМодуля, " "));
Если ОписаниеМодуля.Метаданные <> Неопределено Тогда
ОписаниеМодуля.ИмяФайлаМодуля = ОписаниеМодуля.Метаданные.ПолноеИмя() + "." + ТипМодуля;
Иначе
// Внешняя обработка
ОписаниеМодуля.ИмяФайлаМодуля = ИмяМодуля;
КонецЕсли;
Иначе
ОписаниеМодуля.Метаданные = Метаданные;
ОписаниеМодуля.ИмяФайлаМодуля = "Конфигурация" + "." + ТипМодуля;
КонецЕсли;
Возврат ОписаниеМодуля;
КонецФункции
Процедура ОткрытьОбъектМетаданныхПоИмениМодуляЛкс(Знач ПолноеИмяМодуля) Экспорт
ОписаниеМодуля = ОписаниеМодуляПоИмениЛкс(ПолноеИмяМодуля);
Если ОписаниеМодуля.Метаданные <> Неопределено Тогда
ОткрытьОбъектМетаданныхЛкс(ОписаниеМодуля.Метаданные);
КонецЕсли;
КонецПроцедуры
Процедура СкрытьПоказатьОднозначныеКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, Знач Скрыть = Истина, Знач ИгнорироватьКолонки = Неопределено) Экспорт
ОставитьТолькоРазличающиесяКолонки = Ложь;
Если Скрыть Тогда
// Включаем видимость тех колонок реквизитов, в каких есть различия между элементами группы, а у остальных выключаем
Если ТабличноеПоле.Значение.Количество() > 1 Тогда
ОставитьТолькоРазличающиесяКолонки = Истина;
КонецЕсли;
КонецЕсли;
Для Каждого КолонкаТП Из ТабличноеПоле.Колонки Цикл
Если Ложь
Или (Истина
И ИгнорироватьКолонки <> Неопределено
И ЗначениеЗаполнено(КолонкаТП.Данные)
И ИгнорироватьКолонки.Свойство(КолонкаТП.Данные))
Или ТабличноеПоле.Значение.Колонки.Найти(КолонкаТП.Данные) = Неопределено
Тогда
Продолжить;
КонецЕсли;
Если ОставитьТолькоРазличающиесяКолонки Тогда
ПервоеЗначение = ТабличноеПоле.Значение[0][КолонкаТП.Данные];
Для Индекс = 1 По ТабличноеПоле.Значение.Количество() - 1 Цикл
ТекущееЗначение = ТабличноеПоле.Значение[Индекс][КолонкаТП.Данные];
Если ПервоеЗначение <> ТекущееЗначение Тогда
Прервать;
КонецЕсли;
КонецЦикла;
НоваяВидимость = ПервоеЗначение <> ТекущееЗначение;
Иначе
НоваяВидимость = Истина;
КонецЕсли;
КолонкаТП.Видимость = НоваяВидимость;
КонецЦикла;
КонецПроцедуры
Процедура Форма_ПриОткрытииЛкс(ЭтаФорма) Экспорт
ирКэш.СостояниеПодготовкиКэшМДСеансаЛкс();
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
ЭтаФорма = ПолучитьОбщуюФорму();
#КонецЕсли
МодальныеГруппы = МодальныеГруппыЛкс();
#Если Сервер И Не Сервер Тогда
МодальныеГруппы = Новый Массив;
#КонецЕсли
Если ЭтаФорма.МодальныйРежим Тогда
МодальныеГруппы.Добавить(1);
#Если Сервер И Не Сервер Тогда
АктивироватьМодальныеГруппыЛкс();
#КонецЕсли
ПодключитьГлобальныйОбработчикОжиданияЛкс("АктивироватьМодальныеГруппыЛкс");
ИначеЕсли МодальныеГруппы.Количество() > 0 Тогда
ИндексГруппы = МодальныеГруппы.Количество() - 1;
МодальныеГруппы[ИндексГруппы].Значение = МодальныеГруппы[ИндексГруппы].Значение + 1;
КонецЕсли;
мПлатформа.ПодключитьПерехватКлавиатуры().ЗахватПервым = Ложь; // Используем не по назначению
Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда
ДобавитьВСписокОткрытыхФормЛкс(ЭтаФорма);
ДобавитьИнструментВИсториюРаботыЛкс(ЭтаФорма);
ПодготовитьПрямуюДоставкуСобытияФормыЛкс(ЭтаФорма, "ВнешнееСобытие");
ПодготовитьПрямуюДоставкуСобытияФормыЛкс(ЭтаФорма, "ОбработкаОповещения");
// Подготовка отображения колонков типа Булево
Для Каждого ЭлементФормы Из ЭтаФорма.ЭлементыФормы Цикл
Если ТипЗнч(ЭлементФормы) = Тип("ТабличноеПоле") Тогда
ТипИсточника = ОбщийТипДанныхТабличногоПоляЛкс(ЭлементФормы);
МакетТаблицы = Неопределено;
Если Ложь
Или ТипИсточника = "ТабличнаяЧасть"
Или ТипИсточника = "НаборЗаписей"
Или ТипИсточника = "ТаблицаЗначений"
Или ТипИсточника = "ДеревоЗначений"
Тогда
МакетТаблицы = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ЭлементФормы, Новый Массив);
КонецЕсли;
Если МакетТаблицы = Неопределено Тогда
// Динамический список
Продолжить;
КонецЕсли;
КолонкиДанных = МакетТаблицы.Колонки;
Для Каждого КолонкаТП Из ЭлементФормы.Колонки Цикл
КолонкаДанных = КолонкиДанных.Найти(КолонкаТП.Данные);
Если КолонкаДанных = Неопределено Или КолонкаТП.КартинкиСтрок.Вид <> ВидКартинки.Пустая Тогда
Продолжить;
КонецЕсли;
ТипЗначенияКолонки = Новый ОписаниеТипов(КолонкаДанных.ТипЗначения,, "Null");
ТипыРеквизита = ТипЗначенияКолонки.Типы();
Если ТипыРеквизита.Количество() = 1 И ТипыРеквизита[0] = Тип("Булево") Тогда
КолонкаТП.КартинкиСтрок = ирКэш.КартинкаПоИмениЛкс("ирСостоянияФлажка");
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
//ирОбщий.УстановитьПрикреплениеФормыВУправляемомПриложенииЛкс(Этаформа);
КонецЕсли;
Если Не ЭтаФорма.МодальныйРежим И МодальныеГруппы.Количество() > 0 Тогда
// Антибаг платформы https://www.hostedredmine.com/issues/926161
#Если Сервер И Не Сервер Тогда
АктивироватьАктивнуюФормуЛкс();
#КонецЕсли
ирОбщий.ПодключитьГлобальныйОбработчикОжиданияЛкс("АктивироватьАктивнуюФормуЛкс");
КонецЕсли;
КонецПроцедуры
Процедура ПодготовитьПрямуюДоставкуСобытияФормыЛкс(Знач ЭтаФорма, Знач ИмяСобытия)
ОбработчикСобытия = ЭтаФорма.ПолучитьДействие(ИмяСобытия);
Если Истина
И ОбработчикСобытия <> Неопределено
И Не МетодРеализованЛкс(ЭтаФорма, ОбработчикСобытия)
Тогда
СообщитьЛкс(СтрШаблонИменЛкс("В модуле %1 обработчик события %2 не является экспортным",, ИмяФормыИзФормыЛкс(ЭтаФорма), 2, ИмяСобытия), СтатусСообщения.Внимание);
КонецЕсли;
ЭтаФорма.УстановитьДействие(ИмяСобытия, Неопределено); // Будем вызывать напрямую, чтобы платформа не вызывала обновление всех форм
КонецПроцедуры
Процедура ДобавитьВСписокОткрытыхФормЛкс(ЭтаФорма) Экспорт
ирКэш.ОткрытыеФормыЛкс().Добавить(ЭтаФорма);
СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
СлужебныеДанныеФормы.Вставить("ДатаОткрытия", ТекущееВремяВМиллисекундахЛкс());
КонецПроцедуры
Процедура Форма_ПриЗакрытииЛкс(ЭтаФорма, СохранитьНастройкуПоУмолчанию = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ЭтаФорма = ОткрытьФорму();
#КонецЕсли
// У некоторых из-за большого объема данных в настройках пользователя это вызывает большие задержки
//ПодключитьГлобальныйОбработчикОжиданияЛкс("СохранитьНастройкиПользователяОтложенноЛкс");
СохранитьНастройкуФормыЛкс(ЭтаФорма);
ЗаданияФормы = Неопределено;
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ЭтаФорма);
#Если Сервер И Не Сервер Тогда
СлужебныеДанные = Новый Структура;
#КонецЕсли
Если СлужебныеДанные.Задания.Количество() > 0 Тогда
ЭтаФорма.ОтключитьОбработчикОжидания("ПроверкаЗавершенияФоновыхЗаданий");
Для Каждого КлючИЗначение Из СлужебныеДанные.Задания Цикл
ОтменитьЗаданиеФормыЛкс(ЭтаФорма, КлючИЗначение.Значение, Истина);
КонецЦикла;
КонецЕсли;
МодальныеГруппы = МодальныеГруппыЛкс();
#Если Сервер И Не Сервер Тогда
МодальныеГруппы = Новый Массив;
#КонецЕсли
Если МодальныеГруппы.Количество() > 0 Тогда
ИндексГруппы = МодальныеГруппы.Количество() - 1;
Если ЭтаФорма.МодальныйРежим Тогда
// Вылняется никогда, т.к. свойство МодальныйРежим платформа сбрасывает перед ПриЗакрытии
КоличествоФормВМодальнойГруппе = 0;
Иначе
КоличествоФормВМодальнойГруппе = МодальныеГруппы[ИндексГруппы].Значение;
КоличествоФормВМодальнойГруппе = КоличествоФормВМодальнойГруппе - 1;
КонецЕсли;
Если КоличествоФормВМодальнойГруппе = 0 Тогда
МодальныеГруппы.Удалить(ИндексГруппы);
УстановитьФокусВводаФормеЛкс();
Иначе
МодальныеГруппы[ИндексГруппы].Значение = КоличествоФормВМодальнойГруппе;
КонецЕсли;
КонецЕсли;
ОткрытыеФормы = ирКэш.ОткрытыеФормыЛкс();
Пока Истина Цикл
ПозицияОткрытой = ОткрытыеФормы.Найти(ЭтаФорма);
Если ПозицияОткрытой = Неопределено Тогда
Прервать;
КонецЕсли;
ОткрытыеФормы.Удалить(ПозицияОткрытой);
КонецЦикла;
КонецПроцедуры
Процедура ОтменитьЗаданиеФормыОтложенноЛкс(Параметры) Экспорт
ОтменитьЗаданиеФормыЛкс(Параметры.ЭтаФорма, Параметры.ОписаниеЗадания);
КонецПроцедуры
Функция ОтменитьЗаданиеФормыЛкс(Знач ЭтаФорма, Знач ОписаниеЗадания, Знач ЗакрытьФормуЗадания = Ложь)
Если Не ЗначениеЗаполнено(ОписаниеЗадания.УникальныйИдентификатор) Тогда
Возврат Ложь;
КонецЕсли;
ЗаданияФормы = ирОбщий.СлужебныеДанныеФормыЛкс(ЭтаФорма).Задания;
#Если Сервер И Не Сервер Тогда
ЗаданияФормы = Новый Структура;
#КонецЕсли
ОтменитьФоновоеЗаданиеЛкс(ОписаниеЗадания.УникальныйИдентификатор);
Если ОписаниеЗадания.Многопоточное Тогда
Найденные = ФоновыеЗаданияПотоковЛкс();
ПрефиксКлючаПотока = ПрефиксКлючаПотокаЛкс(ЭтаФорма);
Для Каждого ФоновоеЗадание Из Найденные Цикл
#Если Сервер И Не Сервер Тогда
ФоновоеЗадание = ФоновыеЗадания.Выполнить();
#КонецЕсли
Если СтрНачинаетсяСЛкс(ФоновоеЗадание.Ключ, ПрефиксКлючаПотока) Тогда
ОтменитьФоновоеЗаданиеЛкс(ФоновоеЗадание);
КонецЕсли;
КонецЦикла;
КонецЕсли;
ОбработатьЗавершениеЗаданияФормыЛкс(ОписаниеЗадания, ЭтаФорма,, Истина, ЗакрытьФормуЗадания);
ПроверитьЗавершениеФоновыхЗаданийФормыЛкс(ЭтаФорма);
Возврат Истина;
КонецФункции
Процедура УдалитьСсылкиНаЗакрытыеФормыЛкс(ЭтаФорма = Неопределено) Экспорт
УдалитьФормы = Новый Массив;
ОткрытыеФормы = Новый Массив;
Для Каждого Форма Из ОткрытыеФормы Цикл
Если ЭтаФорма = Форма Или Форма.Открыта() Тогда
Продолжить;
КонецЕсли;
УдалитьФормы.Добавить(Форма);
КонецЦикла;
Для Каждого Форма Из УдалитьФормы Цикл
СообщитьЛкс(СтрШаблонИменЛкс("Удалена ссылка на закрытую ранее форму %1",, Форма.Заголовок));
ОткрытыеФормы.Удалить(ОткрытыеФормы.Найти(Форма));
КонецЦикла;
КонецПроцедуры
Процедура ОповеститьФормыПодсистемыЛкс(ИмяСобытия = Неопределено, Параметр = Неопределено, Источник = Неопределено, Знач ЭтаФорма = Неопределено) Экспорт
Если ЭтаФорма = Неопределено Тогда
ЭтаФорма = Источник;
КонецЕсли;
УдалитьСсылкиНаЗакрытыеФормыЛкс(ЭтаФорма);
// Копируем, чтобы в процессе оповещения массив не менял состав
ОткрытыеФормы = СкопироватьУниверсальнуюКоллекциюЛкс(ирКэш.ОткрытыеФормыЛкс());
Для Каждого Форма Из ОткрытыеФормы Цикл
Если МетодРеализованЛкс(Форма, "ОбработкаОповещения") Тогда
Форма.ОбработкаОповещения(ИмяСобытия, Параметр, Источник);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма) Экспорт
Если ЭтаФорма.МодальныйРежим Тогда
Ответ = Вопрос("Хотите закрыть текущую форму, чтобы открыть новую форму немодально?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Да Тогда
ЭтаФорма.Закрыть();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ЗапроситьСохранениеДанныхФормыЛкс(ЭтаФорма, Отказ = Ложь) Экспорт
Если ЭтаФорма.Модифицированность Тогда
ПередОтображениемДиалогаПередЗакрытиемФормыЛкс(ЭтаФорма);
Ответ = Вопрос("Данные в форме были изменены. Сохранить изменения?", РежимДиалогаВопрос.ДаНетОтмена);
Если Ответ = КодВозвратаДиалога.Отмена Тогда
Отказ = Истина;
КонецЕсли;
КонецЕсли;
Возврат Ответ;
КонецФункции
Функция ПериодОчисткиМенеджераВременныхТаблицЛкс(выхПоУмолчаниюОчищать = Ложь) Экспорт
ПараметрыОчистки = ирОбщий.ВосстановитьЗначениеЛкс("ПредлагатьОчиститьМенеджерВременныхТаблицЧерезМинут");
Если ТипЗнч(ПараметрыОчистки) = Тип("Структура") Тогда
Период = ПараметрыОчистки.Период;
выхПоУмолчаниюОчищать = ПараметрыОчистки.ПоУмолчаниюОчищать;
Иначе
Период = ПараметрыОчистки;
выхПоУмолчаниюОчищать = Ложь;
КонецЕсли;
Если Период = Неопределено Тогда
Период = 60;
ИначеЕсли Период < 1 Тогда
Период = 1;
ИначеЕсли Период > 240 Тогда
Период = 240;
КонецЕсли;
Возврат Период;
КонецФункции
Процедура ПередОтображениемДиалогаПередЗакрытиемФормыЛкс(Знач ЭтаФорма) Экспорт
Если ирКэш.ЛиСеансТолстогоКлиентаУПЛкс() Тогда
ЭтаФорма.Открыть(); // http://www.hostedredmine.com/issues/881581
КонецЕсли;
КонецПроцедуры
Процедура КоманднаяПанельВставитьКнопкиГлобальныхКомандЛкс(Знач КоманднаяПанельПолеВвода)
КнопкаКопировать = КоманднаяПанельПолеВвода.Кнопки.Добавить();
КнопкаКопировать.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
Попытка
КнопкаКопировать.Действие = Новый Действие("КлсКомандаНажатие");
Исключение
КоманднаяПанельПолеВвода.Кнопки.Удалить(КнопкаКопировать);
Возврат;
КонецПопытки;
КнопкаКопировать.Имя = "БуферОбмена_Копировать";
КнопкаКопировать.Текст = "Копировать значение";
КнопкаКопировать.Подсказка = "Копировать значение в буфер обмена";
КнопкаКопировать.Пояснение = КнопкаКопировать.Подсказка;
КнопкаКопировать.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.C, Истина, , Истина); // SHIFT+ALT+C
КнопкаКопировать.Картинка = ирКэш.КартинкаПоИмениЛкс("ирКопировать");
КнопкаВставить = КоманднаяПанельПолеВвода.Кнопки.Добавить();
КнопкаВставить.Имя = "БуферОбмена_Вставить";
КнопкаВставить.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
КнопкаВставить.Текст = "Вставить значение";
КнопкаВставить.Подсказка = "Вставить значение из буфера обмена";
КнопкаВставить.Пояснение = КнопкаВставить.Подсказка;
КнопкаВставить.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.V, Истина, , Истина); // SHIFT+ALT+V
КнопкаВставить.Действие = Новый Действие("КлсКомандаНажатие");
КнопкаВставить.Картинка = ирКэш.КартинкаПоИмениЛкс("ирВставить");
//КнопкаМеню = КоманднаяПанельПолеВвода.Кнопки.Добавить();
//КнопкаМеню.Имя = "ОткрытьГлобальноеМеню";
//КнопкаМеню.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
//КнопкаМеню.Текст = "Глобальное меню";
//КнопкаМеню.Подсказка = "Открыть глобальное меню";
//КнопкаМеню.Пояснение = КнопкаМеню.Подсказка;
//КнопкаМеню.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.E, Истина, Истина); // CTRL+ALT+E
//КнопкаМеню.Действие = Новый Действие("КлсКомандаНажатие");
КонецПроцедуры
Функция ЛиПерехватКлавиатурногоВводаЛкс() Экспорт
//Возврат Ложь; // для отладки
Если Ложь
Или Не ирКэш.ЛиПлатформаWindowsЛкс()
Или Найти(ПараметрЗапуска, "ОтключитьПерехватКлавиатурыИР") > 0
Тогда
Результат = Ложь;
Иначе
#Если ТолстыйКлиентОбычноеПриложение Тогда
Результат = ирОбщий.ЛиПерехватКлавиатурногоВводаВОбычномПриложенииЛкс();
#Иначе
Результат = Истина;
#КонецЕсли
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиПерехватКлавиатурногоВводаВОбычномПриложенииЛкс() Экспорт
Результат = ирКэш.Получить().ПерехватКлавиатурногоВводаВОбычномПриложении;
Возврат Результат;
КонецФункции
Процедура УниверсальнаяКомандаФормыЛкс(Знач ЭтаФорма, Знач Кнопка, Знач ИсточникДействий = Неопределено, Знач МетаданныеВыбора = Неопределено) Экспорт
СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
Если Кнопка.Имя = "БуферОбмена_Копировать" Тогда
БуферОбмена_КопироватьЛкс(ЭтаФорма);
ИначеЕсли Кнопка.Имя = "БуферОбмена_Вставить" Тогда
БуферОбмена_ВставитьЛкс(ЭтаФорма);
ИначеЕсли Кнопка.Имя = "ОткрытьГлобальноеМеню" Тогда
Если Не ЛиПерехватКлавиатурногоВводаЛкс() Тогда
ОткрытьГлобальноеМенюЛкс(ЭтаФорма);
КонецЕсли;
ИначеЕсли Кнопка.Имя = "ОПодсистеме" Тогда
ОткрытьСправкуПоПодсистемеЛкс(ЭтаФорма);
ИначеЕсли Кнопка.Имя = "СтруктураФормы" Тогда
ОткрытьСтруктуруФормыЛкс(ЭтаФорма, ЭтаФорма);
ИначеЕсли Кнопка.Имя = "НовоеОкно" Тогда
ОткрытьНовоеОкноФормыЛкс(ЭтаФорма);
ИначеЕсли Кнопка.Имя = "ЗагрузитьНастройку" Тогда
ВыбратьИЗагрузитьНастройкуФормыЛкс(ЭтаФорма);
ИначеЕсли Кнопка.Имя = "СохранитьНастройку" Тогда
ВыбратьИСохранитьНастройкуФормыЛкс(ЭтаФорма);
ИначеЕсли Кнопка.Имя = "ЗагрузитьНастройкуИзФайла" Тогда
Если Не ПроверитьЗавершениеФоновыхЗаданийФормыЛкс(ЭтаФорма) Тогда
СообщитьЛкс("Нельзя выполнять загрузку настроек, пока форма выполняет фоновые задания");
Возврат;
КонецЕсли;
НастройкаФормы = ЗагрузитьЗначениеИзФайлаИнтерактивноЛкс(СлужебныеДанныеФормы.МенеджерСохраненияНастроек.РасширениеФайла, "Настройка """ + ПервыйФрагментЛкс(ЭтаФорма.Заголовок, ":") + """");
Если НастройкаФормы <> Неопределено Тогда
ирОбщий.ЗагрузитьНастройкуФормыЧерезОбработчикЛкс(ЭтаФорма, НастройкаФормы);
КонецЕсли;
ИначеЕсли Кнопка.Имя = "СохранитьНастройкуВФайл" Тогда
НастройкаФормы = ирОбщий.СохраняемаяНастройкаФормыЛкс(ЭтаФорма);
Если НастройкаФормы <> Неопределено Тогда
СохранитьЗначениеВФайлИнтерактивноЛкс(НастройкаФормы, СлужебныеДанныеФормы.МенеджерСохраненияНастроек.РасширениеФайла, "Настройка """ + ПервыйФрагментЛкс(ЭтаФорма.Заголовок, ":") + """");
КонецЕсли;
Иначе
Если ИсточникДействий = Неопределено Тогда
ИсточникДействий = КоманднаяПанельКнопкиЛкс(ЭтаФорма, Кнопка).ИсточникДействий;
КонецЕсли;
Если ИсточникДействий = Неопределено Тогда
ИсточникДействий = ЭтаФорма.ТекущийЭлемент;
КонецЕсли;
Если ТипЗнч(ИсточникДействий) = Тип("ТабличноеПоле") Тогда
#Если Сервер И Не Сервер Тогда
ИсточникДействий = Новый ТабличноеПоле;
#КонецЕсли
Если Кнопка.Имя = "ПереместитьВверх" Тогда
ТабличноеПолеСдвинутьВыделенныеСтрокиЛкс(ИсточникДействий, -1);
ИначеЕсли Кнопка.Имя = "ПереместитьВниз" Тогда
ТабличноеПолеСдвинутьВыделенныеСтрокиЛкс(ИсточникДействий, +1);
ИначеЕсли Кнопка.Имя = "ПереместитьВНачало" Тогда
ТабличноеПолеСдвинутьВыделенныеСтрокиЛкс(ИсточникДействий, -100000);
ИначеЕсли Кнопка.Имя = "ПереместитьВКонец" Тогда
ТабличноеПолеСдвинутьВыделенныеСтрокиЛкс(ИсточникДействий, +100000);
ИначеЕсли Кнопка.Имя = "СортироватьПоВозрастанию" Тогда
ТабличноеПолеСортироватьЛкс(ЭтаФорма, ИсточникДействий, Истина);
ИначеЕсли Кнопка.Имя = "СортироватьПоУбыванию" Тогда
ТабличноеПолеСортироватьЛкс(ЭтаФорма, ИсточникДействий, Ложь);
ИначеЕсли Кнопка.Имя = "ПоказыватьИтоги" Тогда
ТабличноеПолеКнопкаОтображенияИтоговНажатиеЛкс(ЭтаФорма, ИсточникДействий, Кнопка);
ИначеЕсли Кнопка.Имя = "Идентификаторы" Тогда
КнопкаОтображатьПустыеИИдентификаторыНажатиеЛкс(Кнопка);
ИсточникДействий.ОбновитьСтроки();
ИначеЕсли Кнопка.Имя = "СжатьКолонки" Тогда
СжатьКолонкиТабличногоПоляЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "ШиринаКолонок" Тогда
РасширитьКолонкиТабличногоПоляЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "ГруппировкаТаблицы" Тогда
КомпоновкаТП = КомпоновкаТабличногоПоляЛкс(ЭтаФорма, ИсточникДействий);
Если КомпоновкаТП <> Неопределено Тогда
НастройкаКомпоновки = КомпоновкаТП.Компоновщик.Настройки;
КонецЕсли;
ирОбщий.ОткрытьГруппировкуТабличногоПоляЛкс(ИсточникДействий, НастройкаКомпоновки);
ИначеЕсли Кнопка.Имя = "АнализДанных" Тогда
ФормаАнализа = ирОбщий.ПолучитьФормуЛкс("Обработка.ирАнализДанных.Форма",, ЭтаФорма);
ФормаАнализа.ПараметрТаблица = ИсточникДействий.Значение;
ФормаАнализа.Открыть();
ИначеЕсли Кнопка.Имя = "МенеджерТабличногоПоля" Тогда
ОткрытьМенеджерТабличногоПоляЛкс(ИсточникДействий, ЭтаФорма,, МетаданныеВыбора);
ИначеЕсли Кнопка.Имя = "УстановитьЗначениеВКолонке" Тогда
ОткрытьМенеджерТабличногоПоляЛкс(ИсточникДействий, ЭтаФорма, "Обработка", МетаданныеВыбора);
ИначеЕсли Кнопка.Имя = "ЗагрузитьСтроки" Тогда
ЗагрузитьСтрокиВТабличноеПолеЛкс(ЭтаФорма, ИсточникДействий);
ИначеЕсли Кнопка.Имя = "РазличныеЗначенияКолонки" Тогда
ОткрытьРазличныеЗначенияКолонкиЛкс(ИсточникДействий,,, ЭтаФорма);
ИначеЕсли Кнопка.Имя = "РедакторОбъектаБД" Тогда
ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма);
ОткрытьСсылкуЯчейкиВРедактореОбъектаБДЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "КонсольОбработки" Тогда
ОткрытьОбъектыИзВыделенныхЯчеекВПодбореИОбработкеОбъектовЛкс(ИсточникДействий,, ЭтаФорма);
ИначеЕсли Кнопка.Имя = "ОбработатьОбъекты" Тогда
ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма);
ОткрытьПодборИОбработкуОбъектовИзДинамическогоСпискаЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "ВывестиСтроки" Тогда
ВывестиСтрокиТабличногоПоляИПоказатьЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "КонсольКомпоновки" Тогда
ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма);
ОткрытьДанныеТабличногоПоляВКонсолиКомпоновкиЛкс(ЭтаФорма, ИсточникДействий);
ИначеЕсли Кнопка.Имя = "Сравнить" Тогда
ЗапомнитьСодержимоеЭлементаФормыДляСравненияЛкс(ЭтаФорма, ИсточникДействий);
ИначеЕсли Кнопка.Имя = "СравнитьСтроки" Тогда
ТабличноеПолеИлиТаблицаФормы_СравнитьСтрокиЛкс(ЭтаФорма, ИсточникДействий);
ИначеЕсли Кнопка.Имя = "ЗаполнитьГруппыДублейДляЗамены" Тогда
ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма);
ОткрытьФормуЗаменыСсылокИзТабличногоПоляЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "ОткрытьКоллекцию" Тогда
ОткрытьЗначениеЛкс(ИсточникДействий.Значение,,,, Ложь,, ИсточникДействий);
ИначеЕсли Кнопка.Имя = "ОткрытьКопиюКоллекции" Тогда
КопияКоллекции = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ИсточникДействий,,, Ложь,,, ЭтаФорма);
ОткрытьЗначениеЛкс(КопияКоллекции,,,, Ложь,, ИсточникДействий);
ИначеЕсли Кнопка.Имя = "СвернутьДерево" Тогда
ДеревоЗначенийСвернутьРазвернутьЛкс(ИсточникДействий, Истина);
ИначеЕсли Кнопка.Имя = "РазвернутьДерево" Тогда
ДеревоЗначенийСвернутьРазвернутьЛкс(ИсточникДействий, Ложь);
ИначеЕсли Кнопка.Имя = "ДеревоСвернутьОстальные" Тогда
ТабличноеПолеДеревоЗначений_СвернутьВсеСтрокиЛкс(ИсточникДействий, Истина);
ИначеЕсли Кнопка.Имя = "Очистить" Тогда
ИсточникДействий.Значение.Очистить();
ИначеЕсли Кнопка.Имя = "ОтборПоЗначениюВТекущейКолонке" Тогда
Если ТипЗнч(ИсточникДействий.Значение) <> Тип("ДеревоЗначений") Тогда
ТабличноеПолеОтборДляЗначенияВТекущейКолонкеЛкс(ИсточникДействий, Истина,,,, ЭтаФорма);
КонецЕсли;
ИначеЕсли Кнопка.Имя = "ОтборБезЗначенияВТекущейКолонке" Тогда
Если ТипЗнч(ИсточникДействий.Значение) <> Тип("ДеревоЗначений") Тогда
ТабличноеПолеОтборДляЗначенияВТекущейКолонкеЛкс(ИсточникДействий, Ложь,,,, ЭтаФорма);
КонецЕсли;
ИначеЕсли Кнопка.Имя = "УстановитьФлажки" Тогда
ИзменитьПометкиВыделенныхИлиОтобранныхСтрокЛкс(ИсточникДействий,, Истина,,, Истина);
ИначеЕсли Кнопка.Имя = "СнятьФлажки" Тогда
ИзменитьПометкиВыделенныхИлиОтобранныхСтрокЛкс(ИсточникДействий,, Ложь,,, Истина);
ИначеЕсли Кнопка.Имя = "СколькоСтрок" Тогда
ТабличноеПолеИлиТаблицаФормы_СколькоСтрокЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "НастроитьКолонки" Тогда
ОткрытьНастройкуКолонокТабличногоПоляЛкс(ЭтаФорма, ИсточникДействий);
ИначеЕсли СтрНачинаетсяСЛкс(Кнопка.Имя, НачалоИмениКнопкиПодменюПоследнихВыбранных("Отборы")) Тогда
НастройкаКомпоновки = ирОбщий.ВыбранныйЭлементПоследнихЗначенийЛкс(ЭтаФорма, ИсточникДействий, Кнопка, "Отборы", Истина);
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
ПутьКДанным = "ЭлементыФормы." + ИсточникДействий.Имя + ".Отбор";
ЭтаФорма.ОтключитьОбработчикИзмененияДанных(ПутьКДанным);
ирОбщий.СкопироватьОтборЛюбойЛкс(ИсточникДействий.ОтборСтрок, НастройкаКомпоновки.Отбор);
Попытка
ЭтаФорма.ОбработчикИзмененияДанных(ПутьКДанным);
Исключение
// Временно пропускаем такие ошибки
ирОбщий.СообщитьЛкс(ОписаниеОшибки());
КонецПопытки;
Иначе
ВызватьИсключение "Неизвестное имя команды (" + Кнопка.Имя + ")";
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьНастройкуКолонокТабличногоПоляЛкс(Знач ЭтаФорма, Знач ИсточникДействий) Экспорт
мНастройкаКолонок = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирДинамическийСписок");
#Если Сервер И Не Сервер Тогда
мНастройкаКолонок = Обработки.ирДинамическийСписок.Создать();
#КонецЕсли
ФормаНастроек = мНастройкаКолонок.ПолучитьФорму("НастройкиКолонок", ЭтаФорма);
ФормаНастроек.ПрочитатьНастройкиКолонокИзТабличногоПоля(ИсточникДействий);
ФормаНастроек.СвязанноеТабличноеПоле = ИсточникДействий;
ФормаНастроек.ПараметрРучноеСохранение = Истина;
ТаблицаЗначений = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ИсточникДействий, Новый Массив,,,,, ЭтаФорма);
Если ТаблицаЗначений <> Неопределено Тогда
Для Каждого СтрокаНастройкиКолонки Из ФормаНастроек.НастройкиКолонок Цикл
ДоступноеПоле = ТаблицаЗначений.Колонки.Найти(ИсточникДействий.Колонки[СтрокаНастройкиКолонки.Имя].Данные);
Если ДоступноеПоле = Неопределено Тогда
Продолжить;
КонецЕсли;
СтрокаНастройкиКолонки.ТипЗначения = ДоступноеПоле.ТипЗначения;
КонецЦикла;
КонецЕсли;
ВыбранноеЗначение = ФормаНастроек.ОткрытьМодально();
Если ВыбранноеЗначение <> Неопределено Тогда
мНастройкаКолонок.ПрименитьНастройкиКолонокКТабличномуПолю(ИсточникДействий, ВыбранноеЗначение);
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьТаблицуВКонсолиКомпоновкиЛкс(Знач Таблица, Знач КомпоновкаТП = Неопределено) Экспорт
КонсольКомпоновокДанных = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольКомпоновокДанных");
#Если Сервер И Не Сервер Тогда
КонсольКомпоновокДанных = Обработки.ирКонсольКомпоновокДанных.Создать();
Таблица = Новый ТаблицаЗначений;
#КонецЕсли
Если КомпоновкаТП <> Неопределено Тогда
НастройкаКомпоновки = КомпоновкаТП.Компоновщик.Настройки;
КонецЕсли;
КонсольКомпоновокДанных.ОткрытьПоТаблицеЗначений(Таблица, НастройкаКомпоновки);
КонецПроцедуры
Процедура ОткрытьДанныеТабличногоПоляВКонсолиКомпоновкиЛкс(Знач ЭтаФорма, Знач ТабличноеПоле, Знач НастройкаКомпоновки = Неопределено) Экспорт
КонсольКомпоновокДанных = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольКомпоновокДанных");
#Если Сервер И Не Сервер Тогда
КонсольКомпоновокДанных = Обработки.ирКонсольКомпоновокДанных.Создать();
#КонецЕсли
КомпоновкаТП = КомпоновкаТабличногоПоляЛкс(ЭтаФорма, ТабличноеПоле);
Если КомпоновкаТП <> Неопределено Тогда
Если НастройкаКомпоновки = Неопределено Тогда
НастройкаКомпоновки = КомпоновкаТП.Компоновщик.Настройки;
КонецЕсли;
УстановитьПараметрыВыводаКомпоновкиПоУмолчаниюЛкс(НастройкаКомпоновки);
КонецЕсли;
КопияКоллекции = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле,,,,,, ЭтаФорма);
ВнешниеНаборыДанных = Новый Структура("Основной", КопияКоллекции);
КонсольКомпоновокДанных.ОткрытьПоТабличномуПолю(ТабличноеПоле,, НастройкаКомпоновки, ВнешниеНаборыДанных);
КонецПроцедуры
// Родственник ВернутьПостоянныйПарольПользователяЛкс
// Пароль устанавливается временный и опционально роль ирРазработчик
Функция УстановитьВременныеСвойстваПользователюИБЛкс(ПользовательИБ, ПодменитьПарольНаВремяЗапуска = Истина, ВременноПредоставитьПравоРазработчикИР = Истина,
ОтключитьЗащитуОтОпасныхДействийНаВремяЗапуска = Истина, ЯзыкКонфигурации = "") Экспорт
#Если Сервер И Не Сервер Тогда
ПользовательИБ = ПользователиИнформационнойБазы.СоздатьПользователя();
#КонецЕсли
мПлатформа = ирКэш.Получить();
НужноВернутьАутентификациюОС = Ложь;
НужноВернутьАутентификациюПаролем = Ложь;
НужноВернутьПароль = Ложь;
НужноВернутьЗащитуОтОпасныхДействий = Ложь;
НужноВернутьЯзыкКонфигурации = Ложь;
УдалитьРольРазработчикИР = Ложь;
Если ПодменитьПарольНаВремяЗапуска Тогда
Если СтрокиРавныЛкс(ПользовательИБ.Имя, ИмяПользователя()) Тогда
СообщитьЛкс("Назначение временного пароля собственному пользователю не допускается");
Возврат Неопределено;
КонецЕсли;
мhash = ПользовательИБ.СохраняемоеЗначениеПароля;
Если ПользовательИБ.АутентификацияОС = Истина Тогда
ПользовательИБ.АутентификацияОС = Ложь;
НужноВернутьАутентификациюОС = Истина;
КонецЕсли;
Если ПользовательИБ.АутентификацияСтандартная = Ложь Тогда
ПользовательИБ.АутентификацияСтандартная = Истина;
НужноВернутьАутентификациюПаролем = Истина;
КонецЕсли;
Пароль = Формат(ТекущаяДата(), "ДФ=HHmmss") + XMLСтрока(НомерСеансаИнформационнойБазы()) + "!_qQ";
ПользовательИБ.Пароль = Пароль;
НужноВернутьПароль = Истина;
КонецЕсли;
Если ВременноПредоставитьПравоРазработчикИР И Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПользовательИБ.Роли.Содержит(Метаданные.Роли.ирРазработчик) Тогда
УдалитьРольРазработчикИР = Истина;
ПользовательИБ.Роли.Добавить(Метаданные.Роли.ирРазработчик);
ПользовательИБ.ПолноеИмя = ПользовательИБ.ПолноеИмя + МаркерВременныхРолейЛкс();
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(ЯзыкКонфигурации) Тогда
НужноВернутьЯзыкКонфигурации = Истина;
СтарыйЯзыкКонфигурации = ПользовательИБ.Язык;
Если СтарыйЯзыкКонфигурации <> Неопределено Тогда
СтарыйЯзыкКонфигурации = СтарыйЯзыкКонфигурации.Имя;
КонецЕсли;
ПользовательИБ.Язык = Метаданные.Языки[ЯзыкКонфигурации];
КонецЕсли;
Если ОтключитьЗащитуОтОпасныхДействийНаВремяЗапуска Тогда
Если ирКэш.ДоступнаЗащитаОтОпасныхДействийЛкс() И ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях Тогда
ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Ложь;
НужноВернутьЗащитуОтОпасныхДействий = Истина;
КонецЕсли;
КонецЕсли;
ПользовательИБ.Записать();
НаборПараметров = Новый Структура();
НаборПараметров.Вставить("mHash", мhash);
НаборПараметров.Вставить("НужноВернутьАутентификациюПаролем", НужноВернутьАутентификациюПаролем);
НаборПараметров.Вставить("НужноВернутьАутентификациюОС", НужноВернутьАутентификациюОС);
НаборПараметров.Вставить("ПользовательИБ", ПользовательИБ);
НаборПараметров.Вставить("НужноВернутьПароль", НужноВернутьПароль);
НаборПараметров.Вставить("НужноВернутьЗащитуОтОпасныхДействий", НужноВернутьЗащитуОтОпасныхДействий);
НаборПараметров.Вставить("УдалитьРольРазработчикИР", УдалитьРольРазработчикИР);
НаборПараметров.Вставить("Имя", ПользовательИБ.Имя);
НаборПараметров.Вставить("Пароль", Пароль);
НаборПараметров.Вставить("НужноВернутьЯзыкКонфигурации", НужноВернутьЯзыкКонфигурации);
НаборПараметров.Вставить("ЯзыкКонфигурации", СтарыйЯзыкКонфигурации);
Возврат НаборПараметров;
КонецФункции
// Родственник УстановитьВременныеСвойстваПользователюИБЛкс
Процедура ВернутьПостоянныеСвойстваПользователюИБЛкс(НаборПараметров = Неопределено) Экспорт;
//УстановитьПривилегированныйРежим(Истина);
Если НаборПараметров <> Неопределено Тогда
мhash = НаборПараметров.mhash;
ЯзыкКонфигурации = НаборПараметров.ЯзыкКонфигурации;
НужноВернутьАутентификациюПаролем = НаборПараметров.НужноВернутьАутентификациюПаролем;
НужноВернутьАутентификациюОС = НаборПараметров.НужноВернутьАутентификациюОС;
НужноВернутьПароль = НаборПараметров.НужноВернутьПароль;
НужноВернутьЗащитуОтОпасныхДействий = НаборПараметров.НужноВернутьЗащитуОтОпасныхДействий;
НужноВернутьЯзыкКонфигурации = НаборПараметров.НужноВернутьЯзыкКонфигурации;
ПользовательИБ = НаборПараметров.ПользовательИБ;
УдалитьРольРазработчикИР = НаборПараметров.УдалитьРольРазработчикИР;
Иначе
Возврат;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
#КонецЕсли
Если НужноВернутьПароль Тогда
ПользовательИБ.СохраняемоеЗначениеПароля = мHash;
КонецЕсли;
Если НужноВернутьАутентификациюПаролем Тогда
ПользовательИБ.АутентификацияСтандартная = Ложь;
КонецЕсли;
Если НужноВернутьАутентификациюОС Тогда
ПользовательИБ.АутентификацияОС = Истина;
КонецЕсли;
Если НужноВернутьЗащитуОтОпасныхДействий И ирКэш.ДоступнаЗащитаОтОпасныхДействийЛкс() Тогда
ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Истина;
КонецЕсли;
Если УдалитьРольРазработчикИР Тогда
ПользовательИБ.Роли.Удалить(Метаданные.Роли.ирРазработчик);
ПользовательИБ.ПолноеИмя = СтрокаБезПоследнегоФрагментаЛкс(ПользовательИБ.ПолноеИмя, МаркерВременныхРолейЛкс());
КонецЕсли;
Если НужноВернутьЯзыкКонфигурации Тогда
ПользовательИБ.Язык = Метаданные.Языки[ЯзыкКонфигурации];
КонецЕсли;
ПользовательИБ.Записать();
КонецПроцедуры
Процедура НастроитьПоляВводаПараметровПотоковЛкс(ЭтаФорма, ЕстьКоличествоОбъектовВПорции = Истина) Экспорт
ЭлементыФормы = ЭтаФорма.ЭлементыФормы;
Если ЕстьКоличествоОбъектовВПорции Тогда
СписокВыбора = ЭлементыФормы.КоличествоОбъектовВПорции.СписокВыбора;
СписокВыбора.Добавить(1);
СписокВыбора.Добавить(2);
СписокВыбора.Добавить(5);
СписокВыбора.Добавить(10);
СписокВыбора.Добавить(20);
СписокВыбора.Добавить(50);
СписокВыбора.Добавить(100);
СписокВыбора.Добавить(200);
КонецЕсли;
СписокВыбора = ЭлементыФормы.КоличествоПотоков.СписокВыбора;
СписокВыбора.Добавить(1);
СписокВыбора.Добавить(4);
СписокВыбора.Добавить(8);
СписокВыбора.Добавить(12);
СписокВыбора.Добавить(16);
КонецПроцедуры
Функция ОткрытьМенеджерТабличногоПоляЛкс(Знач ТабличноеПоле = Неопределено, Знач ЭтаФорма, Знач АктивизироватьСтраницу = "", Знач МетаданныеВыбора = Неопределено) Экспорт
Если ТабличноеПоле = Неопределено Тогда
ТабличноеПоле = ЭтаФорма.ТекущийЭлемент;
КонецЕсли;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаМенеджера = мПлатформа.ПолучитьФорму("МенеджерТабличногоПоля", ЭтаФорма);
ФормаМенеджера.УстановитьСвязь(ТабличноеПоле, , АктивизироватьСтраницу, МетаданныеВыбора);
Возврат ФормаМенеджера;
КонецФункции
Процедура ОткрытьСвязанныйСеансТонкогоКлиентаЛкс() Экспорт
Если ПроверитьПлатформаНеWindowsЛкс() Тогда
Возврат;
КонецЕсли;
Результат = ирКэш.ПолучитьСеансТонкогоКлиентаЛкс();
Если Результат = Неопределено Тогда
Возврат;
КонецЕсли;
Результат.Visible = Истина;
Окна = Результат.ПолучитьОкна();
СписокОткрытыхОбъектов = Новый СписокЗначений;
Для Каждого Окно Из Окна Цикл
Попытка
Содержимое = Окно.Содержимое;
Исключение
// В 8.2 нет такого свойства
Продолжить;
КонецПопытки;
Для Каждого Форма Из Содержимое Цикл
Попытка
СсылкаCOM = Форма.Parameters.Key;
Исключение
СсылкаCOM = Неопределено;
КонецПопытки;
Если СсылкаCOM <> Неопределено Тогда
ФрагментыИмениТипа = ирОбщий.СтрРазделитьЛкс(Форма.FormName);
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(Новый УникальныйИдентификатор(Результат.String(СсылкаCOM.УникальныйИдентификатор())));
Ссылка = Новый (Тип(ФрагментыИмениТипа[0] + "Ссылка." + ФрагментыИмениТипа[1]), МассивПараметров);
СписокОткрытыхОбъектов.Добавить(Ссылка, ФрагментыИмениТипа[0] + "." + ФрагментыИмениТипа[1] + " - " + Ссылка);
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если СписокОткрытыхОбъектов.Количество() > 0 Тогда
СписокОткрытыхОбъектов.СортироватьПоПредставлению();
ВыбранныйЭлемент = СписокОткрытыхОбъектов.ВыбратьЭлемент("Выберите объект для открытия в редакторе объекта БД");
Если ВыбранныйЭлемент <> Неопределено Тогда
ОткрытьСсылкуВРедактореОбъектаБДЛкс(ВыбранныйЭлемент.Значение);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ОповеститьОЗаписиОбъектаЛкс(Знач ТипИлиМассив, Знач Источник = Неопределено, Знач ВсеТипыДляПодсистемы = Ложь) Экспорт
Если ТипЗнч(ТипИлиМассив) <> Тип("Массив") Тогда
ТипИлиМассив = ЗначенияВМассивЛкс(ТипИлиМассив);
КонецЕсли;
ВсеТипыДляПодсистемыОповещены = Ложь;
Если ТипИлиМассив.Количество() > 1 Или ВсеТипыДляПодсистемы Тогда
ирОбщий.ОповеститьФормыПодсистемыЛкс("ЗаписанОбъект",, Источник);
ВсеТипыДляПодсистемыОповещены = Истина;
КонецЕсли;
Для Каждого ТипИлиОбъект Из ТипИлиМассив Цикл
Если Не ВсеТипыДляПодсистемыОповещены Тогда
ирОбщий.ОповеститьФормыПодсистемыЛкс("ЗаписанОбъект", ТипИлиОбъект, Источник);
КонецЕсли;
Если ТипЗнч(ТипИлиОбъект) = Тип("Тип") Или ЛиСсылкаНаОбъектБДЛкс(ТипИлиОбъект) Тогда
ОповеститьОбИзменении(ТипИлиОбъект);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Для оповещения об изменениях объектов в памяти клиентского приложения
Процедура ОповеститьОбИзмененииОбъектаВПамятиЛкс(Объект, Источник = Неопределено) Экспорт
ирОбщий.ОповеститьФормыПодсистемыЛкс("ИзмененОбъектВПамяти", Объект, Источник);
КонецПроцедуры
Функция ЭтоНеудобнаяСсылкаДляОбработкиВыбораЛкс(Знач ВыбранноеЗначение) Экспорт
// Почему то для ссылок внешних источников данных оповещение о выборе устанавливает строковое значение
XMLТип = XMLТипЗнч(ВыбранноеЗначение);
Если Истина
И XMLТип <> Неопределено
И (Ложь
Или Найти(XMLТип.ИмяТипа, "ExternalDataSourceTableRef.") > 0
Или (Истина
И ВыбранноеЗначение <> Неопределено
И Метаданные.НайтиПоТипу(ТипЗнч(ВыбранноеЗначение)) <> Неопределено
И РасширениеКонфигурацииОбъектаМДЛкс(ВыбранноеЗначение.Метаданные()) <> Неопределено))
Тогда
ЭтоНеудобнаяСсылка = Истина;
Иначе
ЭтоНеудобнаяСсылка = Ложь;
КонецЕсли;
Возврат ЭтоНеудобнаяСсылка;
КонецФункции
Функция ОткрытьОбъектМетаданныхЛкс(ОбъектИлиПолноеИмяМД) Экспорт
Если ТипЗнч(ОбъектИлиПолноеИмяМД) = Тип("ОбъектМетаданных") Тогда
ОбъектМД = ОбъектИлиПолноеИмяМД;
Иначе
ОбъектМД = ПолучитьМетаданныеЛкс(ОбъектИлиПолноеИмяМД);
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.НайтиПоТипу();
#КонецЕсли
Если ОбъектМД = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
Фрагменты = ирОбщий.СтрРазделитьЛкс(ПолноеИмяМД);
Если Ложь
Или ПеревестиСтроку("ОбщийРеквизит") = Фрагменты[0]
Или (Истина
И Фрагменты.Количество() >= 4
И Не ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(Фрагменты[0]))
Тогда
ИсследоватьЛкс(ОбъектМД);
Возврат Неопределено;
// Для табличной части берем родителя
//ПолноеИмяМД = ОбъектМД.Родитель().ПолноеИмя();
КонецЕсли;
Форма = ПолучитьФормуЛкс("Обработка.ирИнтерфейснаяПанель.Форма");
Форма.ПараметрИмяОбъектаМетаданных = ПолноеИмяМД;
Форма.ПрименитьПараметрыФормы();
Возврат Форма;
КонецФункции
Процедура ОткрытьОбъектМДИзТаблицыСИменамиТиповЛкс(Знач СтрокаТаблицы) Экспорт
Если Найти(СтрокаТаблицы.ИмяТипаЗначения, ".") > 0 Тогда
Тип = Тип(СтрокаТаблицы.ИмяТипаЗначения);
ОбъектМД = Метаданные.НайтиПоТипу(Тип);
Если ОбъектМД <> Неопределено Тогда
ирОбщий.ОткрытьОбъектМетаданныхЛкс(ОбъектМД);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ОткрытьЗначенияФункциональныхОпцийЛкс(Знач ЗначенияОпций, Знач КлючУникальности) Экспорт
Если ЗначенияОпций = Неопределено Или ЗначенияОпций.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаПросмотра = мПлатформа.ПолучитьФорму("ЗначенияФункциональныхОпций", , КлючУникальности);
ФормаПросмотра.НачальноеЗначениеВыбора = ЗначенияОпций;
ФормаПросмотра.Открыть();
Возврат ФормаПросмотра;
КонецФункции
Функция ОткрытьПользователяИБЛкс(Пользователь) Экспорт
ФормаПользователя = ирОбщий.ПолучитьФормуЛкс("Обработка.ирРедакторПользователей.Форма.ПользовательИнфобазы",,, Пользователь);
ФормаПользователя.ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(Пользователь);
ФормаПользователя.Открыть();
Возврат ФормаПользователя;
КонецФункции
Функция ОбработкаОбъектИзФормыЛкс(ЭтаФорма) Экспорт
Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда
ОбработкаОбъект = ЭтаФорма;
Иначе
//ОбработкаОбъект = ЭтаФорма.РеквизитФормыВЗначение("фОбъект");
Фрагменты = СтрРазделитьЛкс(ЭтаФорма.ИмяФормы);
ОбработкаОбъект = ДанныеФормыВЗначение(ЭтаФорма.фОбъект, Тип("ОбработкаОбъект." + Фрагменты[1]));
КонецЕсли;
Возврат ОбработкаОбъект;
КонецФункции
Процедура ПроверитьЗакрытьФормуПриОтказеЛкс(ЭтаФорма, Знач Отказ) Экспорт
// Антибаг платформы 8.3.11-12 Не работает установка параметра Отказ перед открытием обычной формы в управляемом приложении
// https://partners.v8.1c.ru/forum/t/1713475/m/1713475
Если ирКэш.ЛиСеансТолстогоКлиентаУПЛкс() Тогда
Если Отказ И Не ЭтаФорма.МодальныйРежим Тогда
ЭтаФорма.Закрыть();
КонецЕсли;
КонецЕсли
КонецПроцедуры
Функция КлючиСтрокБДИзТаблицыФормыЛкс(Форма = Неопределено, выхКлючТекущейСтроки = Неопределено, выхТаблицаФормыДинамическогоСписка = Неопределено, Знач НуженВидимыйПорядок = Истина) Экспорт
Результат = Новый Массив;
Если Форма = Неопределено Тогда
Форма = АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если Ложь
Или ТипЗнч(Форма.ТекущийЭлемент) = Тип("ТаблицаФормы")
Или ТипЗнч(Форма.ТекущийЭлемент) = Тип("ТабличноеПоле")
Тогда
ТаблицаФормы = Форма.ТекущийЭлемент;
Если ЛиКлючСсылкиИлиРегистраЛкс(ТаблицаФормы.ТекущаяСтрока) Тогда
выхКлючТекущейСтроки = ТаблицаФормы.ТекущаяСтрока;
КонецЕсли;
Ссылка = ТаблицаФормы.ТекущаяСтрока;
ВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТаблицаФормы, НуженВидимыйПорядок);
Если ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда
выхТаблицаФормыДинамическогоСписка = ТаблицаФормы;
Возврат ВыделенныеСтроки;
КонецЕсли;
Структура = Новый Структура("Ссылка, Data");
Для Каждого ВыделеннаяСтрока Из ВыделенныеСтроки Цикл
ДанныеСтроки = ДанныеСтрокиТабличногоПоляЛкс(ТаблицаФормы, ВыделеннаяСтрока);
ЗаполнитьЗначенияСвойств(Структура, ДанныеСтроки);
Ссылка = Структура["Ссылка"];
Если ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда
Результат.Добавить(Ссылка);
КонецЕсли;
Ссылка = Структура["Data"];
Если ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда
Результат.Добавить(Ссылка);
Если ВыделеннаяСтрока = ТаблицаФормы.ТекущаяСтрока Тогда
выхКлючТекущейСтроки = Ссылка;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция КлючОсновногоОбъектаУправляемойФормыЛкс(Форма = Неопределено) Экспорт
Результат = Новый Массив;
Если Форма = Неопределено Тогда
Форма = АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если ТипЗнч(Форма) = Тип("УправляемаяФорма") Тогда
Ссылка = ирОбщий.СсылкаОсновногоОбъектаФормыЛкс(Форма);
Если Не ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда
Попытка
Ссылка = Форма.Параметры.Ключ;
Исключение
КонецПопытки;
КонецЕсли;
Если Не ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда
Ссылка = Неопределено;
КонецЕсли;
КонецЕсли;
Возврат Ссылка;
КонецФункции
Функция СсылкиИзТекущейКолонкиВыделенныхСтрокТаблицыЛкс(Форма = Неопределено, выхКлючТекущейСтроки = Неопределено, НуженВидимыйПорядок = Истина) Экспорт
Результат = Новый Массив;
Если Форма = Неопределено Тогда
Форма = АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если ТипЗнч(Форма.ТекущийЭлемент) = Тип("ТаблицаФормы") Тогда
ТаблицаФормы = Форма.ТекущийЭлемент;
ТекущееПоле = ТаблицаФормы.ТекущийЭлемент;
Если ТекущееПоле = Неопределено Тогда
Возврат Результат;
КонецЕсли;
ПолноеИмяПоля = ТекущееПоле.Имя;
ПутьКДанным = Null;
ВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТаблицаФормы, НуженВидимыйПорядок);
Для Каждого ВыделеннаяСтрока Из ВыделенныеСтроки Цикл
Если ТипЗнч(ВыделеннаяСтрока) = Тип("СтрокаГруппировкиДинамическогоСписка") Тогда
Продолжить;
КонецЕсли;
ДанныеСтроки = ДанныеСтрокиТабличногоПоляЛкс(ТаблицаФормы, ВыделеннаяСтрока);
Если ПутьКДанным = Null Тогда
ПутьКДанным = НайтиПутьКДаннымПоляТаблицыФормыЛкс(ДанныеСтроки, ПолноеИмяПоля);
КонецЕсли;
ЗначениеПоля = Неопределено;
Если ЗначениеЗаполнено(ПутьКДанным) Тогда
ЗначениеПоля = ДанныеСтроки[ПервыйФрагментЛкс(ПутьКДанным)];
КонецЕсли;
Если ЛиКлючСсылкиИлиРегистраЛкс(ЗначениеПоля) Тогда
Результат.Добавить(ЗначениеПоля);
Если ВыделеннаяСтрока = ТаблицаФормы.ТекущаяСтрока Тогда
выхКлючТекущейСтроки = ЗначениеПоля;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Найти(ПутьКДанным, ".") > 0 И Результат.Количество() > 0 Тогда
Результат = ПрочитатьРеквизитПоМассивуСсылокЛкс(Результат, ПоследнийФрагментЛкс(ПутьКДанным));
КонецЕсли;
ИначеЕсли ТипЗнч(Форма.ТекущийЭлемент) = Тип("ТабличноеПоле") Тогда
ТабличноеПоле = Форма.ТекущийЭлемент;
ПутьКДанным = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Если ЗначениеЗаполнено(ПутьКДанным) Тогда
ВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТабличноеПоле, НуженВидимыйПорядок);
Для Каждого ВыделеннаяСтрока Из ВыделенныеСтроки Цикл
ДанныеСтроки = ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле, ВыделеннаяСтрока);
ЗначениеПоля = Неопределено;
Если ЗначениеЗаполнено(ПутьКДанным) Тогда
Попытка
ЗначениеПоля = ДанныеСтроки[ПоследнийФрагментЛкс(ПутьКДанным)];
Исключение
// В отборе компоновки может возникать ошибка "Поле объекта не обнаружено (ПредставлениеДляКраткогоОтображенияЭлемента)"
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Если ЛиКлючСсылкиИлиРегистраЛкс(ЗначениеПоля) Тогда
Результат.Добавить(ЗначениеПоля);
Если ВыделеннаяСтрока = ТабличноеПоле.ТекущаяСтрока Тогда
выхКлючТекущейСтроки = ЗначениеПоля;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ИначеЕсли ТипЗнч(Форма.ТекущийЭлемент) = Тип("ПолеФормы") Тогда
ПолеФормы = Форма.ТекущийЭлемент;
Если ПолеФормы.Вид = ВидПоляФормы.ПолеВвода Тогда
ЗначениеПоля = ДанныеЭлементаФормыЛкс(Форма.ТекущийЭлемент);
Если ЛиКлючСсылкиИлиРегистраЛкс(ЗначениеПоля) Тогда
Результат.Добавить(ЗначениеПоля);
выхКлючТекущейСтроки = ЗначениеПоля;
КонецЕсли;
ИначеЕсли ПолеФормы.Вид = ВидПоляФормы.ПолеТабличногоДокумента Тогда
ДанныеРасшифровки = ДанныеРасшифровкиУправляемойФормыОтчетаЛкс(Форма);
ТабличныйДокумент = ДанныеЭлементаФормыЛкс(ПолеФормы);
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
Если ТабличныйДокумент = Неопределено Тогда
Возврат Результат;
КонецЕсли;
КлючТекущейСтроки = Неопределено;
ТаблицаЗначений = ТаблицаКлючейИзТабличногоДокументаЛкс(ТабличныйДокумент, ДанныеРасшифровки,,, КлючТекущейСтроки);
Если ТаблицаЗначений.Колонки.Количество() > 0 Тогда
Для Каждого ЗначениеПоля Из ТаблицаЗначений.ВыгрузитьКолонку(0) Цикл
Если ЛиКлючСсылкиИлиРегистраЛкс(ЗначениеПоля) Тогда
Результат.Добавить(ЗначениеПоля);
КонецЕсли;
КонецЦикла;
Если КлючТекущейСтроки <> Неопределено И ЛиКлючСсылкиИлиРегистраЛкс(КлючТекущейСтроки[0]) Тогда
выхКлючТекущейСтроки = КлючТекущейСтроки[0];
КонецЕсли;
КонецЕсли;
Если выхКлючТекущейСтроки = Неопределено И Результат.Количество() > 0 Тогда
выхКлючТекущейСтроки = Результат[0];
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПрочитатьРеквизитПоМассивуСсылокЛкс(Знач Ссылки, Знач ИмяРеквизита) Экспорт
#Если Сервер И Не Сервер Тогда
Ссылки = Новый Массив;
#КонецЕсли
Результат = Новый Массив;
Если Ссылки.Количество() > 0 Тогда
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Т." + ИмяРеквизита + " ИЗ " + Ссылки[0].Метаданные().ПолноеИмя() + " КАК Т ГДЕ Т.Ссылка В (&Ссылки)";
Запрос.УстановитьПараметр("Ссылки", Ссылки);
Результат = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(0);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЭтоУправляемаяФормаОтчетаЛкс(Знач АктивнаяФорма, РазрешитьВнешнийОтчет = Ложь) Экспорт
Возврат Истина
И ТипЗнч(АктивнаяФорма) <> Тип("Форма")
И (Ложь
Или Найти(АктивнаяФорма.ИмяФормы, ирОбщий.ПеревестиСтроку("Отчет") + ".") = 1
Или РазрешитьВнешнийОтчет И Найти(АктивнаяФорма.ИмяФормы, ирОбщий.ПеревестиСтроку("ВнешнийОтчет") + ".") = 1);
КонецФункции
Функция ТекущийЭлементАктивнойФормыЛкс(АктивнаяФорма = Неопределено) Экспорт
Если АктивнаяФорма = Неопределено Тогда
АктивнаяФорма = АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
ТекущийЭлемент = АктивнаяФорма.ТекущийЭлемент;
Если ТипЗнч(АктивнаяФорма) = Тип("УправляемаяФорма") Тогда
Если ТипЗнч(ТекущийЭлемент) = Тип("ОсновнойЭлементФормы") Тогда
// http://www.hostedredmine.com/issues/880476
ТекущийЭлемент = Неопределено;
КонецЕсли;
КонецЕсли;
Возврат ТекущийЭлемент;
КонецФункции
Процедура ЗапомнитьСодержимоеЭлементаАктивнойФормыДляСравненияЛкс(Форма = Неопределено) Экспорт
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма);
Если Истина
И ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы")
И ТипЗнч(ТекущийЭлемент) <> Тип("ТабличноеПоле")
И ТипЗнч(ТекущийЭлемент) <> Тип("ПолеТабличногоДокумента")
И Не (Истина
И ТипЗнч(ТекущийЭлемент) = Тип("ПолеФормы")
И ТекущийЭлемент.Вид = ВидПоляФормы.ПолеТабличногоДокумента)
Тогда
Возврат;
КонецЕсли;
ирОбщий.ЗапомнитьСодержимоеЭлементаФормыДляСравненияЛкс(Форма, ТекущийЭлемент);
КонецПроцедуры
Процедура ОткрытьТаблицуЗначенийИзАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт
ТекущаяСтрокаТаблицы = Неопределено;
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма);
Если Ложь
Или ТипЗнч(ТекущийЭлемент) = Тип("ТаблицаФормы")
Тогда
Результат = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТекущийЭлемент,, Истина, Ложь,,, Форма, ТекущаяСтрокаТаблицы);
ИначеЕсли ТипЗнч(ТекущийЭлемент) = Тип("ТабличноеПоле") Тогда
// Используем стандартный диалог, чтобы не терялась возможность оставить только видимые колонки
ИначеЕсли Ложь
Или ТипЗнч(ТекущийЭлемент) = Тип("ПолеТабличногоДокумента")
Или (Истина
И ТипЗнч(ТекущийЭлемент) = Тип("ПолеФормы")
И ТекущийЭлемент.Вид = ВидПоляФормы.ПолеТабличногоДокумента)
Тогда
ДанныеРасшифровки = ДанныеРасшифровкиУправляемойФормыОтчетаЛкс(Форма);
ТабличныйДокумент = ДанныеЭлементаФормыЛкс(ТекущийЭлемент);
Если ТабличныйДокумент = Неопределено Тогда
Возврат;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
ОбластьДляАнализа = Неопределено;
ТекущаяОбласть = ТабличныйДокумент.ТекущаяОбласть;
Если ТекущаяОбласть.Верх = ТекущаяОбласть.Низ Тогда
Ответ = Вопрос("Выделена только одна строка. Хотите обработать все строки?", РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Да);
Если Ответ = КодВозвратаДиалога.Да Тогда
ПерваяСтрокаОбласти = ТекущаяОбласть.Верх;
ШиринаКолонкиТекущейОбласти = ТабличныйДокумент.Область(ТекущаяОбласть.Верх, ТекущаяОбласть.Лево).ШиринаКолонки;
Для НомерСтроки = -ТекущаяОбласть.Верх + 1 По 0 Цикл
ШиринаКолонкиПроверяемойОбласти = ТабличныйДокумент.Область(-НомерСтроки, ТекущаяОбласть.Лево, -НомерСтроки, ТекущаяОбласть.Лево).ШиринаКолонки;
Если ШиринаКолонкиТекущейОбласти = 0 Тогда
ШиринаКолонкиТекущейОбласти = ШиринаКолонкиПроверяемойОбласти;
КонецЕсли;
Если ШиринаКолонкиТекущейОбласти <> ШиринаКолонкиПроверяемойОбласти Тогда
ПерваяСтрокаОбласти = -НомерСтроки + 1;
Прервать;
КонецЕсли;
КонецЦикла;
ОбластьДляАнализа = ТабличныйДокумент.Область(ПерваяСтрокаОбласти, ТекущаяОбласть.Лево, ТабличныйДокумент.ВысотаТаблицы, ТекущаяОбласть.Право);
КонецЕсли;
КонецЕсли;
Результат = ТаблицаКлючейИзТабличногоДокументаЛкс(ТабличныйДокумент, ДанныеРасшифровки,, ОбластьДляАнализа, ТекущаяСтрокаТаблицы);
#Если Сервер И Не Сервер Тогда
Результат = Новый ТаблицаЗначений;
#КонецЕсли
Если Результат.Колонки.Количество() = 0 Тогда
Ответ = Вопрос("Ячейки не содержат расшифровки. Хотите назначить имена колонкам из первой строки выделенной области?", РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Нет);
ЛиПерваяСтрокаСодержитИменаКолонок = Ответ = КодВозвратаДиалога.Да;
Результат = ТаблицаЗначенийИзТабличногоДокументаЛкс(ТабличныйДокумент, ЛиПерваяСтрокаСодержитИменаКолонок,,,, ?(ОбластьДляАнализа = Неопределено, Истина, ОбластьДляАнализа), ТекущаяСтрокаТаблицы);
КонецЕсли;
#Если Сервер И Не Сервер Тогда
Результат = Новый ТаблицаЗначений;
#КонецЕсли
Если ТекущаяСтрокаТаблицы <> Неопределено Тогда
ИндексТекущейСтроки = Результат.Индекс(ТекущаяСтрокаТаблицы);
КонецЕсли;
Результат = СузитьТипыКолонокТаблицыБезПотериДанныхЛкс(Результат);
Если ТекущаяСтрокаТаблицы <> Неопределено Тогда
ТекущаяСтрокаТаблицы = Результат[ИндексТекущейСтроки];
КонецЕсли;
ТекущийЭлемент = Неопределено;
Иначе
Возврат;
КонецЕсли;
Если Результат <> Неопределено Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаТаблицыЗначений = мПлатформа.ПолучитьФорму("ТаблицаЗначений", , Результат);
ФормаТаблицыЗначений.ПараметрТабличноеПоле = ТекущийЭлемент;
ФормаТаблицыЗначений.НачальноеЗначениеВыбора = Результат;
ФормаТаблицыЗначений.Открыть();
Если ТекущаяСтрокаТаблицы <> Неопределено Тогда
ФормаТаблицыЗначений.УстановитьТекущуюСтроку(ТекущаяСтрокаТаблицы, Результат);
КонецЕсли;
Иначе // ДинамическийСписок
ирОбщий.ВывестиСтрокиТабличногоПоляИПоказатьЛкс(ТекущийЭлемент);
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьТабличныйДокументИзАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Форма = ОткрытьФорму();
#КонецЕсли
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма);
Если Ложь
Или ТипЗнч(ТекущийЭлемент) = Тип("ПолеТабличногоДокумента")
Или (Истина
И ТипЗнч(ТекущийЭлемент) = Тип("ПолеФормы")
И ТекущийЭлемент.Вид = ВидПоляФормы.ПолеТабличногоДокумента)
Тогда
Результат = ДанныеЭлементаФормыЛкс(ТекущийЭлемент);
ДанныеРасшифровки = ДанныеРасшифровкиУправляемойФормыОтчетаЛкс(Форма);
КонецЕсли;
Если Результат <> Неопределено Тогда
Если ТипЗнч(ТекущийЭлемент) = Тип("ПолеТабличногоДокумента") Тогда
ДоступноИзменение = Истина
И Не ТекущийЭлемент.ТолькоПросмотр
И ТекущийЭлемент.ПолучитьДействие("ПриИзмененииСодержимогоОбласти") = Неопределено;
ирОбщий.ПолеТабличногоДокументаВосстановитьОформлениеТекущихСтрокЛкс(Форма, ТекущийЭлемент);
Иначе
ПутьКДанным = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТекущийЭлемент,, Форма);
ДоступноИзменение = Истина
И ТекущийЭлемент.Редактирование
И Не ТекущийЭлемент.Защита
И ЛиДоступноРедактированиеЭлементаУправляемойФормыЛкс(ТекущийЭлемент)
И ЗначениеЗаполнено(ПутьКДанным)
//И ТекущийЭлемент.ПолучитьДействие("ПриИзмененииСодержимогоОбласти") = Неопределено // но на клиенте его получить нельзя
;
КонецЕсли;
НовоеЗначение = ОткрытьТабличныйДокументРезультатаКомпоновкиЛкс(Результат, ДанныеРасшифровки,, ДоступноИзменение);
Если НовоеЗначение <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ТекущийЭлемент = Новый ТабличныйДокумент;
НовоеЗначение = Новый ТабличныйДокумент;
#КонецЕсли
Если ТипЗнч(ТекущийЭлемент) = Тип("ПолеТабличногоДокумента") Тогда
// Так только текущий язык останется
ТекущийЭлемент.ВставитьОбласть(НовоеЗначение.Область(),,, Ложь);
Если ТекущийЭлемент.ИзменяетДанные Тогда
Форма.Модифицированность = Истина;
КонецЕсли;
Иначе
Выполнить("Форма." + ПутьКДанным + " = НовоеЗначение");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ЛиДоступноРедактированиеЭлементаУправляемойФормыЛкс(Знач ТекущийЭлемент) Экспорт
Возврат РодительЭлементаУправляемойФормыЛкс(ТекущийЭлемент, "все", "ТолькоПросмотр", Истина) <> "Неопределено";
КонецФункции
Функция ОткрытьТабличныйДокументРезультатаКомпоновкиЛкс(Знач ПолеТабличногоДокумента, Знач ДанныеРасшифровки = Неопределено, Знач ИмяСохраненияПоложенияОкна = "", Знач Модально = Ложь) Экспорт
//ТабличныйДокумент = Новый ТабличныйДокумент;
//ТабличныйДокумент.Вывести(ПолеТабличногоДокумента);
ТабличныйДокумент = ПолучитьОбластьТабличногоДокументаИнтерактивноЛкс(ПолеТабличногоДокумента);
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
ТабличныйДокумент.ИмяСохраненияПоложенияОкна = ИмяСохраненияПоложенияОкна;
Если ДанныеРасшифровки <> Неопределено Тогда
УпроститьРасшифровкиТабличногоДокументаКомпоновкиЛкс(ТабличныйДокумент, ДанныеРасшифровки);
КонецЕсли;
Результат = Неопределено;
Если ОткрытьЗначениеЛкс(ТабличныйДокумент,,,, Модально,, ПолеТабличногоДокумента) Тогда
Результат = ТабличныйДокумент;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ДанныеРасшифровкиУправляемойФормыОтчетаЛкс(Знач Форма) Экспорт
ВозможныеИменаРеквизитов = Новый Массив;
ВозможныеИменаРеквизитов.Добавить("ДанныеРасшифровки");
ВозможныеИменаРеквизитов.Добавить("ОтчетДанныеРасшифровки");
Для Каждого ИмяРеквизита Из ВозможныеИменаРеквизитов Цикл
Попытка
ДанныеРасшифровки = Форма[ИмяРеквизита];
Прервать;
Исключение
ДанныеРасшифровки = Неопределено;
КонецПопытки;
КонецЦикла;
Если Истина
И ТипЗнч(ДанныеРасшифровки) = Тип("Строка")
И ЗначениеЗаполнено(ДанныеРасшифровки)
Тогда
ДанныеРасшифровки = ПолучитьИзВременногоХранилища(ДанныеРасшифровки);
КонецЕсли;
Возврат ДанныеРасшифровки;
КонецФункции
Процедура ОткрытьРазличныеЗначенияКолонкиАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма);
Если Истина
И ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы")
И ТипЗнч(ТекущийЭлемент) <> Тип("ТабличноеПоле")
Тогда
Возврат;
КонецЕсли;
ирОбщий.ОткрытьРазличныеЗначенияКолонкиЛкс(ТекущийЭлемент,,, Форма);
КонецПроцедуры
Процедура ОтладитьКомпоновкуДанныхАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт
Если Форма = Неопределено Тогда
Форма = АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если ТипЗнч(Форма) = Тип("УправляемаяФорма") Тогда
Попытка
НастройкиОтчета = Форма.НастройкиОтчета;
Исключение
НастройкиОтчета = Неопределено;
КонецПопытки;
Если НастройкиОтчета <> Неопределено И НастройкиОтчета.СхемаМодифицирована Тогда
// Стандартная форма отчета БСП
СхемаКомпоновки = ПолучитьИзВременногоХранилища(НастройкиОтчета.АдресСхемы);
Иначе
Фрагменты = СтрРазделитьЛкс(Форма.ИмяФормы);
Если Фрагменты[0] = ирОбщий.ПеревестиСтроку("Отчет") Тогда
ОтчетОбъект = Отчеты[Фрагменты[1]].Создать();
#Если Сервер И Не Сервер Тогда
ОтчетОбъект = Обработки.ирКонсольКомпоновокДанных.Создать();
#КонецЕсли
СхемаКомпоновки = ОтчетОбъект.СхемаКомпоновкиДанных;
//ИначеЕсли Фрагменты[0] = ирОбщий.ПеревестиСтроку("ВнешнийОтчет") Тогда
// // https://forum.mista.ru/topic.php?id=857116
// ОтчетОбъект = ВнешниеОтчеты.Создать(Фрагменты[1]);
// #Если Сервер И Не Сервер Тогда
// ОтчетОбъект = ВнешниеОтчеты.Создать();
// #КонецЕсли
// СхемаКомпоновки = ОтчетОбъект.СхемаКомпоновкиДанных;
Иначе
СообщитьЛкс(СтрШаблонИменЛкс("Не поддерживаемый тип метаданных отчета - %1",, Фрагменты[0]));
Возврат;
КонецЕсли;
КонецЕсли;
КомпоновщикНастроек = Форма.Отчет.КомпоновщикНастроек;
Иначе
Попытка
ОбщийМодульТиповыеОтчеты = Вычислить("ТиповыеОтчеты");
Исключение
КонецПопытки;
Если Истина
И ОбщийМодульТиповыеОтчеты <> Неопределено
И МетодРеализованЛкс(ОбщийМодульТиповыеОтчеты, "ЗагрузитьВРеквизитЗначенияНастроекПанелиПользователя")
Тогда
ОбщийМодульТиповыеОтчеты.ЗагрузитьВРеквизитЗначенияНастроекПанелиПользователя(Форма.ЭтотОбъект, Форма);
ОбщийМодульТиповыеОтчеты.ПолучитьПримененуюНастройку(Форма.ЭтотОбъект);
КонецЕсли;
СхемаКомпоновки = Форма.СхемаКомпоновкиДанных;
КомпоновщикНастроек = Форма.КомпоновщикНастроек;
КонецЕсли;
ОтладитьЛкс(СхемаКомпоновки,, КомпоновщикНастроек.ПолучитьНастройки());
КонецПроцедуры
Процедура РедактироватьАктивныйСписокЗначенийУправляемыйЛкс(Форма = Неопределено) Экспорт
Если Форма = Неопределено Тогда
Форма = АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если ТипЗнч(Форма) <> Тип("УправляемаяФорма") Тогда
Возврат;
КонецЕсли;
ПутьКДанным = "";
ДанныеЭлементаФормыЛкс(Форма.ТекущийЭлемент, ПутьКДанным);
Если Не ЗначениеЗаполнено(ПутьКДанным) Тогда
Возврат;
КонецЕсли;
СтруктураОтбора = СтруктураОтбораПоСвязямИПараметрамВыбораЛкс(Форма.Элементы.Value);
ирОбщий.ОткрытьСписокЗначенийЛкс(Форма[ПутьКДанным], СтруктураОтбора);
КонецПроцедуры
Процедура НастроитьДинамическийСписокАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма);
Если ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы") Тогда
Возврат;
КонецЕсли;
ДанныеЭлемента = ДанныеЭлементаФормыЛкс(ТекущийЭлемент);
Если ТипЗнч(ДанныеЭлемента) <> Тип("ДинамическийСписок") Тогда
Возврат;
КонецЕсли;
Параметры = Новый Структура("Настройки, ПользовательскиеНастройки, ФиксированныеНастройки, ИсточникДоступныхНастроек");
СхемаИНастройки = ИсполняемыеСхемаИНастройкиСпискаУправляемойФормаЛкс(Форма);
Если СхемаИНастройки <> Неопределено Тогда
Параметры.Вставить("ИсполняемаяСхема", ПоместитьВоВременноеХранилище(СхемаИНастройки.Схема, Форма.УникальныйИдентификатор));
Параметры.Вставить("ИсполняемыеНастройки", СхемаИНастройки.Настройки);
КонецЕсли;
ЗаполнитьЗначенияСвойств(Параметры, ДанныеЭлемента.КомпоновщикНастроек);
Параметры.ИсточникДоступныхНастроек = ДанныеЭлемента.КомпоновщикНастроек.ПолучитьИсточникДоступныхНастроек();
Если ирКэш.НомерВерсииПлатформыЛкс() > 803001 Тогда
Выполнить("ОткрытьФорму(""Обработка.ирДинамическийСписок.Форма.НастройкиСпискаУпр"", Параметры, ТекущийЭлемент,,,,, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца)");
Иначе
ОткрытьФормуМодально("Обработка.ирДинамическийСписок.Форма.НастройкиСпискаУпр", Параметры, ТекущийЭлемент);
КонецЕсли;
КонецПроцедуры
Функция ИсполняемыеСхемаИНастройкиСпискаУправляемойФормаЛкс(Знач Форма) Экспорт
Если Форма.ИмяФормы = "Обработка.ирДинамическийСписок.Форма.ФормаУпр" Тогда
СхемаИНастройки = Форма.ИсполняемыеСхемаИНастройки();
Иначе
#Если Сервер И Не Сервер Тогда
ирОбщий.УправляемаяФормаБСП_ИсполняемыеСхемаИНастройкиТаблицыЛкс();
#КонецЕсли
СхемаИНастройки = УправляемаяФормаБСП_ВыполнитьНаСервереЛкс(Форма, "ирОбщий.УправляемаяФормаБСП_ИсполняемыеСхемаИНастройкиТаблицыЛкс");
КонецЕсли;
Возврат СхемаИНастройки;
КонецФункции
Процедура ОткрытьДинамическийСписокАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма);
ДанныеЭлемента = ДанныеЭлементаФормыЛкс(ТекущийЭлемент);
Если ТипЗнч(ДанныеЭлемента) <> Тип("ДинамическийСписок") Тогда
Возврат;
КонецЕсли;
ПолноеИмяТаблицыБД = "";
ОбщийТипДанныхТаблицы = ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(ТекущийЭлемент,,, ПолноеИмяТаблицыБД);
Если ПолноеИмяТаблицыБД = Неопределено Тогда
Возврат;
КонецЕсли;
КомпоновщикНастроек = ДанныеЭлемента.КомпоновщикНастроек;
#Если Сервер И Не Сервер Тогда
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
#КонецЕсли
НастройкиСписка = КомпоновщикНастроек.ПолучитьНастройки();
ТекущаяКолонка = ДанныеЭлементаФормыЛкс(ТекущийЭлемент.ТекущийЭлемент);
Форма = ПолучитьФормуСпискаЛкс(ПолноеИмяТаблицыБД,, Истина,,,, ТекущийЭлемент.ТекущаяСтрока, НастройкиСписка.Отбор, ПолноеИмяТаблицыБД, ТекущаяКолонка);
Форма.Открыть();
КонецПроцедуры
Процедура ОтборБезЗначенияВТекущейКолонкеАктивнойФормыЛкс(Параметры) Экспорт
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Параметры.Форма);
Если Истина
И ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы")
И ТипЗнч(ТекущийЭлемент) <> Тип("ТабличноеПоле")
Тогда
Возврат;
КонецЕсли;
ОбщийТипДанныхТаблицы = ОбщийТипДанныхТабличногоПоляЛкс(ТекущийЭлемент);
Если Истина
И ОбщийТипДанныхТаблицы <> "Список"
И ОбщийТипДанныхТаблицы <> "ТабличнаяЧасть"
И ОбщийТипДанныхТаблицы <> "НаборЗаписей"
Тогда
Возврат;
КонецЕсли;
ТабличноеПолеОтборДляЗначенияВТекущейКолонкеЛкс(ТекущийЭлемент);
КонецПроцедуры
Процедура НайтиВыбратьСсылкуВДинамическомСпискеЛкс(Форма = Неопределено) Экспорт
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма);
Если Истина
И ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы")
И ТипЗнч(ТекущийЭлемент) <> Тип("ТабличноеПоле")
Тогда
Возврат;
КонецЕсли;
ИмяТаблицыБД = ирОбщий.ИмяТаблицыБДДинамическогоСпискаЛкс(ТекущийЭлемент);
Если Не ЗначениеЗаполнено(ИмяТаблицыБД) Тогда
Возврат;
КонецЕсли;
НайтиВыбратьСсылкуВДинамическомСпискеПоIDЛкс(ТекущийЭлемент);
КонецПроцедуры
Процедура НайтиВыбратьСсылкуВДинамическомСпискеПоIDЛкс(Знач ТабличноеПоле, Форма = Неопределено) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаВводаИдентификатора = мПлатформа.ПолучитьФорму("УникальныйИдентификатор");
НовыйИдентификатор = ФормаВводаИдентификатора.ОткрытьМодально();
Если НовыйИдентификатор = Неопределено Тогда
Возврат;
КонецЕсли;
Ссылка = ирОбщий.ПолучитьМенеджерЛкс(ирОбщий.ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле)).ПолучитьСсылку(НовыйИдентификатор);
ДинамическийСписокУстановитьТекущуюСтрокуСКонтролемЛкс(ТабличноеПоле, Ссылка, Форма);
КонецПроцедуры
Процедура ДинамическийСписокУстановитьТекущуюСтрокуСКонтролемЛкс(ТабличноеПоле, Ссылка, Форма = Неопределено) Экспорт
ТабличноеПоле.ТекущаяСтрока = Ссылка;
Если ТабличноеПоле.ТекущаяСтрока = Ссылка Тогда
СообщитьЛкс("Объект найден и установлен текущей строкой");
Иначе
Если Форма = Неопределено Тогда
Форма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле);
КонецЕсли;
Если Не ирОбщий.ЛиСуществуетОбъектПоСсылкеЛкс(Ссылка) Тогда
Если ТабличноеПоле.РежимВыбора Тогда
Ответ = Вопрос("Объект не найден в таблице. Выбрать ссылку?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
Форма.ОповеститьОВыборе(Ссылка);
КонецЕсли;
Иначе
СообщитьЛкс("Объект не найден в таблице");
КонецЕсли;
Иначе
Если ТабличноеПоле.РежимВыбора Тогда
Ответ = Вопрос("Объект найден в таблице, но не отвечает текущему отбору. Выбрать ссылку?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
Форма.ОповеститьОВыборе(Ссылка);
КонецЕсли;
Иначе
СообщитьЛкс("Объект найден в таблице, но не отвечает текущему отбору");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ЗапросДинамическогоСпискаЛкс(Знач ТабличноеПоле, Знач ПолноеИмяТаблицыБД = "", Знач УчитываяОтбор = Истина, Знач АнализируемоеПоле = "", Компоновщик = Неопределено) Экспорт
ДанныеТабличногоПоля = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
Если Не ЗначениеЗаполнено(ПолноеИмяТаблицыБД) Тогда
ПолноеИмяТаблицыБД = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле);
КонецЕсли;
ПоляТаблицыБД = ирКэш.ПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД);
#Если Сервер И Не Сервер Тогда
ПоляТаблицыБД = НайтиПоСсылкам().Колонки;
#КонецЕсли
ЕстьПрисоединенныеПоля = ЗначениеЗаполнено(АнализируемоеПоле) И ПоляТаблицыБД.Найти(АнализируемоеПоле, "Имя") = Неопределено;
Если Не ЕстьПрисоединенныеПоля И УчитываяОтбор Тогда
ПоляОтбора = Новый Соответствие;
НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДанныеТабличногоПоля);
НайтиЭлементОтбораЛкс(НастройкиСписка.Отбор,, ПоляОтбора,, Истина,, Истина);
Для Каждого КлючИЗначение Из ПоляОтбора Цикл
Если ПоляТаблицыБД.Найти(КлючИЗначение.Ключ, "Имя") = Неопределено Тогда
ЕстьПрисоединенныеПоля = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Запрос = Неопределено;
Если Не ЕстьПрисоединенныеПоля Тогда
Запрос = Новый Запрос;
Иначе
СхемаИНастройки = ИсполняемыеСхемаИНастройкиСпискаУправляемойФормаЛкс(РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле));
Если СхемаИНастройки <> Неопределено Тогда
Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
СхемаКомпоновки = СхемаИНастройки.Схема;
НастройкаКомпоновки = СхемаИНастройки.Настройки;
#Если Сервер И Не Сервер Тогда
СхемаКомпоновки = Новый СхемаКомпоновкиДанных;
#КонецЕсли
Если Не УчитываяОтбор Тогда
НастройкаКомпоновки.Отбор.Элементы.Очистить();
ИначеЕсли ЗначениеЗаполнено(АнализируемоеПоле) Тогда
ЭлементОтбораКолонки = НайтиДобавитьЭлементОтбораКомпоновкиЛкс(НастройкаКомпоновки.Отбор, АнализируемоеПоле);
Если ЭлементОтбораКолонки <> Неопределено Тогда
ЭлементОтбораКолонки.Использование = Ложь;
КонецЕсли;
КонецЕсли;
Компоновщик.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки));
Запрос = ЗапросИзКомпоновкиЛкс(СхемаКомпоновки, НастройкаКомпоновки);
КонецЕсли;
КонецЕсли;
Возврат Запрос;
КонецФункции
Процедура ДобавитьКолонкиГруппыФормыВТаблицуЗначенийЛкс(Знач КолонкиИсточника, Знач Результат, Знач СтрокаИлиКоллекция, Знач ИменаКолонокРезультата = "")
Если ТипЗнч(ИменаКолонокРезультата) = Тип("Строка") И ЗначениеЗаполнено(ИменаКолонокРезультата) Тогда
ИменаКолонокРезультата = СтрРазделитьЛкс(ИменаКолонокРезультата, ",", Истина);
ИначеЕсли ТипЗнч(ИменаКолонокРезультата) = Тип("Массив") Тогда
Иначе
ИменаКолонокРезультата = Неопределено;
КонецЕсли;
Для Каждого ПолеТаблицыФормы Из КолонкиИсточника Цикл
Если ТипЗнч(ПолеТаблицыФормы) = Тип("ГруппаФормы") Тогда
ДобавитьКолонкиГруппыФормыВТаблицуЗначенийЛкс(ПолеТаблицыФормы.ПодчиненныеЭлементы, Результат, СтрокаИлиКоллекция, ИменаКолонокРезультата);
Продолжить;
КонецЕсли;
ПолноеИмяПоля = ПолеТаблицыФормы.Имя;
ПутьКДанным = НайтиПутьКДаннымПоляТаблицыФормыЛкс(СтрокаИлиКоллекция, ПолноеИмяПоля);
Если Истина
И ЗначениеЗаполнено(ПутьКДанным)
И (Ложь
Или ИменаКолонокРезультата = Неопределено
Или ИменаКолонокРезультата.Найти(ПутьКДанным) <> Неопределено)
Тогда
Результат.Колонки.Добавить(СтрЗаменить(ПутьКДанным, ".", "_"),, ПутьКДанным);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ОткрытьСтатистикаMSSQLПоПоследнимЗапросамЛкс(ДатаНачала, ДатаКонца) Экспорт
ОтчетОбъект = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Отчет.ирСтатистикаПоЗапросамСУБД");
#Если Сервер И Не Сервер Тогда
ОтчетОбъект = Отчеты.ирСтатистикаПоЗапросамСУБД.Создать();
#КонецЕсли
КлючВарианта = "Последние";
ФормаОтчета = ОтчетОбъект.ПолучитьФорму(,, КлючВарианта);
ФормаОтчета.ПараметрКлючВарианта = КлючВарианта;
ФормаОтчета.Открыть();
НастройкиОтчета = ФормаОтчета.КомпоновщикНастроек.Настройки;
#Если Сервер И Не Сервер Тогда
НастройкиОтчета = Компоновщик.Настройки;
#КонецЕсли
НастройкиОтчета.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ПопавшиеВПоследниеМинут")).Использование = Ложь;
НастройкиОтчета.ПараметрыДанных.УстановитьЗначениеПараметра("НачалоИнтервала", ДатаНачала);
НастройкиОтчета.ПараметрыДанных.УстановитьЗначениеПараметра("КонецИнтервала", ДатаКонца);
ФормаОтчета.ДействияФормыСформировать();
КонецФункции
Процедура ЗаполнитьИзмененыеПоляВСтрокеВерсииДанныхЛкс(Знач ДанныеСтроки, Знач КлючОбъекта = Неопределено, Знач ПолноеИмяМД = "") Экспорт
#Если Сервер И Не Сервер Тогда
ДанныеСтроки = Обработки.ирИсторияДанных.Создать().Версии.Добавить();
#КонецЕсли
Если ДанныеСтроки.ИзмененныеПоля = "?" Тогда
Если ДанныеСтроки.НомерВерсии > 1 Тогда
ИсторияДанныхМоя = Вычислить("ИсторияДанных");
#Если Сервер И Не Сервер Тогда
ИсторияДанныхМоя = ИсторияДанных;
#КонецЕсли
Если КлючОбъекта = Неопределено Тогда
КлючОбъекта = КлючОбъектаСтрокиВерсииДанныхЛкс(ДанныеСтроки, ПолноеИмяМД);
КонецЕсли;
Попытка
СтруктураРазличий = ИсторияДанныхМоя.ПолучитьРазличияВерсий(КлючОбъекта, ДанныеСтроки.НомерВерсии);
Исключение
// Может быть ошибка "Данные истории не найдены"
Пустышка = 0;
КонецПопытки;
Если СтруктураРазличий <> Неопределено Тогда
ИзмененныеПоля = Новый СписокЗначений;
Для Каждого КлючИЗначение Из СтруктураРазличий Цикл
ИзмененныеПоля.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
ИзмененныеПоля.СортироватьПоЗначению();
ДанныеСтроки.ИзмененныеПоля = ирОбщий.СтрСоединитьЛкс(ИзмененныеПоля);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция КлючОбъектаСтрокиВерсииДанныхЛкс(Знач ДанныеСтроки, Знач ПолноеИмяМД) Экспорт
КлючОбъекта = ДанныеСтроки.Данные;
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ПолноеИмяМД);
Если НадоСериализоватьКлючДанныхДляОтображенияЛкс(КорневойТип) Тогда
Попытка
КлючОбъекта = ЗначениеИзСтрокиВнутрЛкс(КлючОбъекта);
Исключение
// Некоторые большие ключи регистров в сериализованном виде не умещаются в 1024 символа
КлючОбъекта = "<Ключ записи регистра обрезан и не может быть восстановлен>";
КонецПопытки;
ИначеЕсли ЛиКорневойТипКонстантыЛкс(КорневойТип) Тогда
КлючОбъекта = КлючОбъектаКонстантыЛкс(ПоследнийФрагментЛкс(ПолноеИмяМД));
КонецЕсли;
Возврат КлючОбъекта;
КонецФункции
Процедура Форма_ОткрытьБезЗахватаФокусаЛкс(Форма) Экспорт
АктивнаяФорма = АктивнаяФормаЛкс();
Форма.Открыть();
Если АктивнаяФорма <> Неопределено Тогда
Форма_АктивироватьОткрытьЛкс(АктивнаяФорма);
КонецЕсли;
КонецПроцедуры
Функция ДобавитьОтборВИсториюТабличногоПоляЛкс(Знач ЭтаФорма, Знач ТабличноеПолеИлиКлюч, Знач Отбор, СтарыйОтбор, Знач ИгнорироватьЭлементы = "") Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый ПостроительЗапроса;
Отбор = Пустышка.Отбор;
СтарыйОтбор = Пустышка.Отбор;
#КонецЕсли
ДобавленВСписок = Ложь;
Если Строка(Отбор) <> Строка(СтарыйОтбор) Тогда
Если "" + Отбор <> "" Тогда
Если Истина
И ТипЗнч(ТабличноеПолеИлиКлюч) = Тип("Строка")
И ТипЗнч(СтарыйОтбор) = Тип("Отбор")
Тогда
Для Каждого ЭлементОтбора Из Отбор Цикл
СтарыйЭлементОтбора = НайтиЭлементОтбораЛкс(СтарыйОтбор, ЭлементОтбора.Имя);
Если Истина
И ЭлементОтбора.Использование
И (Ложь // Защита от попадания в историю промежуточных строк горячего фильтра по подстроке
Или Форма_ВводДоступенЛкс(ЭтаФорма)
Или (Истина
И ЭлементОтбора.ВидСравнения <> ВидСравнения.НеСодержит
И ЭлементОтбора.ВидСравнения <> ВидСравнения.Содержит))
И (Ложь
Или СтарыйЭлементОтбора = Неопределено
Или СтарыйЭлементОтбора.Значение <> ЭлементОтбора.Значение)
Тогда
ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(ЭлементОтбора, ТабличноеПолеИлиКлюч);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ТипЗнч(ТабличноеПолеИлиКлюч) = Тип("Строка") Тогда
Компоновщик = ирКэш.КомпоновщикТаблицыМетаданныхЛкс(ТабличноеПолеИлиКлюч);
Иначе
#Если Клиент Тогда
Схема = СоздатьСхемуПоТаблицамЗначенийЛкс(Новый Структура("Т", ТабличноеПолеИлиКлюч.Значение.ВыгрузитьКолонки()));
Компоновщик = КомпоновщикПоСхемеКомпоновкиЛкс(Схема);
#КонецЕсли
КонецЕсли;
НастройкаКомпоновки = Компоновщик.Настройки;
СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, Отбор, Истина,,,, ИгнорироватьЭлементы);
ПредставлениеОтбора = ПредставлениеЗначенияСОграничениемДлиныЛкс(НастройкаКомпоновки.Отбор, 150);
Если ПредставлениеОтбора <> "" Тогда
ДобавленВСписок = ПоследниеВыбранныеДобавитьЛкс(ЭтаФорма, НастройкаКомпоновки, ПредставлениеОтбора, ТабличноеПолеИлиКлюч, "Отборы", Истина);
КонецЕсли;
КонецЕсли;
ПостроительЗапроса = Новый ПостроительЗапроса;
Если ТипЗнч(ТабличноеПолеИлиКлюч) = Тип("Строка") Тогда
ПустаяТаблица = ПустаяТаблицаЗначенийИзТаблицыБДЛкс(ТабличноеПолеИлиКлюч);
Иначе
ПустаяТаблица = ТабличноеПолеИлиКлюч.Значение;
КонецЕсли;
ПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ПустаяТаблица);
СтарыйОтбор = ПостроительЗапроса.Отбор;
СкопироватьОтборПостроителяЛкс(СтарыйОтбор, Отбор,, Истина);
КонецЕсли;
Возврат ДобавленВСписок;
КонецФункции
Функция ДобавитьОтборКомпоновкиВИсториюТаблицыБДЛкс(Знач ЭтаФорма, Знач ПолноеИмяТаблицы, Знач АктивнаяНастройка, Знач СтараяНастройка) Экспорт
#Если Сервер И Не Сервер Тогда
СтараяНастройка = Новый НастройкиКомпоновкиДанных;
АктивнаяНастройка = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
СтарыйОтбор = СтараяНастройка.Отбор;
Отбор = АктивнаяНастройка.Отбор;
ДобавленВСписок = Ложь;
Если Строка(Отбор) <> Строка(СтарыйОтбор) Тогда
Если "" + Отбор <> "" Тогда
Для Каждого ЭлементОтбора Из Отбор.Элементы Цикл
Если Ложь
Или ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
Или Найти(ЭлементОтбора.ЛевоеЗначение, ".") > 0
Тогда
Продолжить;
КонецЕсли;
СтарыйЭлементОтбора = ирОбщий.НайтиЭлементОтбораЛкс(СтарыйОтбор, "" + ЭлементОтбора.ЛевоеЗначение);
Если Истина
И ЭлементОтбора.Использование
И (Ложь // Защита от попадания в историю промежуточных строк горячего фильтра по подстроке
Или Форма_ВводДоступенЛкс(ЭтаФорма)
Или (Истина
И ЭлементОтбора.ВидСравнения <> ВидСравненияКомпоновкиДанных.НеСодержит
И ЭлементОтбора.ВидСравнения <> ВидСравненияКомпоновкиДанных.Содержит))
И (Ложь
Или СтарыйЭлементОтбора = Неопределено
Или СтарыйЭлементОтбора.ПравоеЗначение <> ЭлементОтбора.ПравоеЗначение)
Тогда
ирОбщий.ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(ЭлементОтбора, ПолноеИмяТаблицы);
КонецЕсли;
КонецЦикла;
Компоновщик = ирКэш.КомпоновщикТаблицыМетаданныхЛкс(ПолноеИмяТаблицы);
НастройкаКомпоновки = Компоновщик.Настройки;
ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, Отбор, Истина);
ДобавленВСписок = ирОбщий.ПоследниеВыбранныеДобавитьЛкс(ЭтаФорма, НастройкаКомпоновки, ПредставлениеЗначенияСОграничениемДлиныЛкс(НастройкаКомпоновки.Отбор, 150), ПолноеИмяТаблицы, "Отборы", Истина);
КонецЕсли;
ирОбщий.СкопироватьНастройкиКомпоновкиЛкс(АктивнаяНастройка, СтараяНастройка, Истина);
КонецЕсли;
Возврат ДобавленВСписок;
КонецФункции
#КонецЕсли
#Если Клиент Тогда
// Эта обертка нужно для возможности привязать ее к команде панели инструментов
Процедура ОтладитьОтложенныйОбъектБезПараметровЛкс() Экспорт
Если Не ПроверитьЧтоСеансТолстогоКлиентаЛкс() Тогда
Возврат;
КонецЕсли;
#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
ОтладитьОтложенныйОбъектЛкс();
#КонецЕсли
КонецПроцедуры
Процедура УстановитьПрикреплениеФормыВУправляемомПриложенииЛкс(Этаформа, ПроверитьДоступностьВвода = Ложь, ПоложениеПрикрепленногоОкна = Неопределено) Экспорт
#Если Не ВебКлиент Тогда
Если ирКэш.ЛиСеансТолстогоКлиентаУПЛкс() И Не Этаформа.МодальныйРежим Тогда
Если ПроверитьДоступностьВвода И Не Форма_ВводДоступенЛкс(Этаформа) Тогда // При открытии формы ВводДоступен() всегда равно Ложь
Возврат;
КонецЕсли;
Если ПоложениеПрикрепленногоОкна = Неопределено Тогда
Если ЭтаФорма.СостояниеОкна = ВариантСостоянияОкна.Прикрепленное Тогда
ПоложениеПрикрепленногоОкна = ЭтаФорма.ПоложениеПрикрепленногоОкна;
КонецЕсли;
КонецЕсли;
Если ПоложениеПрикрепленногоОкна <> Неопределено Тогда
ОжидатьЗавершения = Ложь; // Вроде не играет роли
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803017 Тогда
Если Истина
И ТипЗнч(ЭтаФорма) = Тип("Форма")
И ирКэш.НомерВерсииПлатформыЛкс() < 803021
Тогда
КомандаАктивацииПунктаОкна = "{UP 2}";
Иначе
КомандаАктивацииПунктаОкна = "{UP 4}";
КонецЕсли;
ОтправитьНажатияКлавишЛкс("%-", ОжидатьЗавершения); // Такой вызов меню окна не работает в 8.3.15-16
ОтправитьНажатияКлавишЛкс(КомандаАктивацииПунктаОкна, ОжидатьЗавершения);
ОтправитьНажатияКлавишЛкс("{ENTER}", ОжидатьЗавершения);
// Снизу может находиться пункт меню "Сообщения", если было выведено хотя бы одно сообщение
//Если ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Верх Тогда
// ОтправитьНажатияКлавишЛкс("{UP 3}", ОжидатьЗавершения);
//ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Низ Тогда
// ОтправитьНажатияКлавишЛкс("{UP 2}", ОжидатьЗавершения);
//ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Лево Тогда
// ОтправитьНажатияКлавишЛкс("{UP 5}", ОжидатьЗавершения);
//ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Право Тогда
// ОтправитьНажатияКлавишЛкс("{UP 4}", ОжидатьЗавершения);
//КонецЕсли;
Если ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Верх Тогда
ОтправитьНажатияКлавишЛкс("{Down 4}", ОжидатьЗавершения);
ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Низ Тогда
ОтправитьНажатияКлавишЛкс("{Down 5}", ОжидатьЗавершения);
ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Лево Тогда
ОтправитьНажатияКлавишЛкс("{Down 2}", ОжидатьЗавершения);
ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Право Тогда
ОтправитьНажатияКлавишЛкс("{Down 3}", ОжидатьЗавершения);
КонецЕсли;
ОтправитьНажатияКлавишЛкс("{ENTER}", ОжидатьЗавершения);
ИначеЕсли ирКэш.НомерВерсииПлатформыЛкс() >= 803015 Тогда
// ОтправитьНажатияКлавишЛкс("%-"); // Такой вызов меню окна не работает в 8.3.15-16
Иначе
ОтправитьНажатияКлавишЛкс("%", ОжидатьЗавершения);
ОтправитьНажатияКлавишЛкс("{Down 1}", ОжидатьЗавершения);
// https://www.hostedredmine.com/issues/927695
//ОтправитьНажатияКлавишЛкс("{О}", ОжидатьЗавершения); // Привязка к русскому языку ввода
ОтправитьНажатияКлавишЛкс("{Down 4}", ОжидатьЗавершения); // Если использовать UP то будет проход через опциональный пункт "Функции для технического специалиста"
ОтправитьНажатияКлавишЛкс("{ENTER}", ОжидатьЗавершения);
Если ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Верх Тогда
ОтправитьНажатияКлавишЛкс("{UP 4}", ОжидатьЗавершения);
ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Низ Тогда
ОтправитьНажатияКлавишЛкс("{UP 3}", ОжидатьЗавершения);
ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Лево Тогда
ОтправитьНажатияКлавишЛкс("{UP 6}", ОжидатьЗавершения);
ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Право Тогда
ОтправитьНажатияКлавишЛкс("{UP 5}", ОжидатьЗавершения);
КонецЕсли;
ОтправитьНажатияКлавишЛкс("{ENTER}", ОжидатьЗавершения);
КонецЕсли;
КонецЕсли;
КонецЕсли;
#КонецЕсли
КонецПроцедуры
// https://docs.microsoft.com/ru-ru/office/vba/language/reference/user-interface-help/sendkeys-statement
// Параметры:
// СтрокаКлавиш - Строка - SHIFT +, CTRL ^, ALT %
//
Процедура ОтправитьНажатияКлавишЛкс(СтрокаКлавиш, ОжидатьЗавершения = Ложь) Экспорт
Если Не ирКэш.ЛиПлатформаWindowsЛкс() Тогда
Возврат;
КонецЕсли;
ирПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
ирПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ирПлатформа.WshShell().SendKeys(СтрокаКлавиш, ОжидатьЗавершения); // При этом почему то NumLock перенажимается
КонецПроцедуры
Процедура ОткрытьСписокИнструментовЛкс() Экспорт
ОткрытьПанельИнструментовЛкс(Истина, Ложь);
КонецПроцедуры
Процедура ОткрытьПанельИнструментовЛкс(ТолькоОткрытьФормуСпискаИнструментов = Ложь, ОткрытьСтраницуНастроек = Ложь) Экспорт
Если ПроверитьЧтоСеансТолстогоКлиентаЛкс() Тогда
#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
ФормаСпискаИнструментов = ПолучитьФормуЛкс("Обработка.ирПортативный.Форма.Форма");
Если ФормаСпискаИнструментов.Открыта() Тогда
ФормаСпискаИнструментов.ПараметрТолькоОткрытьНастройки = ТолькоОткрытьФормуСпискаИнструментов;
ФормаСпискаИнструментов.Открыть();
Иначе
//ирОбщий.ОткрытьПанельИнструментовЛкс(Истина); // Так будут считаны настройки
ФормаНастроек = ирОбщий.ОткрытьФормуЛкс("Обработка.ирПортативный.Форма.ФормаНастроек");
Если ОткрытьСтраницуНастроек Тогда
ФормаНастроек.ЭлементыФормы.Панель.ТекущаяСтраница = ФормаНастроек.ЭлементыФормы.Панель.Страницы.Настройки;
КонецЕсли;
КонецЕсли;
#КонецЕсли
КонецЕсли;
КонецПроцедуры
Процедура СохранитьНастройкиПользователяЛкс() Экспорт
Если Не ПроверитьЧтоСеансТолстогоКлиентаЛкс() Тогда
Возврат;
КонецЕсли;
#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
СохранитьНастройкиПользователя();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьНастройкиАлгоритмовЛкс() Экспорт
Если Не ПроверитьЧтоСеансТолстогоКлиентаЛкс() Тогда
Возврат;
КонецЕсли;
#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
Если ирКэш.ЛиЭтоРасширениеКонфигурацииЛкс() Тогда
СообщитьЛкс("Команда недоступна в варианте Расширение");
Возврат;
КонецЕсли;
Форма = ирКэш.Получить().ПолучитьФорму("НастройкиАлгоритмов");
Форма.Открыть();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьРегистрацияCOMКомпонентЛкс() Экспорт
ОткрытьФормуЛкс("Обработка.ирПлатформа.Форма.РегистрацияCOMКомпонент");
КонецПроцедуры
Процедура ОткрытьОтладкаВнешнихОбработокБСПЛкс() Экспорт
ОткрытьФормуЛкс("ОбщаяФорма.ирОтладкаВнешнихОбработокБСП");
КонецПроцедуры
Процедура ОткрытьОбработкаМодулейМетаданныхЛкс() Экспорт
Если Не ПроверитьЧтоСеансТолстогоКлиентаЛкс() Тогда
Возврат;
КонецЕсли;
#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
Форма = ирКэш.Получить().ПолучитьФорму("ОбработкаМодулейМетаданных");
Форма.Открыть();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьПодключениеВнешнихИсточниковДанныхЛкс() Экспорт
Если Не ПроверитьЧтоСеансТолстогоКлиентаЛкс() Тогда
Возврат;
КонецЕсли;
#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
Форма = ирКэш.Получить().ПолучитьФорму("ПодключениеВнешнихИсточниковДанных");
Форма.Открыть();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьГлобальноеМенюЛкс(АктивнаяФорма = Неопределено) Экспорт
Если Не ПроверитьЧтоСеансТолстогоКлиентаЛкс() Тогда
Возврат;
КонецЕсли;
#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
Если АктивнаяФорма = Неопределено Тогда
АктивнаяФорма = АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если АктивнаяФорма = Неопределено Тогда
Возврат;
КонецЕсли;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Форма = мПлатформа.ПолучитьФорму("ГлобальноеМеню");
Если Не Форма.Открыта() Тогда
Форма.АктивнаяФорма = АктивнаяФорма;
Форма.ОткрытьМодально();
КонецЕсли;
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьФункцииРежимаОтладкиЛкс() Экспорт
Если Не ПроверитьЧтоСеансТолстогоКлиентаЛкс() Тогда
Возврат;
КонецЕсли;
#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
Форма = ирКэш.Получить().ПолучитьФорму("ФункцииРежимаОтладки");
Форма.Открыть();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьЗапускСеансаЛкс() Экспорт
#Если ВебКлиент Тогда
Сообщить("Команда недоступна в вебклиенте");
#ИначеЕсли ТолстыйКлиентОбычноеПриложение Тогда
ОткрытьФормуЛкс("Обработка.ирПортативный.Форма.ЗапускСеансаОбычная");
#Иначе
ОткрытьФормуЛкс("Обработка.ирПортативный.Форма.ЗапускСеансаУправляемая");
#КонецЕсли
КонецПроцедуры
// Открывает справку по первой подсистеме метаданных переданного объекта
//
// Параметры:
// Объект - любой объект, имеющий метаданные.
//
Процедура ОткрытьСправкуПоПодсистемеЛкс(Объект = Неопределено) Экспорт
Если Не ПроверитьЧтоСеансТолстогоКлиентаЛкс() Тогда
Возврат;
КонецЕсли;
#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
Если Ложь
Или ТипЗнч(Объект) = Тип("Неопределено")
Или ТипЗнч(Объект) = Тип("ОкноКлиентскогоПриложения")
Тогда
//
ИначеЕсли ТипЗнч(Объект) = Тип("Форма") Тогда
ПолноеИмяМД = СлужебныеДанныеФормыЛкс(Объект).ИмяФормы;
ИначеЕсли ТипЗнч(Объект) = Тип("УправляемаяФорма") Тогда
ПолноеИмяМД = Объект.ИмяФормы;
Иначе
Если ТипЗнч(Объект) = Тип("Тип") Тогда
ОбъектМД = Метаданные.НайтиПоТипу(Объект);
Иначе
ОбъектМД = Объект.Метаданные();
КонецЕсли;
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ПолноеИмяМД = СтрЗаменить(ПолноеИмяМД, "ВнешняяОбработка.", "Обработка.");
ПолноеИмяМД = СтрЗаменить(ПолноеИмяМД, "ВнешнийОтчет.", "Отчет.");
КонецЕсли;
Форма = ирКэш.Получить().ПолучитьФорму("ОПодсистеме",, ПолноеИмяМД);
Форма.Открыть();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьНастройкуТехножурналаПоПользователюЛкс() Экспорт
ФормаНастройки = ирОбщий.ПолучитьФормуЛкс("Обработка.ирНастройкаТехножурнала.Форма");
ФормаНастройки.Открыть();
ФормаНастройки.НаСервере = Не ирКэш.ЛиФайловаяБазаЛкс();
ФормаНастройки.ПриИзмененииПравилаПолученияФайлаНастройки();
ФормаНастройки.ПереключитьТрассировкуЗапросов(Истина);
КонецПроцедуры
Процедура ОтключитьГлобальныеОбработчикиОжиданияЛкс() Экспорт
Если ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
Возврат;
КонецЕсли;
Если Не ПроверитьЧтоСеансТолстогоКлиентаЛкс() Тогда
Возврат;
КонецЕсли;
ОткрытьФормуЛкс("Обработка.ирПлатформа.Форма.ГлобальныеОбработчикиОжидания");
КонецПроцедуры
Функция ОткрытьФормуЛкс(Знач ПолноеИмяФормы, Знач Параметры = Неопределено, Знач Владелец = Неопределено, Знач Уникальность = Неопределено, Знач Окно = Неопределено) Экспорт
#Если ТонкийКлиент Или ВебКлиент Тогда
Параметры = Новый Структура("ИмяФормыДляОткрытия", ПолноеИмяФормы);
Форма = ПолучитьФорму("Обработка.ирПортативный.Форма.ЗапускСеансаУправляемая", Параметры, Владелец, Уникальность, Окно);
#Иначе
Форма = ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
#КонецЕсли
Если Форма <> Неопределено Тогда
Форма.Открыть();
КонецЕсли;
Возврат Форма;
КонецФункции
#КонецЕсли
// Получает первый фрагмент, отделяемый разделителем от строки.
// Написана для оптимизации по скорости.
//
// Параметры:
// пСтрока - Строка - которую разбиваем;
// *пРазделитель - Строка, "." - символ-разделитель;
// *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина.
//
// Возвращаемое значение:
// - Строка - первый фрагмент строки;
// Неопределено - в строке не обнаружен разделитель.
//
Функция ПервыйФрагментЛкс(пСтрока, Разделитель = ".", ЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина) Экспорт
Если Ложь
//Или ирКэш.РежимОтладкиЛкс() // Закомментировано для ускорения
Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Позиция = Найти(пСтрока, Разделитель);
Если Позиция > 0 Тогда
Возврат Лев(пСтрока, Позиция - 1);
Иначе
Если ЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда
Возврат пСтрока;
Иначе
Возврат "";
КонецЕсли;
КонецЕсли;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Позиция = Найти(пСтрока, Разделитель); Если Позиция > 0 Тогда Возврат Лев(пСтрока, Позиция - 1); Иначе Если ЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда Возврат пСтрока; Иначе Возврат ""; КонецЕсли; КонецЕсли;
КонецЕсли;
КонецФункции
Функция СтрКончаетсяНаЛкс(ПерваяСтрока, ВтораяСтрока, СУчетомРегистра = Ложь) Экспорт
КонецСтроки = Прав(ПерваяСтрока, СтрДлина(ВтораяСтрока));
Если СУчетомРегистра Тогда
Результат = КонецСтроки = ВтораяСтрока;
Иначе
Результат = НРег(КонецСтроки) = НРег(ВтораяСтрока);
КонецЕсли;
Возврат Результат;
КонецФункции
// Получает последний фрагмент, отделяемый разделителем от строки.
// Для для длинных строк медленно! Для них рекомендуется использовать регулярные выражения.
//
// Параметры:
// пСтрока - Строка - в которой ищем;
// *пМаркер - Строка, "." - отсекающий маркер;
// *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина - разрешение использования границ строки
// в случае, если маркер не найден.
//
// Возвращаемое значение:
// Неопределено - маркер не найден;
// - Число - позиция маркера.
//
Функция ПоследнийФрагментЛкс(пСтрока, пМаркер = ".", пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина) Экспорт
Если Ложь
//Или ирКэш.РежимОтладкиЛкс() // Закомментировано для ускорения
Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Подстрока = пСтрока;
МаркерНайден = Ложь;
Пока пМаркер <> "" Цикл
Позиция = Найти(Подстрока, пМаркер);
Если Позиция = 0 Тогда
Прервать;
КонецЕсли;
МаркерНайден = Истина;
Подстрока = Сред(Подстрока, Позиция + СтрДлина(пМаркер));
КонецЦикла;
Если Истина
И Не МаркерНайден
И пЛиИспользоватьГраницуЕслиМаркерНеНайден
Тогда
Возврат пСтрока;
ИначеЕсли МаркерНайден Тогда
Возврат Подстрока;
Иначе
Возврат "";
КонецЕсли;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Подстрока = пСтрока; МаркерНайден = Ложь; Пока пМаркер <> "" Цикл Позиция = Найти(Подстрока, пМаркер); Если Позиция = 0 Тогда Прервать; КонецЕсли; МаркерНайден = Истина; Подстрока = Сред(Подстрока, Позиция + СтрДлина(пМаркер)); КонецЦикла; Если Истина И Не МаркерНайден И пЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда Возврат пСтрока; ИначеЕсли МаркерНайден Тогда Возврат Подстрока; Иначе Возврат ""; КонецЕсли;
КонецЕсли;
КонецФункции
Функция ИменительныйПадежПериодаЛкс(Знач ЛюбойПадеж) Экспорт
ЛюбойПадеж = Нрег(ЛюбойПадеж);
Если ЛюбойПадеж = "года" Тогда
Результат = "год";
ИначеЕсли ЛюбойПадеж = "полугодия" Тогда
Результат = "полугодие";
ИначеЕсли ЛюбойПадеж = "квартала" Тогда
Результат = "квартал";
ИначеЕсли ЛюбойПадеж = "месяца" Тогда
Результат = "месяц";
ИначеЕсли ЛюбойПадеж = "декады" Тогда
Результат = "декада";
ИначеЕсли ЛюбойПадеж = "недели" Тогда
Результат = "неделя";
ИначеЕсли ЛюбойПадеж = "дня" Тогда
Результат = "день";
ИначеЕсли ЛюбойПадеж = "часа" Тогда
Результат = "час";
ИначеЕсли ЛюбойПадеж = "минуты" Тогда
Результат = "минута";
ИначеЕсли ЛюбойПадеж = "секунды" Тогда
Результат = "секунда";
Иначе
ВызватьИсключение "Период не опознан """ + ЛюбойПадеж + """";
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ДобавитьЕслиНужноПравыйСлешВФайловыйПутьЛкс(КаталогИсполняемыхФайлов) Экспорт
Если Прав(КаталогИсполняемыхФайлов, 1) <> "\" Тогда
КаталогИсполняемыхФайлов = КаталогИсполняемыхФайлов + "\";
КонецЕсли;
КонецПроцедуры
// Проверяет правильность заполнения реквизитов объекта
// Параметры:
// Объект -
// ОбязательныеПоля - Строка(0,П), Массив
// Отказ - Булево
// Заголовок - Строка(0,П)
//
// Возвращаемое значение: Булево - истина, если проверка пройдена успешно
Функция ПроверитьЗаполнениеРеквизитовОбъектаЛкс(Знач Объект, Знач ОбязательныеПоля = "", Отказ = Ложь) Экспорт
Результат = Истина;
Попытка
ОбменДаннымиЗагрузка = Объект.ОбменДанными.Загрузка;
Исключение
ОбменДаннымиЗагрузка = Ложь;
КонецПопытки;
Если ОбменДаннымиЗагрузка Тогда
Возврат Результат;
КонецЕсли;
Если ТипЗнч(ОбязательныеПоля) = Тип("Строка") Тогда
МассивПолей = СтрРазделитьЛкс(ОбязательныеПоля, ",", Истина);
ОбязательныеПоля = Новый Соответствие;
Для каждого Значение Из МассивПолей Цикл
ОбязательныеПоля[Значение] = "";
КонецЦикла;
//ОбязательныеПоля = Новый Структура(ОбязательныеПоля);
КонецЕсли;
РеквизитыМД = Объект.Метаданные().Реквизиты;
Для каждого КлючЗначение Из ОбязательныеПоля Цикл
ПутьКДанным = КлючЗначение.Ключ;
Значение = Вычислить("Объект." + ПутьКДанным);
Если Не ЗначениеЗаполнено(Значение) Тогда // надо ругаться
Если Не ЗначениеЗаполнено(КлючЗначение.Значение) Тогда
Фрагменты = СтрРазделитьЛкс(ПутьКДанным);
ИндексСтрокиТЧ = Неопределено;
Если Фрагменты.Количество() > 1 Тогда
ИндексСтрокиТЧ = СтрокаМеждуМаркерамиЛкс(Фрагменты[0], "[", "]", Ложь);
Если ИндексСтрокиТЧ <> Неопределено Тогда
ИндексСтрокиТЧ = Число(ИндексСтрокиТЧ);
//ИмяТЧ = ПолучитьПервыйФрагментИис(Фрагменты[0], "[");
КонецЕсли;
КонецЕсли;
//ПредставлениеРеквизита = РеквизитыМД[КлючЗначение.Ключ].Представление();
ПредставлениеРеквизита = СокрЛП(Фрагменты[Фрагменты.ВГраница()]);
СтрокаСообщения = "Не заполнено значение реквизита """ + ПредставлениеРеквизита + """";
Если ИндексСтрокиТЧ <> Неопределено Тогда
СтрокаСообщения = СтрокаСообщения + " в строке №" + Формат(ИндексСтрокиТЧ + 1, "ЧГ=") + " таблицы """ + СокрЛП(ирОбщий.ПервыйФрагментЛкс(Фрагменты[0], "[")) + """";
КонецЕсли;
Иначе
СтрокаСообщения = КлючЗначение.Значение;
КонецЕсли;
Отказ = Истина;
СообщитьЛкс(СтрокаСообщения, СтатусСообщения.Внимание);
Результат = Ложь;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ЛиОписанияТиповПересекаютсяЛкс(Знач ОписаниеТипов1, Знач ОписаниеТипов2, Знач ИсключаяПримитивныеТипы = Ложь) Экспорт
Если Ложь
Или ТипЗнч(ОписаниеТипов1) = Тип("КолонкаТаблицыЗначений")
Или ТипЗнч(ОписаниеТипов1) = Тип("КолонкаДереваЗначений")
Или ТипЗнч(ОписаниеТипов1) = Тип("КолонкаРезультатаЗапроса")
Или ТипЗнч(ОписаниеТипов1) = Тип("ДоступноеПолеКомпоновкиДанных")
Или ТипЗнч(ОписаниеТипов1) = Тип("ДоступноеПолеОтбораКомпоновкиДанных")
Тогда
ОписаниеТипов1 = ОписаниеТипов1.ТипЗначения;
КонецЕсли;
Если Ложь
Или ТипЗнч(ОписаниеТипов2) = Тип("КолонкаТаблицыЗначений")
Или ТипЗнч(ОписаниеТипов2) = Тип("КолонкаДереваЗначений")
Или ТипЗнч(ОписаниеТипов2) = Тип("КолонкаРезультатаЗапроса")
Или ТипЗнч(ОписаниеТипов2) = Тип("ДоступноеПолеКомпоновкиДанных")
Или ТипЗнч(ОписаниеТипов2) = Тип("ДоступноеПолеОтбораКомпоновкиДанных")
Тогда
ОписаниеТипов2 = ОписаниеТипов2.ТипЗначения;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОписаниеТипов1 = Новый ОписаниеТипов;
ОписаниеТипов2 = Новый ОписаниеТипов;
#КонецЕсли
Результат = Ложь;
Типы1 = ОписаниеТипов1.Типы();
Если Истина
И Типы1.Количество() = 0
И ОписаниеТипов2.Типы().Количество() = 0
Тогда
Результат = Истина;
Иначе
Для Каждого Тип Из Типы1 Цикл
Если Истина
И ИсключаяПримитивныеТипы
И (Ложь
Или Тип = Тип("Булево")
Или Тип = Тип("Строка")
Или Тип = Тип("Число")
Или Тип = Тип("Дата"))
Тогда
Продолжить;
КонецЕсли;
Если ОписаниеТипов2.СодержитТип(Тип) Тогда
Результат = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
//
// Параметры:
// ВариантКвалификаторов - Число - 0 - пересекать, 1 - брать от ОписаниеТипов1, 2 - брать от ОписаниеТипов2
Функция ПересечьОписанияТиповЛкс(ОписаниеТипов1, ОписаниеТипов2, ИсключаяПримитивныеТипы = Ложь, ВариантКвалификаторов = 0) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов1 = Новый ОписаниеТипов;
ОписаниеТипов2 = Новый ОписаниеТипов;
#КонецЕсли
Если ВариантКвалификаторов = 1 Тогда
КвалификаторыЧисла = ОписаниеТипов1.КвалификаторыЧисла;
КвалификаторыСтроки = ОписаниеТипов1.КвалификаторыСтроки;
КвалификаторыДаты = ОписаниеТипов1.КвалификаторыДаты;
Иначе
КвалификаторыЧисла = ОписаниеТипов2.КвалификаторыЧисла;
КвалификаторыСтроки = ОписаниеТипов2.КвалификаторыСтроки;
КвалификаторыДаты = ОписаниеТипов2.КвалификаторыДаты;
Если ВариантКвалификаторов = 0 Тогда
Если КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная И ОписаниеТипов1.КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная Тогда
ДопустимаяДлинаНовая = ДопустимаяДлина.Переменная;
Иначе
ДопустимаяДлинаНовая = ДопустимаяДлина.Фиксированная;
КонецЕсли;
КвалификаторыСтроки = Новый КвалификаторыСтроки(
Мин(КвалификаторыСтроки.Длина, ОписаниеТипов1.КвалификаторыСтроки.Длина),
ДопустимаяДлинаНовая);
КвалификаторыЧисла = Новый КвалификаторыЧисла(
Мин(КвалификаторыЧисла.Разрядность, ОписаниеТипов1.КвалификаторыЧисла.Разрядность),
Мин(КвалификаторыЧисла.РазрядностьДробнойЧасти, ОписаниеТипов1.КвалификаторыЧисла.РазрядностьДробнойЧасти),
?(КвалификаторыЧисла.ДопустимыйЗнак = ДопустимыйЗнак.Неотрицательный, КвалификаторыЧисла.ДопустимыйЗнак, ОписаниеТипов1.КвалификаторыЧисла.ДопустимыйЗнак));
Если КвалификаторыДаты.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда
ЧастиДатыНовая = ОписаниеТипов1.КвалификаторыДаты.ЧастиДаты;
ИначеЕсли КвалификаторыДаты.ЧастиДаты <> ОписаниеТипов1.КвалификаторыДаты.ЧастиДаты И ОписаниеТипов1.КвалификаторыДаты.ЧастиДаты <> ЧастиДаты.ДатаВремя Тогда
ЧастиДатыНовая = ЧастиДаты.ДатаВремя;
Иначе
ЧастиДатыНовая = КвалификаторыДаты.ЧастиДаты;
КонецЕсли;
КвалификаторыДаты = Новый КвалификаторыДаты(ЧастиДатыНовая);
КонецЕсли;
КонецЕсли;
МассивОбщихТипов = Новый Массив;
Если ОписаниеТипов1.Типы().Количество() = 0 Тогда
МассивОбщихТипов = ОписаниеТипов2.Типы();
ИначеЕсли ОписаниеТипов2.Типы().Количество() = 0 Тогда
МассивОбщихТипов = ОписаниеТипов1.Типы();
Иначе
Для Каждого Тип Из ОписаниеТипов1.Типы() Цикл
Если Истина
И ИсключаяПримитивныеТипы
И (Ложь
Или Тип = Тип("Булево")
Или Тип = Тип("Строка")
Или Тип = Тип("Число")
Или Тип = Тип("Дата"))
Тогда
Продолжить;
КонецЕсли;
Если ОписаниеТипов2.СодержитТип(Тип) Тогда
МассивОбщихТипов.Добавить(Тип);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Результат = Новый ОписаниеТипов(МассивОбщихТипов,,, КвалификаторыЧисла, КвалификаторыСтроки, КвалификаторыДаты);
Возврат Результат;
КонецФункции
Функция ОбъединитьОписанияТиповЛкс(ОписаниеТипов1, ОписаниеТипов2) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов1 = Новый ОписаниеТипов;
ОписаниеТипов2 = Новый ОписаниеТипов;
#КонецЕсли
КвалификаторыСтроки = ОписаниеТипов2.КвалификаторыСтроки;
Если КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная Или ОписаниеТипов1.КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная Тогда
ДопустимаяДлинаНовая = ДопустимаяДлина.Переменная;
Иначе
ДопустимаяДлинаНовая = ДопустимаяДлина.Фиксированная;
КонецЕсли;
КвалификаторыСтроки = Новый КвалификаторыСтроки(
Макс(КвалификаторыСтроки.Длина, ОписаниеТипов1.КвалификаторыСтроки.Длина),
ДопустимаяДлинаНовая);
КвалификаторыЧисла = ОписаниеТипов2.КвалификаторыЧисла;
КвалификаторыЧисла = Новый КвалификаторыЧисла(
Макс(КвалификаторыЧисла.Разрядность, ОписаниеТипов1.КвалификаторыЧисла.Разрядность),
Макс(КвалификаторыЧисла.РазрядностьДробнойЧасти, ОписаниеТипов1.КвалификаторыЧисла.РазрядностьДробнойЧасти),
?(КвалификаторыЧисла.ДопустимыйЗнак = ДопустимыйЗнак.Любой, КвалификаторыЧисла.ДопустимыйЗнак, ОписаниеТипов1.КвалификаторыЧисла.ДопустимыйЗнак));
КвалификаторыДаты = ОписаниеТипов2.КвалификаторыДаты;
Если КвалификаторыДаты.ЧастиДаты = ОписаниеТипов1.КвалификаторыДаты.ЧастиДаты Тогда
ЧастиДатыНовая = КвалификаторыДаты.ЧастиДаты;
Иначе
ЧастиДатыНовая = ЧастиДаты.ДатаВремя;
КонецЕсли;
КвалификаторыДаты = Новый КвалификаторыДаты(ЧастиДатыНовая);
МассивОбщихТипов = ОписаниеТипов1.Типы();
Для Каждого Тип Из ОписаниеТипов2.Типы() Цикл
МассивОбщихТипов.Добавить(Тип);
КонецЦикла;
Результат = Новый ОписаниеТипов(МассивОбщихТипов,,, КвалификаторыЧисла, КвалификаторыСтроки, КвалификаторыДаты);
Возврат Результат;
КонецФункции
// Проверяет, отвечает ли строка правилам формирования имен переменных встроенного языка.
//
// Параметры:
// Строка - Строка.
//
// Возвращаемое значение:
// Булево.
//
Функция ЛиИмяПеременнойЛкс(Строка) Экспорт
Если ПустаяСтрока(Строка) Тогда
Возврат Ложь;
КонецЕсли;
Пустышка = Новый Структура;
Попытка
Пустышка.Вставить(Строка);
Возврат Истина;
Исключение
Возврат Ложь;
КонецПопытки;
КонецФункции
// Пространство имен текущей конфигурации.
// Возвращаемое значение:
//
Функция ПространствоИменТекущейКонфигурацииЛкс() Экспорт
Возврат "http://v8.1c.ru/8.1/data/enterprise/current-config";
КонецФункции
Функция ЗначениеСвойстваПолучитьБезопасноЛкс(ЭлементФормы, Знач ИмяСвойстваЗаголовка) Экспорт
СтруктураЗначений = Новый Структура(ИмяСвойстваЗаголовка);
ЗаполнитьЗначенияСвойств(СтруктураЗначений, ЭлементФормы);
ЗаголовокЭлемента = СтруктураЗначений[ИмяСвойстваЗаголовка];
Возврат ЗаголовокЭлемента;
КонецФункции
// Функция - Восстановить текущую строку таблицы формы лкс
//
// Параметры:
// ТабличноеПоле - ТабличноеПоле, ТаблицаФормы -
// КлючТекущейСтроки - Структура -
// ДанныеТаблицы - -
//
// Возвращаемое значение:
// - Булево - успешность установки текущей строки
//
Функция ТабличноеПолеВосстановитьТекущуюСтрокуЛкс(ТабличноеПоле, Знач КлючТекущейСтроки, Знач ДанныеТаблицы = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
Если КлючТекущейСтроки <> Неопределено Тогда
Если ДанныеТаблицы = Неопределено Тогда
ДанныеТаблицы = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
КонецЕсли;
Строка = СтрокаТабличнойКоллекцииПоКлючуЛкс(ДанныеТаблицы, КлючТекущейСтроки);
Если Строка <> Неопределено Тогда
Попытка
ИдентификаторСтроки = Строка.ПолучитьИдентификатор();
Исключение
ИдентификаторСтроки = Строка;
КонецПопытки;
ТабличноеПоле.ТекущаяСтрока = ИдентификаторСтроки;
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ТабличноеПолеВосстановитьВыделенныеСтрокиЛкс(ТабличноеПоле, Знач КлючиВыделенныхСтрок, Знач ДанныеТаблицы = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
Если КлючиВыделенныхСтрок.Количество() > 0 Тогда
ТабличноеПоле.ВыделенныеСтроки.Очистить();
КонецЕсли;
Для Каждого КлючВыделеннойСтроки Из КлючиВыделенныхСтрок Цикл
Если ДанныеТаблицы = Неопределено Тогда
ДанныеТаблицы = ТабличноеПоле.Значение;
КонецЕсли;
Строка = СтрокаТабличнойКоллекцииПоКлючуЛкс(ДанныеТаблицы, КлючВыделеннойСтроки);
Если Строка <> Неопределено Тогда
Попытка
ИдентификаторСтроки = Строка.ПолучитьИдентификатор();
Исключение
ИдентификаторСтроки = Строка;
КонецПопытки;
ТабличноеПоле.ВыделенныеСтроки.Добавить(ИдентификаторСтроки);
КонецЕсли;
КонецЦикла;
КонецФункции
Функция ТабличноеПолеВосстановитьСостояниеСтрокЛкс(Знач ТабличноеПоле, Знач СтруктураСостояния, ВременноОтключитьОтображение = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
СтруктураСостояния = Новый Структура;
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
Если ВременноОтключитьОтображение Тогда
// Предотвращаем двойную (синхронную и затем асинхронную) перерисовку видимых строк табличного поля при установке текущих колонки и строки.
// Такое происходит например в обработчике ПриАктивацииСтраницы в ирЗагрузкаТабличныхДанных. В остальных случаях пользы от этого вероятно нет.
ОбработчикПриВыводеСтроки = ТабличноеПолеОтключитьОтображениеЛкс(ТабличноеПоле);
КонецЕсли;
Если ЗначениеЗаполнено(СтруктураСостояния.ТекущаяКолонка) Тогда
ТекущаяКолонка = ТабличноеПоле.Колонки.Найти(СтруктураСостояния.ТекущаяКолонка);
Если ТекущаяКолонка <> Неопределено И ТекущаяКолонка.Видимость Тогда
ТабличноеПоле.ТекущаяКолонка = ТекущаяКолонка;
КонецЕсли;
КонецЕсли;
ТекущаяСтрокаУстановлена = ТабличноеПолеВосстановитьТекущуюСтрокуЛкс(ТабличноеПоле, СтруктураСостояния.ТекущаяСтрока);
ТабличноеПолеВосстановитьВыделенныеСтрокиЛкс(ТабличноеПоле, СтруктураСостояния.ВыделенныеСтроки);
Если ВременноОтключитьОтображение Тогда
ТабличноеПолеВключитьОтображениеЛкс(ТабличноеПоле, ОбработчикПриВыводеСтроки);
КонецЕсли;
Возврат ТекущаяСтрокаУстановлена;
КонецФункции
Процедура ТабличноеПолеВключитьОтображениеЛкс(Знач ТабличноеПоле, Знач ОбработчикПриВыводеСтроки) Экспорт
ТабличноеПоле.УстановитьДействие("ПриВыводеСтроки", ОбработчикПриВыводеСтроки);
ТабличноеПоле.Видимость = Истина;
КонецПроцедуры
Функция ТабличноеПолеОтключитьОтображениеЛкс(Знач ТабличноеПоле)
ОбработчикПриВыводеСтроки = ТабличноеПоле.ПолучитьДействие("ПриВыводеСтроки");
ТабличноеПоле.УстановитьДействие("ПриВыводеСтроки", Неопределено);
ТабличноеПоле.Видимость = Ложь;
Возврат ОбработчикПриВыводеСтроки;
КонецФункции
Функция СтрокаТабличнойКоллекцииПоКлючуЛкс(Знач ТабличнаяКоллекция, Знач КлючТекущейСтроки) Экспорт
Если ТипЗнч(КлючТекущейСтроки) = Тип("Структура") Тогда
#Если Сервер И Не Сервер Тогда
КлючТекущейСтроки = Новый Структура;
#КонецЕсли
Если ТипЗнч(ТабличнаяКоллекция) = Тип("ДеревоЗначений") Тогда
НайденныеСтроки = ТабличнаяКоллекция.Строки.НайтиСтроки(КлючТекущейСтроки, Истина);
Иначе
Если Истина
И КлючТекущейСтроки.Количество() = 1
И КлючТекущейСтроки.Свойство("НомерСтроки")
И ТабличнаяКоллекция.Колонки.Найти("НомерСтроки") = Неопределено
Тогда
НайденныеСтроки = Новый Массив;
Если ТабличнаяКоллекция.Количество() >= КлючТекущейСтроки.НомерСтроки Тогда
НайденныеСтроки.Добавить(ТабличнаяКоллекция[КлючТекущейСтроки.НомерСтроки - 1]);
КонецЕсли;
Иначе
НайденныеСтроки = ТабличнаяКоллекция.НайтиСтроки(КлючТекущейСтроки);
КонецЕсли;
КонецЕсли;
Если НайденныеСтроки.Количество() > 0 Тогда
Строка = НайденныеСтроки[0];
КонецЕсли;
Иначе
Если ТабличнаяКоллекция.Количество() > КлючТекущейСтроки Тогда
Строка = ТабличнаяКоллекция[КлючТекущейСтроки];
КонецЕсли;
КонецЕсли;
Возврат Строка;
КонецФункции
// Параметры:
// ТаблицаФормы - ТаблицаФормы, ТабличноеПоле -
// ИменаКлючевыхКолонок - Строка, 0[число] - если 0, то используется логический номер строки
// СтрокаТаблицы - -
//
// Результат:
// Структура
//
Функция ТабличноеПолеКлючСтрокиЛкс(ТаблицаФормы, ИменаКлючевыхКолонок = "Ссылка", Знач СтрокаТаблицы = Неопределено) Экспорт
Если СтрокаТаблицы = Неопределено Тогда
СтрокаТаблицы = ТаблицаФормы.ТекущиеДанные;
КонецЕсли;
Если СтрокаТаблицы <> Неопределено Тогда
Если ИменаКлючевыхКолонок = 0 Тогда
КлючТекущейСтроки = Новый Структура("НомерСтроки");
КлючТекущейСтроки.НомерСтроки = СтрокаТаблицы.Владелец().Индекс(СтрокаТаблицы) + 1;
Иначе
КлючТекущейСтроки = Новый Структура(ИменаКлючевыхКолонок);
ЗаполнитьЗначенияСвойств(КлючТекущейСтроки, СтрокаТаблицы, ИменаКлючевыхКолонок);
КонецЕсли;
КонецЕсли;
Возврат КлючТекущейСтроки;
КонецФункции
// Функция - Табличное поле ключи строк лкс
//
// Параметры:
// ТаблицаФормы - -
// ИменаКлючевыхКолонок - Строка, 0[число] - если 0, то используется логический номер строки
// СтрокиТаблицы - -
//
// Возвращаемое значение:
// -
//
Функция ТабличноеПолеКлючиСтрокЛкс(ТаблицаФормы, ИменаКлючевыхКолонок = "Ссылка", Знач СтрокиТаблицы = Неопределено) Экспорт
Если СтрокиТаблицы = Неопределено Тогда
СтрокиТаблицы = ТаблицаФормы.ВыделенныеСтроки;
КонецЕсли;
Результат = Новый Массив;
Для Каждого СтрокаТаблицы Из СтрокиТаблицы Цикл
Если СтрокаТаблицы = Неопределено Тогда
// Случается в дереве формы ирРедакторИзмененийНаУзлах
Продолжить;
КонецЕсли;
КлючТекущейСтроки = ТабличноеПолеКлючСтрокиЛкс(ТаблицаФормы, ИменаКлючевыхКолонок, СтрокаТаблицы);
Результат.Добавить(КлючТекущейСтроки);
КонецЦикла;
Возврат Результат;
КонецФункции
// Функция - Табличное поле состояние строк лкс
//
// Параметры:
// ТабличноеПоле - -
// ИменаКлючевыхКолонок - Строка, 0[число] - если 0, то используется логический номер строки
//
// Возвращаемое значение:
// -
//
Функция ТабличноеПолеСостояниеСтрокЛкс(Знач ТабличноеПоле, Знач ИменаКлючевыхКолонок = 0) Экспорт
СтруктураСостояния = Новый Структура("ТекущаяКолонка, ТекущаяСтрока, ВыделенныеСтроки");
СтруктураСостояния.ТекущаяСтрока = ТабличноеПолеКлючСтрокиЛкс(ТабличноеПоле, ИменаКлючевыхКолонок);
СтруктураСостояния.ВыделенныеСтроки = ТабличноеПолеКлючиСтрокЛкс(ТабличноеПоле, ИменаКлючевыхКолонок);
Если ТабличноеПоле.ТекущаяКолонка <> Неопределено Тогда
СтруктураСостояния.ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка.Имя;
КонецЕсли;
Возврат СтруктураСостояния;
КонецФункции
Функция ТабличноеПолеСтрокаПоискаЛкс(Знач ЭтаФорма, Знач ТабличноеПоле) Экспорт
Префикс = ирОбщий.ПрефиксРеквизитовКомпоновкиТабличногоПоляЛкс(ЭтаФорма, ТабличноеПоле);
Попытка
СтрокаПоиска = ЭтаФорма[Префикс + "СтрокаПоиска"];
Исключение
СтрокаПоиска = "";
КонецПопытки;
Возврат СтрокаПоиска;
КонецФункции
Функция ИмяФормыИзФормыЛкс(ЭтаФорма) Экспорт
Если ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма") Тогда
Результат = ЭтаФорма.ИмяФормы;
Иначе
Результат = СлужебныеДанныеФормыЛкс(ЭтаФорма).ИмяФормы;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СлужебныеДанныеФормыЛкс(ЭтаФорма) Экспорт
Результат = Неопределено;
#Если Клиент Тогда
Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда
Результат = ЭтаФорма.Панель.Страницы[0].Значение;
Если Результат = Неопределено Тогда
Результат = Новый Структура();
ЭтаФорма.Панель.Страницы[0].Значение = Результат;
КонецЕсли;
Иначе
#КонецЕсли
Попытка
Результат = ЭтаФорма.мСлужебныеДанные;
Исключение
КонецПопытки;
#Если Клиент Тогда
КонецЕсли;
#КонецЕсли
Возврат Результат;
КонецФункции
Функция ПроверитьПлатформаНеWindowsЛкс(выхОтказ = Неопределено, Знач НазваниеФункции = "", ДляРегВыражений = Ложь) Экспорт
Если Ложь
Или (Истина
И Не ДляРегВыражений
И Не ирКэш.ЛиПлатформаWindowsЛкс()
Или (Истина
И ДляРегВыражений
И Не ирКэш.ДоступныРегВыраженияЛкс()))
Тогда
выхОтказ = Истина;
Если ЗначениеЗаполнено(НазваниеФункции) Тогда
НазваниеФункции = ирОбщий.СтрокаВВыражениеВстроенногоЯзыкаЛкс(НазваниеФункции);
КонецЕсли;
СообщитьЛкс(СтрШаблонИменЛкс("Функция %1 поддерживается только в ОС Windows",, НазваниеФункции), СтатусСообщения.Внимание,, Истина);
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Процедура ОчиститьПодчиненныеЭлементыФормыЛкс(Знач Родитель, КоличествоНеудаляемых = 1) Экспорт
Если Ложь
#Если Клиент Тогда
Или ТипЗнч(Родитель) = Тип("Панель")
#КонецЕсли
Тогда
Родитель.Страницы.Очистить();
ИначеЕсли Ложь
#Если Клиент Тогда
Или ТипЗнч(Родитель) = Тип("ТабличноеПоле")
#КонецЕсли
Тогда
Родитель.Колонки.Очистить();
Иначе
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(Родитель);
ПодчиненныеЭлементы = Родитель.ПодчиненныеЭлементы;
НачальноеКоличество = ПодчиненныеЭлементы.Количество();
Для Счетчик = 1 По НачальноеКоличество Цикл
ПодчиненныйЭлемент = ПодчиненныеЭлементы[НачальноеКоличество - Счетчик];
Если ПодчиненныеЭлементы.Количество() > КоличествоНеудаляемых Тогда
ЭтаФорма.Элементы.Удалить(ПодчиненныйЭлемент);
Иначе
// Статистически добавленные нельзя удалять
ПодчиненныйЭлемент.Видимость = Ложь;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура УстановитьГотовностьДанныхСтраницыЛкс(ЭтаФорма, Страница, Готовность = Истина) Экспорт
НеготовыеСтраницы = СлужебныеДанныеФормыЛкс(ЭтаФорма).НеготовыеСтраницы;
#Если Сервер И Не Сервер Тогда
НеготовыеСтраницы = Новый СписокЗначений;
#КонецЕсли
ЭлементСписка = НеготовыеСтраницы.НайтиПоЗначению(Страница.Имя);
Если ЭлементСписка <> Неопределено И Готовность Тогда
НеготовыеСтраницы.Удалить(ЭлементСписка);
ИначеЕсли ЭлементСписка = Неопределено И Не Готовность Тогда
НеготовыеСтраницы.Добавить(Страница.Имя);
КонецЕсли;
КонецПроцедуры
Функция ПолучитьГотовностьДанныхСтраницыЛкс(ЭтаФорма, Страница) Экспорт
НеготовыеСтраницы = СлужебныеДанныеФормыЛкс(ЭтаФорма).НеготовыеСтраницы;
#Если Сервер И Не Сервер Тогда
НеготовыеСтраницы = Новый СписокЗначений;
#КонецЕсли
ЭлементСписка = НеготовыеСтраницы.НайтиПоЗначению(Страница.Имя);
Результат = ЭлементСписка = Неопределено;
Возврат Результат;
КонецФункции
Процедура СоздатьКолонкиТабличногоПоляЛкс(ТабличноеПоле) Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
ОчиститьПодчиненныеЭлементыФормыЛкс(ТабличноеПоле, 0);
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле);
ПутьКДанным = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТабличноеПоле);
РеквизитыТаблицы = ЭтаФорма.ПолучитьРеквизиты(ПутьКДанным);
Для Каждого РеквизитТаблицы Из РеквизитыТаблицы Цикл
ПолеФормы = ЭтаФорма.Элементы.Добавить(ТабличноеПоле.Имя + РеквизитТаблицы.Имя, Тип("ПолеФормы"), ТабличноеПоле);
ПолеФормы.Вид = ВидПоляФормы.ПолеВвода;
Попытка
ПолеФормы.ПутьКДанным = ПутьКДанным + "." + РеквизитТаблицы.Имя;
Исключение
// При РеквизитТаблицы.Имя = "КоличествоСтрок"
КонецПопытки;
КонецЦикла;
Иначе
ТабличноеПоле.СоздатьКолонки();
КонецЕсли;
КонецПроцедуры
Функция ТипЗначенияЭлементаФормыЛкс(ЭлементФормы, ВызыватьИсключение = Истина) Экспорт
Попытка
ТипЗначения = ЭлементФормы.ТипЗначения;
Исключение
// Упр
ЭтаФорма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(ЭлементФормы);
Попытка
ТипЗначения = ЭтаФорма.мСлужебныеДанные.ТипыЗначений[ЭлементФормы.Имя];
Исключение
Если ВызыватьИсключение Тогда
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
КонецПопытки;
Возврат ТипЗначения;
КонецФункции
// Чтобы функция всегда возвращала правильное значение в управляемой форме, должен быть
// выполнен общий обработчик формы ПриСозданииНаСервере.
//
// Параметры:
// Элемент - -
// выхПутьКДанным - -
// ЭтаФорма - -
// ВзятьОтобранное - Булево, Неопределено - для компонуемого табличного поля взять отобранное, при "Неопределено" структура отбора просмотра игнорируется
//
// Возвращаемое значение:
// -
//
Функция ДанныеЭлементаФормыЛкс(Знач Элемент, выхПутьКДанным = "", ЭтаФорма = Неопределено, ВзятьОтобранное = Ложь) Экспорт
Если Истина
И ЭтаФорма <> Неопределено
И ТипЗнч(Элемент) = Тип("ТабличноеПоле")
И ВзятьОтобранное <> Неопределено
Тогда
КомпоновкаТП = КомпоновкаТабличногоПоляЛкс(ЭтаФорма, Элемент);
Если КомпоновкаТП <> Неопределено Тогда
Если ВзятьОтобранное И КомпоновкаТП.ИспользоватьОтбор Тогда
Возврат КомпоновкаТП.ТаблицаОтобранное;
Иначе
Возврат КомпоновкаТП.ТаблицаЗначений;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Попытка
// Обычная форма
Данные = Элемент.Значение;
Попытка
выхПутьКДанным = Элемент.Данные;
Исключение
// Колонка табличного поля
выхПутьКДанным = Неопределено;
КонецПопытки;
Возврат Данные;
Исключение
КонецПопытки;
Если Ложь
#Если Клиент Тогда
Или ТипЗнч(Элемент) = Тип("ПолеТабличногоДокумента")
#КонецЕсли
Тогда
Данные = Элемент;
Иначе
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(Элемент, Тип("УправляемаяФорма")); // Переменная ЭтаФорма используется в Вычислить ниже
выхПутьКДанным = ПутьКДаннымЭлементаУправляемойФормыЛкс(Элемент, , ЭтаФорма);
Если Не ЗначениеЗаполнено(выхПутьКДанным) Тогда
выхПутьКДанным = Элемент.Имя;
КонецЕсли;
Попытка
Данные = Вычислить("ЭтаФорма." + выхПутьКДанным);
Исключение
Данные = Неопределено;
КонецПопытки;
Если Данные = Неопределено Тогда
ЧастыеИменаОбъектов = Новый Массив;
ЧастыеИменаОбъектов.Добавить("Объект");
ЧастыеИменаОбъектов.Добавить("Запись");
ЧастыеИменаОбъектов.Добавить("Отчет");
ЧастыеИменаОбъектов.Добавить("Обработка");
ЧастыеИменаОбъектов.Добавить("Задача");
Для Каждого ИмяОбъекта Из ЧастыеИменаОбъектов Цикл
выхПутьКДанным = ИмяОбъекта + "." + Элемент.Имя;
Попытка
Данные = Вычислить("ЭтаФорма." + выхПутьКДанным);
Прервать;
Исключение
КонецПопытки;
КонецЦикла;
Если Данные = Неопределено Тогда
Для Счетчик = 1 По СтрДлина(Элемент.Имя) Цикл
выхПутьКДанным = Лев(Элемент.Имя, Счетчик) + "." + Сред(Элемент.Имя, Счетчик + 1);
Попытка
Данные = Вычислить("ЭтаФорма." + выхПутьКДанным);
Прервать;
Исключение
КонецПопытки;
КонецЦикла;
КонецЕсли;
Если Истина
И ТипЗнч(Элемент) = Тип("ТаблицаФормы")
И Данные <> Неопределено
И ТипЗнч(Данные) <> Тип("ДинамическийСписок")
И Элемент.ТекущаяСтрока <> Неопределено
И Данные.НайтиПоИдентификатору(Элемент.ТекущаяСтрока) = Неопределено
Тогда
//https://www.hostedredmine.com/issues/948431
Данные = Неопределено;
КонецЕсли;
Если Данные = Неопределено Тогда
выхПутьКДанным = Неопределено;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Данные;
КонецФункции
Функция КомпоновкаТабличногоПоляЛкс(Знач ЭтаФорма, Знач ТабличноеПоле) Экспорт
КомпоновкаТП = Новый Структура;
Компоновщик = Неопределено;
Префикс = ПрефиксРеквизитовКомпоновкиТабличногоПоляЛкс(ЭтаФорма, ТабличноеПоле, Компоновщик);
Если Префикс = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
КомпоновкаТП.Вставить("Компоновщик", Компоновщик);
КомпоновкаТП.Вставить("ТаблицаОтобранное", ЭтаФорма[Префикс + "Отобранное"]);
КомпоновкаТП.Вставить("ТаблицаЗначений", ЭтаФорма[Префикс]);
КомпоновкаТП.Вставить("ИспользоватьОтбор", ЭтаФорма[Префикс + "ИспользоватьОтбор"]);
КомпоновкаТП.Вставить("НадписьОтборПросмотра", ЭтаФорма.ЭлементыФормы[Префикс + "НадписьОтборПросмотра"]);
КомпоновкаТП.Вставить("ФлажокИспользоватьОтбор", ЭтаФорма.ЭлементыФормы[Префикс + "ИспользоватьОтбор"]);
Возврат КомпоновкаТП;
КонецФункции
Функция ПрефиксРеквизитовКомпоновкиТабличногоПоляЛкс(Знач ЭтаФорма, Знач ТабличноеПоле, выхКомпоновщик = Неопределено) Экспорт
Префикс = "" + ТабличноеПоле.Имя; // Тут может быть имитатор табличного поля
выхКомпоновщик = Неопределено;
Для Счетчик = 1 По 2 Цикл
Попытка
выхКомпоновщик = ЭтаФорма[Префикс + "Компоновщик"];
Исключение
КонецПопытки;
Если выхКомпоновщик = Неопределено И Найти(Префикс, "_") > 0 Тогда
Префикс = ПервыйФрагментЛкс(Префикс, "_"); // Редактор объекта БД
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
Если выхКомпоновщик = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Возврат Префикс;
КонецФункции
Функция ИдентификаторСтрокиТабличногоПоляЛкс(Знач НоваяСтрока) Экспорт
Если Ложь
Или ТипЗнч(НоваяСтрока) = Тип("ДанныеФормыЭлементКоллекции")
Или ТипЗнч(НоваяСтрока) = Тип("ДанныеФормыЭлементДерева")
Тогда
НоваяСтрока = НоваяСтрока.ПолучитьИдентификатор();
КонецЕсли;
Возврат НоваяСтрока;
КонецФункции
Функция НайтиЭлементКоллекцииЛкс(Знач Коллекция, Знач Свойство, Знач Значение, Знач ТипЭлемента = Неопределено) Экспорт
Структура = Новый Структура(Свойство);
Для каждого Элемент Из Коллекция Цикл
Если Истина
И ТипЭлемента <> Неопределено
И ТипЗнч(Элемент) <> ТипЭлемента
Тогда
Продолжить;
КонецЕсли;
ЗаполнитьЗначенияСвойств(Структура, Элемент, Свойство);
Если Структура[Свойство] = Значение Тогда
Результат = Элемент;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ЗначенияСвойстваКоллекцииЛкс(Знач Коллекция, Знач Свойство = "Имя", Знач ТипЭлемента = Неопределено) Экспорт
Результат = Новый Массив;
Для каждого Элемент Из Коллекция Цикл
Если Истина
И ТипЭлемента <> Неопределено
И ТипЗнч(Элемент) <> ТипЭлемента
Тогда
Продолжить;
КонецЕсли;
Результат.Добавить(Элемент[Свойство]);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция РежимОтладкиИзКоманднойСтрокиЛкс(Знач СтрокаЗапускаПроцесса) Экспорт
МаркерОтладки = "-debug";
ПозицияСтрокиТипаОтладчика = Найти(НРег(СтрокаЗапускаПроцесса), Нрег(МаркерОтладки));
Если ЗначениеЗаполнено(ПозицияСтрокиТипаОтладчика) Тогда
СтрокаОтладчика = СокрЛ(Сред(СтрокаЗапускаПроцесса, ПозицияСтрокиТипаОтладчика + СтрДлина(МаркерОтладки)));
Если Найти(НРег(СтрокаОтладчика), "-http") = 1 Тогда
РежимОтладки = "http";
Иначе
РежимОтладки = "tcp";
КонецЕсли;
Иначе
РежимОтладки = "нет";
КонецЕсли;
Возврат РежимОтладки;
КонецФункции
Функция СтрЗаменитьЛкс(Знач ГдеЗаменять, Знач ЧтоЗаменять, Знач НаЧтоЗаменять, ОставитьЧтоЗаменять = Ложь, ВыброситьИсключениеПриОтсутствии = Истина) Экспорт
Если ВыброситьИсключениеПриОтсутствии И Найти(ГдеЗаменять, ЧтоЗаменять) < 1 Тогда
ВызватьИсключение "Шаблонная строка """ + ЧтоЗаменять + """ не найдена в тексте";
КонецЕсли;
Если ОставитьЧтоЗаменять Тогда
НаЧтоЗаменять = ЧтоЗаменять + НаЧтоЗаменять;
КонецЕсли;
Результат = СтрЗаменить(ГдеЗаменять, ЧтоЗаменять, НаЧтоЗаменять);
Возврат Результат;
КонецФункции
Функция СтрНайтиЛкс(Знач Строка, Знач ПодстрокаПоиска, Знач НаправлениеПоискаСКонца = Ложь, Знач НачальнаяПозиция = Неопределено, Знач НомерВхождения = 1, Знач УчитыватьРегистр = Истина) Экспорт
Если Не УчитыватьРегистр Тогда
Строка = НРег(Строка);
ПодстрокаПоиска = НРег(ПодстрокаПоиска);
КонецЕсли;
Если ирКэш.НомерРежимаСовместимостиЛкс() >= 803006 Тогда
Возврат Вычислить("СтрНайти(Строка, ПодстрокаПоиска, ?(НаправлениеПоискаСКонца, НаправлениеПоиска.СКонца, НаправлениеПоиска.СНачала), НачальнаяПозиция, НомерВхождения)");
КонецЕсли;
ТекущаяПозиция = 0;
ЗнакНаправленияДвижения = 0;
ДлинаСтрПоиска = СтрДлина(ПодстрокаПоиска);
Попытка
Если НачальнаяПозиция <> Неопределено Тогда
НачальнаяПозиция = Число(НачальнаяПозиция);
Если НачальнаяПозиция <= 0 ИЛИ НачальнаяПозиция > СтрДлина(Строка) Тогда
ВызватьИсключение ("");
КонецЕсли;
КонецЕсли;
Исключение
ВызватьИсключение("Недопустимое значение параметра (параметр номер '4')");
КонецПопытки;
Если НаправлениеПоискаСКонца Тогда
НачальнаяПозиция = ?(НачальнаяПозиция <> Неопределено, НачальнаяПозиция, СтрДлина(Строка));
ЗнакНаправленияДвижения = -1;
Иначе
НачальнаяПозиция = ?(НачальнаяПозиция <> Неопределено, НачальнаяПозиция, 1);
ЗнакНаправленияДвижения = 1;
КонецЕсли;
Если ирКэш.РежимОтладкиЛкс() Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Пока Истина
И НомерВхождения <> 0
И (Ложь
Или (Истина
И Не НаправлениеПоискаСКонца
И НачальнаяПозиция <= СтрДлина(Строка))
Или (Истина
И НаправлениеПоискаСКонца
И НачальнаяПозиция >= 0))
Цикл
Позиция = Найти(Сред(Строка, НачальнаяПозиция, ДлинаСтрПоиска), ПодстрокаПоиска);
Если Позиция Тогда
ТекущаяПозиция = НачальнаяПозиция;
НачальнаяПозиция = ТекущаяПозиция + ДлинаСтрПоиска * ЗнакНаправленияДвижения;
НомерВхождения = НомерВхождения - 1;
Иначе
НачальнаяПозиция = НачальнаяПозиция + 1 * ЗнакНаправленияДвижения;
КонецЕсли;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Пока Истина И НомерВхождения <> 0 И (Ложь Или (Истина И Не НаправлениеПоискаСКонца И НачальнаяПозиция <= СтрДлина(Строка)) Или (Истина И НаправлениеПоискаСКонца И НачальнаяПозиция >= 0)) Цикл Позиция = Найти(Сред(Строка, НачальнаяПозиция, ДлинаСтрПоиска), ПодстрокаПоиска); Если Позиция Тогда ТекущаяПозиция = НачальнаяПозиция; НачальнаяПозиция = ТекущаяПозиция + ДлинаСтрПоиска * ЗнакНаправленияДвижения; НомерВхождения = НомерВхождения - 1; Иначе НачальнаяПозиция = НачальнаяПозиция + 1 * ЗнакНаправленияДвижения; КонецЕсли; КонецЦикла;
КонецЕсли;
Если НомерВхождения Тогда
ТекущаяПозиция = 0;
КонецЕсли;
Возврат ТекущаяПозиция;
КонецФункции
Функция СтрНачинаетсяСЛкс(ГдеИщем, ЧтоИщем, УчитыватьРегистр = Ложь) Экспорт
Длина = СтрДлина(ЧтоИщем);
Результат = Ложь
Или (Истина
И УчитыватьРегистр
И Лев(ГдеИщем, Длина) = ЧтоИщем)
Или (Истина
И Не УчитыватьРегистр
И Лев(НРег(ГдеИщем), Длина) = НРег(ЧтоИщем));
Возврат Результат;
КонецФункции
// Функция разбивает строку разделителем.
// Старые имена - РазбитьСтрокуРазделителем, ПолучитьМассивИзСтрокиСРазделителем
//
// Параметры:
// пСтрока - Строка - которую разбиваем;
// *пРазделитель - Строка, "." - символ-разделитель;
// *ОбрезатьНепечатныеСимволы - Булево, *Ложь - делать СокрЛП.
// *ОставлятьПустуюСтроку - Булево, *Истина - если передана пустая строка, то добавлять ее в массив.
//
// Возвращаемое значение:
// Массив - фрагментов.
//
Функция СтрРазделитьЛкс(Знач Стр, Знач Разделитель = ".", Знач ОбрезатьНепечатныеСимволы = Ложь, Знач ОставлятьПустуюСтроку = Истина) Экспорт
//Если Истина
// И Не ОбрезатьНепечатныеСимволы
// И ОставлятьПустуюСтроку
// И СтрДлина(Разделитель) = 1
// И ирКэш.НомерРежимаСовместимостиЛкс() >= 803006 // опасность рекурсии
//Тогда
// Возврат Вычислить("СтрРазделить(Стр, Разделитель, ОставлятьПустуюСтроку)"); // Вычислить() ниверлирует выигрыш
//КонецЕсли;
Если Ложь
//Или ирКэш.РежимОтладкиЛкс() // Закомментировано для избежания беконечной рекурсии
Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
МассивСтрок = Новый Массив;
Если Истина
И Не ОставлятьПустуюСтроку
И ПустаяСтрока(Стр)
Тогда
Возврат МассивСтрок;
КонецЕсли;
Если Разделитель = " " Тогда
Стр = СокрЛП(Стр);
Пока 1=1 Цикл
Поз = Найти(Стр, Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр, Поз-1));
Стр = СокрЛ(Сред(Стр, Поз));
КонецЦикла;
Иначе
ДлинаРазделителя = СтрДлина(Разделитель);
Пока 1=1 Цикл
Поз = Найти(Стр, Разделитель);
Если Поз=0 Тогда
Фрагмент = Стр;
Если ОбрезатьНепечатныеСимволы Тогда
Фрагмент = СокрЛП(Фрагмент);
КонецЕсли;
МассивСтрок.Добавить(Фрагмент);
Возврат МассивСтрок;
КонецЕсли;
Фрагмент = Лев(Стр, Поз-1);
Если ОбрезатьНепечатныеСимволы Тогда
Фрагмент = СокрЛП(Фрагмент);
КонецЕсли;
МассивСтрок.Добавить(Фрагмент);
Стр = Сред(Стр, Поз+ДлинаРазделителя);
КонецЦикла;
КонецЕсли;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
МассивСтрок = Новый Массив; Если Истина И Не ОставлятьПустуюСтроку И ПустаяСтрока(Стр) Тогда Возврат МассивСтрок; КонецЕсли; Если Разделитель = " " Тогда Стр = СокрЛП(Стр); Пока 1=1 Цикл Поз = Найти(Стр, Разделитель); Если Поз=0 Тогда МассивСтрок.Добавить(Стр); Возврат МассивСтрок; КонецЕсли; МассивСтрок.Добавить(Лев(Стр, Поз-1)); Стр = СокрЛ(Сред(Стр, Поз)); КонецЦикла; Иначе ДлинаРазделителя = СтрДлина(Разделитель); Пока 1=1 Цикл Поз = Найти(Стр, Разделитель); Если Поз=0 Тогда Фрагмент = Стр; Если ОбрезатьНепечатныеСимволы Тогда Фрагмент = СокрЛП(Фрагмент); КонецЕсли; МассивСтрок.Добавить(Фрагмент); Возврат МассивСтрок; КонецЕсли; Фрагмент = Лев(Стр, Поз-1); Если ОбрезатьНепечатныеСимволы Тогда Фрагмент = СокрЛП(Фрагмент); КонецЕсли; МассивСтрок.Добавить(Фрагмент); Стр = Сред(Стр, Поз+ДлинаРазделителя); КонецЦикла; КонецЕсли;
КонецЕсли;
Возврат МассивСтрок;
КонецФункции
// Получает подстроку заключенную между первым вхождением начального маркера и первым вхождением
// в правой части конечного маркера. Сами маркеры не включаются в результат. Опционально - если
// маркер не найден, то границей считается граница строки.
//
// Параметры:
// Текст - Строка - в которой ищем;
// НачальныйМаркер - Строка, *Неопределено - начальный маркер подстроки;
// КонечныйМаркер - Строка, *Неопределено - конечный маркер подстроки;
// ИспользоватьГраницуЕслиНачальныйМаркерНеНайден - Булево, *Истина - разрешение использования границ строки в случае, если маркер не найден;
// ВключатьМаркеры - Булево, *Ложь - включение маркеров в результат
// ВыброситьИсключениеЕслиНеНайдено - Булево -
// ИспользоватьГраницуЕслиКонечныйМаркерНеНайден - Булево, Неопределено - по умолчанию совпадает с ИспользоватьГраницуЕслиНачальныйМаркерНеНайден
//
// Возвращаемое значение:
// Неопределено - обязательные условия не выполнены;
// Строка - найденная подстрока.
//
Функция СтрокаМеждуМаркерамиЛкс(Текст, НачальныйМаркер = Неопределено, КонечныйМаркер = Неопределено, ИспользоватьГраницуЕслиНачальныйМаркерНеНайден = Истина, ВключатьМаркеры = Ложь,
ВыброситьИсключениеЕслиНеНайдено = Ложь, Знач ИспользоватьГраницуЕслиКонечныйМаркерНеНайден = Неопределено) Экспорт
ПозицияНачальногоМаркера = Найти(Текст, НачальныйМаркер);
Если Истина
И ПозицияНачальногоМаркера = 0
И ИспользоватьГраницуЕслиНачальныйМаркерНеНайден = Ложь
Тогда
Если ВыброситьИсключениеЕслиНеНайдено Тогда
ВызватьИсключение "Не найдено вхождение начального маркера";
Иначе
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Если Ложь
ИЛИ НачальныйМаркер = Неопределено
ИЛИ ПозицияНачальногоМаркера = 0
Тогда
ПозицияНачальногоМаркера = - СтрДлина(НачальныйМаркер);
КонецЕсли;
Стр = Сред(Текст, ПозицияНачальногоМаркера + СтрДлина(НачальныйМаркер));
ПозицияКонечногоМаркера = Найти(Стр, КонечныйМаркер);
Если ИспользоватьГраницуЕслиКонечныйМаркерНеНайден = Неопределено Тогда
ИспользоватьГраницуЕслиКонечныйМаркерНеНайден = ИспользоватьГраницуЕслиНачальныйМаркерНеНайден;
КонецЕсли;
Если Истина
И ПозицияКонечногоМаркера = 0
И ИспользоватьГраницуЕслиКонечныйМаркерНеНайден = Ложь
Тогда
Если ВыброситьИсключениеЕслиНеНайдено Тогда
ВызватьИсключение "Не найдено вхождение конечного маркера";
Иначе
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Если Ложь
ИЛИ КонечныйМаркер = Неопределено
ИЛИ ПозицияКонечногоМаркера = 0
Тогда
ПозицияКонечногоМаркера = СтрДлина(Стр) + 1;
КонецЕсли;
Результат = Лев(Стр, ПозицияКонечногоМаркера - 1);
Если ВключатьМаркеры Тогда
Если НачальныйМаркер <> Неопределено Тогда
Результат = НачальныйМаркер + Результат;
КонецЕсли;
Если КонечныйМаркер <> Неопределено Тогда
Результат = Результат + КонечныйМаркер;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПервыеНепечатныеСимволыЛкс(Текст) Экспорт
RegExp = ирКэш.ВычислительРегВыраженийЛкс();
RegExp.Global = Ложь;
RegExp.Pattern = "\S";
Результат = RegExp.НайтиВхождения(Текст);
Если Результат.Количество() > 0 Тогда
ТекстСмещения = Лев(Текст, Результат[0].FirstIndex);
Иначе
ТекстСмещения = "";
КонецЕсли;
Возврат ТекстСмещения;
КонецФункции
Функция ЛиВнутриСтроковогоЛитералаЛкс(ТекущееНачалоСтроки) Экспорт
Возврат (?(Лев(СокрЛ(ТекущееНачалоСтроки), 1) = "|", 1, 0) + СтрЧислоВхождений(ТекущееНачалоСтроки, """")) % 2 = 1;
КонецФункции
// Дополняет массив МассивПриемник значениями из массива МассивИсточник.
//
// Параметры:
// МассивПриемник - Массив - массив, в который необходимо добавить значения.
// МассивИсточник - Массив - массив значений для заполнения.
// ТолькоУникальныеЗначения - Булево - если истина, то в массив будут включены только уникальные значения.
//
Процедура ДополнитьМассивЛкс(МассивПриемник, МассивИсточник, ТолькоУникальныеЗначения = Ложь) Экспорт
Если ТолькоУникальныеЗначения Тогда
УникальныеЗначения = СоответствиеИзМассиваЛкс(МассивПриемник);
КонецЕсли;
Для Каждого Значение Из МассивИсточник Цикл
Если ТолькоУникальныеЗначения Тогда
Если УникальныеЗначения[Значение] <> Неопределено Тогда
Продолжить;
КонецЕсли;
УникальныеЗначения.Вставить(Значение, Истина);
КонецЕсли;
МассивПриемник.Добавить(Значение);
КонецЦикла;
КонецПроцедуры
Функция СоответствиеИзМассиваЛкс(Знач Массив) Экспорт
УникальныеЗначения = Новый Соответствие;
Для Каждого Значение Из Массив Цикл
УникальныеЗначения.Вставить(Значение, Истина);
КонецЦикла;
Возврат УникальныеЗначения;
КонецФункции
Функция СоответствиеВМассивЛкс(Знач Соответствие, ПомещатьКлючи = Истина, ПомещатьЗначения = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
Соответствие = Новый Соответствие;
#КонецЕсли
Результат = Новый Массив;
Для Каждого КлючИЗначение Из Соответствие Цикл
Если ПомещатьКлючи Тогда
Результат.Добавить(КлючИЗначение.Ключ);
КонецЕсли;
Если ПомещатьЗначения Тогда
Результат.Добавить(КлючИЗначение.Значение);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
// Возвращет массив без повторяющихся элементов.
//
// Параметры:
// Массив - Массив - массив произвольных значений.
//
// Возвращаемое значение:
// Массив - новая коллекция уникальных элементов.
//
Функция СвернутьМассивЛкс(Массив) Экспорт
Результат = Новый Массив;
ДополнитьМассивЛкс(Результат, Массив, Истина);
Возврат Результат;
КонецФункции
Функция СоответствиеИзПредставленийСпискаЗначенийЛкс(Знач СписокЗначений) Экспорт
#Если Сервер И Не Сервер Тогда
СписокЗначений = Новый СписокЗначений;
#КонецЕсли
УникальныеЗначения = Новый Соответствие;
Для Каждого КлючИЗначение Из СписокЗначений Цикл
УникальныеЗначения.Вставить(КлючИЗначение.Представление, КлючИЗначение.Значение);
КонецЦикла;
Возврат УникальныеЗначения;
КонецФункции
// Дополняет список СписокПриемник значениями из массива СписокИсточник.
//
// Параметры:
// СписокПриемник - СписокЗначений - куда необходимо добавить элементы;
// СписокИсточник - СписокЗначений - элементы, которые надо добавить;
// ТолькоУникальныеПредставления - Булево - если истина, то в приемник будут включены только уникальные представления.
//
Процедура ДополнитьСписокЗначенийЛкс(СписокПриемник, СписокИсточник, ТолькоУникальныеПредставления = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
СписокИсточник = Новый СписокЗначений;
СписокПриемник = Новый СписокЗначений;
#КонецЕсли
Если ТолькоУникальныеПредставления Тогда
УникальныеЗначения = СоответствиеИзПредставленийСпискаЗначенийЛкс(СписокПриемник);
КонецЕсли;
Для Каждого ЭлементСписка Из СписокИсточник Цикл
Если ТолькоУникальныеПредставления Тогда
Если УникальныеЗначения[ЭлементСписка.Представление] <> Неопределено Тогда
Продолжить;
КонецЕсли;
УникальныеЗначения.Вставить(ЭлементСписка.Представление, Истина);
КонецЕсли;
СписокПриемник.Добавить(ЭлементСписка.Значение, ЭлементСписка.Представление, ЭлементСписка.Пометка, ЭлементСписка.Картинка);
КонецЦикла;
КонецПроцедуры
// Возвращет список значений без повторяющихся представлений.
//
// Параметры:
// СписокВход - СписокЗначений - список произвольных значений с представлениями.
//
// Возвращаемое значение:
// СписокЗначений - новая коллекция уникальных представлений.
//
Функция СвернутьСписокЗначенийПоПредставлениюЛкс(СписокВход) Экспорт
Результат = Новый СписокЗначений;
ДополнитьСписокЗначенийЛкс(Результат, СписокВход, Истина);
Возврат Результат;
КонецФункции
Функция ПересечьМассивыЛкс(Массив1, Массив2) Экспорт
Элементы2 = СоответствиеИзМассиваЛкс(Массив2);
Результат = Новый Массив;
Для Каждого Элемент1 Из Массив1 Цикл
Если Элементы2[Элемент1] = Неопределено Тогда
Продолжить;
КонецЕсли;
Результат.Добавить(Элемент1);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ПроверитьЧтоСеансТолстогоКлиентаЛкс(НавигационнаяСсылка = "") Экспорт
Доступно = Ложь;
Если ирКэш.ЛиСеансТолстогоКлиентаЛкс() Тогда
Доступно = Истина;
#Если Клиент Тогда
ИначеЕсли ирКэш.ЛиСеансТонкогоКлиентаЛкс() Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ЗапускСеансаУправляемая", Новый Структура("НавигационнаяСсылка", НавигационнаяСсылка));
#КонецЕсли
Иначе
СообщитьЛкс("Функция доступна только в толстом клиенте",,, Истина);
КонецЕсли;
Возврат Доступно;
КонецФункции
// Встроенный язык не поддерживает функциональную адресацию ячеек памяти в левом операнде присвоения. Например
// ПриложениеОбъект.Value("RunForever") = Истина
Процедура УстановитьЗначениеПоФункциональнойСсылкеЛкс(Объект, Значение, ИмяФункции, ПараметрФункции) Экспорт
СкриптМенеджер = ирКэш.СкриптМенеджерЛкс();
Скрипт = "
|Function SetFuncValue(Object, Parameter, Value)
|Object." + ИмяФункции + "(Parameter) = Value
|End Function
|";
СкриптМенеджер.Language = "vbscript";
СкриптМенеджер.AddCode(Скрипт);
СкриптМенеджер.Run("SetFuncValue", Объект, ПараметрФункции, Значение);
КонецПроцедуры
Функция МассивИзКоллекцииЛкс(Знач Коллекция) Экспорт
Результат = Новый Массив;
Для Каждого Элемент Из Коллекция Цикл
Результат.Добавить(Элемент);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ВыгрузитьСвойствоКоллекцииЛкс(Знач Коллекция, Знач Свойство = "Имя", Знач ТипЭлемента = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(Свойство) Тогда
Если ТипЗнч(Коллекция) = Тип("Соответствие") Тогда
Свойство = "Ключ";
КонецЕсли;
КонецЕсли;
Результат = Новый Массив;
Структура = Новый Структура(Свойство);
Для каждого Элемент Из Коллекция Цикл
Если Истина
И ТипЭлемента <> Неопределено
И ТипЗнч(Элемент) <> ТипЭлемента
Тогда
Продолжить;
КонецЕсли;
ЗаполнитьЗначенияСвойств(Структура, Элемент, Свойство);
Результат.Добавить(Структура[Свойство]);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция МинимальнаяШиринаКолонкиЛкс() Экспорт
Возврат 5; // Начиная с 5 гарантируется возможность увеличения ширины перетаскиванием даже при очень большом числе колонок
КонецФункции
// Возвращает значение свойства структуры.
//
// Параметры:
// Структура - Структура
// - ФиксированнаяСтруктура - объект, из которого необходимо прочитать значение ключа.
// Ключ - Строка - имя свойства структуры, для которого необходимо прочитать значение.
// ЗначениеПоУмолчанию - Произвольный - необязательный. Возвращается когда в структуре нет значения по указанному
// ключу.
// Для скорости рекомендуется передавать только быстро вычисляемые значения (например примитивные типы),
// а инициализацию более тяжелых значений выполнять после проверки полученного значения (только если это
// требуется).
//
// Возвращаемое значение:
// Произвольный - значение свойства структуры. ЗначениеПоУмолчанию если в структуре нет указанного свойства.
//
Функция СвойствоСтруктурыЛкс(Структура, Ключ, ЗначениеПоУмолчанию = Неопределено) Экспорт
Если Структура = Неопределено Тогда
Возврат ЗначениеПоУмолчанию;
КонецЕсли;
Результат = ЗначениеПоУмолчанию;
Если Структура.Свойство(Ключ, Результат) Тогда
Возврат Результат;
Иначе
Возврат ЗначениеПоУмолчанию;
КонецЕсли;
КонецФункции
Функция РасширениеКонфигурацииОбъектаМДЛкс(ОбъектМД) Экспорт
Результат = Неопределено;
Если ирКэш.НомерВерсииПлатформыЛкс() > 803007 Тогда
Результат = ОбъектМД.РасширениеКонфигурации();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиАсинхронностьДоступнаЛкс() Экспорт
#Если Клиент Тогда
Возврат Истина
И Не ирКэш.Получить().АсинхронностьЗапрещена
И ирКэш.НомерВерсииПлатформыЛкс() <> 803009 // https://www.hostedredmine.com/issues/936748
И (Не ирКэш.ЛиФайловаяБазаЛкс() Или ирКэш.НомерРежимаСовместимостиЛкс() >= 803001)
И Не ирКэш.ЛиПортативныйРежимЛкс()
#Если Клиент И Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
И Не МонопольныйРежим()
// https://www.hostedredmine.com/issues/925027
И Не СтрКончаетсяНаЛкс(ПользователиИнформационнойБазы.ТекущийПользователь().ПолноеИмя, МаркерВременныхРолейЛкс())
#КонецЕсли
;
#Иначе
Возврат Ложь;
#КонецЕсли
КонецФункции
///////////////////////////////////////////////////
// Управляемые формы
// Ищет элемент нужного типа, начиная с указанного, шагая по родителям.
//
// Параметры:
// Элемент - ЭлементФормы - произвольный элемент формы, с которого начинаем поиск
// ТипРодителя - Тип, *Неопределено - тип искомого элемента, при Неопределено используется Тип("УправляемаяФорма"), при "все" тип не проверяется
// Свойство - Строка - проверять свойство
// ЗначениеСвойства - Произвольный - проверять значение свойства
//
// Возвращаемое значение:
// ЭлементФормы -
//
Функция РодительЭлементаУправляемойФормыЛкс(Знач Элемент, ТипРодителя = Неопределено, Знач Свойство = "", Знач ЗначениеСвойства = Неопределено) Экспорт
ТипУправляемаяФорма = Тип("УправляемаяФорма");
Если ТипРодителя = Неопределено Тогда
ТипРодителя = ТипУправляемаяФорма;
КонецЕсли;
Пока Не (Истина
И (Ложь
Или ТипРодителя = "все"
Или ТипЗнч(Элемент) = ТипРодителя)
И (Ложь
Или Не ЗначениеЗаполнено(Свойство)
Или Элемент[Свойство] = ЗначениеСвойства))
Цикл
Если ТипЗнч(Элемент) = ТипУправляемаяФорма Тогда
Элемент = Неопределено;
Прервать;
КонецЕсли;
Попытка
Элемент = Элемент.Родитель;
Исключение
// Ошибка платформы http://www.hostedredmine.com/issues/880476
Родитель = Неопределено;
Прервать;
КонецПопытки;
КонецЦикла;
Возврат Элемент;
КонецФункции
Функция ВсеПодчиненныеЭлементыФормыЛкс(ГруппаФормы, ВключаяГруппы = Ложь, Результат = Неопределено) Экспорт
Если Результат = Неопределено Тогда
Результат = Новый Массив;
КонецЕсли;
Для Каждого Подчиненный Из ГруппаФормы.ПодчиненныеЭлементы Цикл
Если ТипЗнч(Подчиненный) = Тип("ГруппаФормы") Тогда
ВсеПодчиненныеЭлементыФормыЛкс(Подчиненный, ВключаяГруппы, Результат);
Если Не ВключаяГруппы Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Результат.Добавить(Подчиненный);
КонецЦикла;
Возврат Результат;
КонецФункции
// Путь - можно передавать как полный путь к реквизиту, так и путь к родительскому реквизиту
//
// Параметры:
// ЭтаФорма - <тип> -
// Путь - <тип>, "" -
// ИмяРеквизита - <тип>, "" -
//
// Возвращаемое значение:
//
Функция ПолучитьРеквизитФормыЛкс(ЭтаФорма, Знач Путь = "", Знач ИмяРеквизита = "") Экспорт
Если Не ЗначениеЗаполнено(ИмяРеквизита) Тогда
Фрагменты = ирОбщий.СтрРазделитьЛкс(Путь);
ИмяРеквизита = Фрагменты[Фрагменты.Количество() - 1];
Фрагменты.Удалить(Фрагменты.Количество() - 1);
Путь = ирОбщий.СтрСоединитьЛкс(Фрагменты, ".");
КонецЕсли;
Результат = Неопределено;
РеквизитыФормы = ЭтаФорма.ПолучитьРеквизиты(Путь);
Для Каждого РеквизитФормы Из РеквизитыФормы Цикл
Если НРег(РеквизитФормы.Имя) = Нрег(ИмяРеквизита) Тогда
Результат = РеквизитФормы;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
// Получить тип реквизита формы
//
// Параметры:
// ЭтаФорма - <тип> -
// Путь - <тип>, "" -
// ИмяРеквизита - <тип> -
//
// Возвращаемое значение:
//
Функция ПолучитьТипРеквизитаФормыЛкс(ЭтаФорма, Путь = "", ИмяРеквизита = "") Экспорт
РеквизитФормы = ПолучитьРеквизитФормыЛкс(ЭтаФорма, Путь, ИмяРеквизита);
Результат = РеквизитФормы.ТипЗначения.Типы()[0];
Возврат Результат;
КонецФункции
// Получить путь К данным элемента управляемой формы. Чтобы функция возвращала правильное значение, в форме должен быть
// выполнен общий обработчик формы _ПриСозданииНаСервереИис.
//
// Параметры:
// Поле - <тип> -
//
// Возвращаемое значение:
//
Функция ПутьКДаннымЭлементаУправляемойФормыЛкс(Знач ЭлементФормы, ОтносительноРодителя = Ложь, Знач ЭтаФорма = Неопределено) Экспорт
Если ЭтаФорма = Неопределено Тогда
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ЭлементФормы, Тип("УправляемаяФорма"));
КонецЕсли;
ПутьКДаннымПоля = "";
Если ЭлементФормы <> ЭтаФорма Тогда
СнимокФормы = Новый Структура("мСлужебныеДанные");
ЗаполнитьЗначенияСвойств(СнимокФормы, ЭтаФорма);
//СообщитьЛкс(Поле.Имя); // Для отладки http://www.hostedredmine.com/issues/850205, http://www.hostedredmine.com/issues/850204
Если СнимокФормы.мСлужебныеДанные <> Неопределено И Не ЭтаФорма.мСлужебныеДанные.ПутиКДанным.Свойство(ЭлементФормы.Имя, ПутьКДаннымПоля) Тогда
ПутьКДаннымПоля = "";
КонецЕсли;
Если ОтносительноРодителя Тогда
ПутьКДаннымПоля = ПоследнийФрагментЛкс(ПутьКДаннымПоля);
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(ПутьКДаннымПоля) Тогда
// Криво, но для управляемой формы на клиенте других способов нет
Попытка
Пустышка = ЭтаФорма[ЭлементФормы.Имя];
ПутьКДаннымПоля = ЭлементФормы.Имя;
Исключение
КонецПопытки;
КонецЕсли;
Возврат ПутьКДаннымПоля;
КонецФункции
Процедура СкопироватьКнопкиКоманднойПанелиУправляемойФормыЛкс(Знач КоманднаяПанельИсточник, Знач КоманднаяПанельПриемник, Знач ПрефиксИмени) Экспорт
ЭтаФорма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(КоманднаяПанельИсточник);
ЭлементыФормы = ЭтаФорма.Элементы;
Для Каждого КнопкаОбразец Из КоманднаяПанельИсточник.ПодчиненныеЭлементы Цикл
Если Ложь
Или ТипЗнч(КнопкаОбразец) = Тип("ГруппаФормы")
Или Не ЗначениеЗаполнено(КнопкаОбразец.ИмяКоманды)
Тогда
// Это - системная команда
Продолжить;
КонецЕсли;
ИмяНовойКнопки = ПрефиксИмени + КнопкаОбразец.Имя;
НоваяКнопка = ЭлементыФормы.Добавить(ИмяНовойКнопки, ТипЗнч(КнопкаОбразец), КоманднаяПанельПриемник);
ЗаполнитьЗначенияСвойств(НоваяКнопка, КнопкаОбразец,, "Имя");
КонецЦикла;
КонецПроцедуры
Функция НайтиСтрокуДереваФормыПоАдресуЛкс(НачальнаяСтрока, КлючиУровней, Знач ИмяКлючевойКолонки = "Ссылка") Экспорт
ТекущаяСтрока = НачальнаяСтрока;
Уровень = 0;
Для Уровень = 0 По КлючиУровней.Количество() - 1 Цикл
ЭлементыДерева = ТекущаяСтрока.ПолучитьЭлементы();
лТекущаяСтрока = НайтиЭлементКоллекцииЛкс(ЭлементыДерева, ИмяКлючевойКолонки, КлючиУровней[Уровень]);
Если лТекущаяСтрока <> Неопределено Тогда
ТекущаяСтрока = лТекущаяСтрока;
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
Возврат ТекущаяСтрока;
КонецФункции
Функция УправляемаяФормаБСП_ВыполнитьНаСервереЛкс(Знач Форма, Знач Обработчик, ПараметрКоманды = Неопределено) Экспорт
Если Истина
И ирКэш.НомерВерсииБСПЛкс() > 200
И (Ложь
Или ирОбщий.МетодРеализованЛкс(Форма, "Подключаемый_ВыполнитьКомандуНаСервере")
Или ирОбщий.МетодРеализованЛкс(Форма, "Подключаемый_ПродолжитьВыполнениеКомандыНаСервере"))
Тогда
Попытка
ТаблицаКомандБСП = ПолучитьИзВременногоХранилища(Форма.ПараметрыПодключаемыхКоманд.АдресТаблицыКоманд);
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
Возврат Неопределено;
КонецПопытки;
ИмяКомандыВФорме = ирОбщий.ПоследнийФрагментЛкс(Обработчик);
ПараметрыВызова = Новый Структура;
ПараметрыВызова.Вставить("ИмяКомандыВФорме", ИмяКомандыВФорме);
ПараметрыВызова.Вставить("ПараметрКоманды", ПараметрКоманды);
ПараметрыВызова.Вставить("Результат", Неопределено);
#Если Сервер И Не Сервер Тогда
ТаблицаКомандБСП = Новый ТаблицаЗначений;
ирОбщий.УсловноеОформлениеУправляемойФормыЛкс();
#КонецЕсли
Если ТаблицаКомандБСП.Найти(ИмяКомандыВФорме, "ИмяВФорме") = Неопределено Тогда
ОписаниеКоманды = ТаблицаКомандБСП.Добавить();
ОписаниеКоманды.ИмяВФорме = ИмяКомандыВФорме;
ОписаниеКоманды.Обработчик = Обработчик;
АдресТаблицыКомандБСП = ПоместитьВоВременноеХранилище(ТаблицаКомандБСП, Форма.УникальныйИдентификатор);
Форма.ПараметрыПодключаемыхКоманд.АдресТаблицыКоманд = АдресТаблицыКомандБСП;
КонецЕсли;
Если ирОбщий.МетодРеализованЛкс(Форма, "Подключаемый_ВыполнитьКомандуНаСервере") Тогда
Форма.Подключаемый_ВыполнитьКомандуНаСервере(ПараметрыВызова, );
ИначеЕсли ирОбщий.МетодРеализованЛкс(Форма, "Подключаемый_ПродолжитьВыполнениеКомандыНаСервере") Тогда
Форма.Подключаемый_ПродолжитьВыполнениеКомандыНаСервере(ПараметрыВызова, );
КонецЕсли;
РезультатВызова = ПараметрыВызова.Результат;
КонецЕсли;
Возврат РезультатВызова;
КонецФункции
Функция УправляемаяФормаБСП_УсловноеОформлениеЛкс(ПараметрКоманды, Контекст) Экспорт
НастройкиКомпоновки = Новый НастройкиКомпоновкиДанных;
ирОбщий.СкопироватьЭлементыКомпоновкиЛкс(НастройкиКомпоновки.УсловноеОформление, Контекст.Форма.УсловноеОформление);
Контекст.Результат = НастройкиКомпоновки;
КонецФункции
Функция УправляемаяФормаБСП_ИсполняемыеСхемаИНастройкиТаблицыЛкс(ПараметрКоманды, Контекст) Экспорт
Если Не ЗначениеЗаполнено(ПараметрКоманды) Тогда
ИмяТаблицыФормы = Контекст.Форма.ТекущийЭлемент.Имя;
Иначе
ИмяТаблицыФормы = ПараметрКоманды;
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("Схема", Контекст.Форма.Элементы[ИмяТаблицыФормы].ПолучитьИсполняемуюСхемуКомпоновкиДанных());
Результат.Вставить("Настройки", Контекст.Форма.Элементы[ИмяТаблицыФормы].ПолучитьИсполняемыеНастройкиКомпоновкиДанных());
Контекст.Результат = Результат;
КонецФункции
#Если Клиент Тогда
Функция Форма_ВводДоступенЛкс(Знач ЭтаФорма, Знач ПроверятьПолеHTML = Ложь) Экспорт
Попытка
ВводДоступен = ЭтаФорма.ВводДоступенЛкс();
Исключение
КонецПопытки;
Результат = Ложь
Или ВводДоступен = Истина
Или ЭтаФорма.ВводДоступен()
Или (Истина
И ПроверятьПолеHTML
// При фокусе ввода у HTML функция ВводДоступен() возвращает Ложь https://partners.v8.1c.ru/forum/t/1943796/m/1943796
// Этот антибаг работает некорректно - для неактивной формы возращает Истина. Поэтому эту проверку имеет смысл включать только убедившись что надежным способом активной формы не нашлось
И (Ложь
Или (Истина
И ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ПолеФормы")
И ЭтаФорма.ТекущийЭлемент.Вид = ВидПоляФормы.ПолеHTMLДокумента
И ЭтаФорма.ТекущийЭлемент.Документ.hasFocus()) // Затратная функция 1мс
#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
Или (Истина
И ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ПолеHTMLДокумента")
И ЭтаФорма.ТекущийЭлемент.Документ.hasFocus()) // Затратная функция 1мс
#КонецЕсли
));
Возврат Результат;
КонецФункции
// Параметры:
// ЭтаФорма - Форма - обязательный для обычных форм
Процедура Форма_ВнешнееСобытиеЛкс(ЭтаФорма = Неопределено, Источник, Событие, Данные, ВводДоступен = Неопределено) Экспорт
Если Источник = "KeyboardHook" Тогда
Если ЭтаФорма = Неопределено Тогда
ЭтаФорма = АктивнаяУправляемаяФормаЛкс();
Если ЭтаФорма = Неопределено Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Если ВводДоступен <> Истина И Не Форма_ВводДоступенЛкс(ЭтаФорма) Тогда
Возврат;
КонецЕсли;
ПолученноеЧисло = Лев(Данные,5);
ПолученноеЧисло = Число(ПолученноеЧисло);
ВиртуальнаяКлавиша = ПолученноеЧисло % 256;
ПолученноеЧисло = ПолученноеЧисло - ВиртуальнаяКлавиша;
РасширеннаяКлавиша = ПолученноеЧисло % 512;
ПолученноеЧисло = ПолученноеЧисло - РасширеннаяКлавиша;
ПравыйАльт = ПолученноеЧисло % 1024;
ПолученноеЧисло = ПолученноеЧисло - ПравыйАльт;
ЛевыйАльт = ПолученноеЧисло % 2048;
ПолученноеЧисло = ПолученноеЧисло - ЛевыйАльт;
ПравыйКонтрол = ПолученноеЧисло % 4096;
ПолученноеЧисло = ПолученноеЧисло - ПравыйКонтрол;
ЛевыйКонтрол = ПолученноеЧисло % 8192;
ПолученноеЧисло = ПолученноеЧисло - ЛевыйКонтрол;
ПравыйШифт = ПолученноеЧисло % 16384;
ПолученноеЧисло = ПолученноеЧисло - ПравыйШифт;
ЛевыйШифт = ПолученноеЧисло;
Если СтрДлина(Данные) > 5 Тогда
Символ = Сред(Данные, 6);
Иначе
Символ = "";
КонецЕсли;
КодыКлавиш = ирКэш.КодыКлавишЛкс();
Если Ложь
Или Найти(Данные, КодыКлавиш["CTRL+~"]) = 1
Тогда
ирОбщий.ОткрытьГлобальноеМенюЛкс(ЭтаФорма);
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
ИначеЕсли Ложь
Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ПолеВвода")
Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ТабличноеПоле")
Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ПолеФормы")
Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ТаблицаФормы")
Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ПолеТабличногоДокумента")
Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ПолеHTMLДокумента")
Тогда
Если Найти(Данные, КодыКлавиш["CTRL+C"]) = 1 Тогда
Попытка
ирОбщий.БуферОбмена_КопироватьЛкс(ЭтаФорма);
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
Сообщить(ОписаниеОшибки);
КонецПопытки;
ИначеЕсли Ложь
//Или Найти(Данные, КодыКлавиш["CTRL+V"]) = 1 // Много нежелательных действий
Или Найти(Данные, КодыКлавиш["ALT+SHIFT+V"]) = 1
Тогда
ирОбщий.БуферОбмена_ВставитьЛкс(ЭтаФорма);
ИначеЕсли Найти(Данные, КодыКлавиш["CTRL+A"]) = 1 Тогда
Если ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ТабличноеПоле") Тогда
ирОбщий.ТабличноеПолеОбновитьТекстыПодваловЛкс(ЭтаФорма, ЭтаФорма.ТекущийЭлемент);
КонецЕсли;
ИначеЕсли Найти(Данные, КодыКлавиш["Space"]) = 1 Тогда
Если ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ТабличноеПоле") Тогда // Только для форм инструментов
ТабличноеПоле = ЭтаФорма.ТекущийЭлемент;
КолонкаПометки = КолонкаПометкиТабличногоПоляЛкс(ТабличноеПоле);
Если Истина
И Не ТабличноеПоле.ТолькоПросмотр
И ТабличноеПоле.ТекущаяКолонка <> Неопределено
И ТабличноеПоле.ТекущаяКолонка <> КолонкаПометки
И (Ложь
Или ТабличноеПоле.ТекущаяКолонка.ТолькоПросмотр
Или ТабличноеПоле.ТекущаяКолонка.ЭлементУправления = Неопределено)
И (Ложь
Или Не ТабличноеПоле.ИзменяетДанные
Или Не ЭтаФорма.ТолькоПросмотр)
Тогда
ТабличноеПоле_ИнтерактивноУстановитьПометкуТекущейСтрокиЛкс(ТабличноеПоле,, Неопределено);
КонецЕсли;
КонецЕсли;
КонецЕсли;
#КонецЕсли
КонецЕсли;
//Сообщить(Данные);
КонецЕсли;
КонецПроцедуры
Функция АктивнаяУправляемаяФормаЛкс() Экспорт
#Если ТолстыйКлиентОбычноеПриложение Тогда
Возврат Неопределено;
#КонецЕсли
ТекущееОкно = АктивноеОкно();
Если ТекущееОкно = Неопределено Тогда
Окна = ПолучитьОкна();
Для Каждого ТекущееОкно Из Окна Цикл
Если ТекущееОкно.НачальнаяСтраница Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ТипЗнч(ТекущееОкно) = Тип("ОкноКлиентскогоПриложения") Тогда
АктивнаяФорма = Неопределено;
Для Каждого Форма Из ТекущееОкно.Содержимое Цикл
Если Форма_ВводДоступенЛкс(Форма) Тогда
АктивнаяФорма = Форма;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат АктивнаяФорма;
КонецФункции
// Для тонкого клиента
Процедура ПослеУстановкиKeyboardHook(Результат = 1) Экспорт
Если Результат = Неопределено Тогда
Возврат;
КонецЕсли;
Успех = ПодключитьВнешнююКомпоненту("Обработка.ирПлатформа.Макет.KeyboardHookZip", "ПерехватКлавиатуры", ТипВнешнейКомпоненты.Native);
Если Не Успех Тогда
//ОповещениеОЗавершении = Новый ОписаниеОповещения("ПослеУстановкиKeyboardHook", ирОбщий);
//НачатьУстановкуВнешнейКомпоненты(ОповещениеОЗавершении, "Обработка.ирПлатформа.Макет.KeyboardHookZip"); // Не скомпилируется на 8.2
Попытка
УстановитьВнешнююКомпоненту("Обработка.ирПлатформа.Макет.KeyboardHookZip");
Исключение
// "Режим использования модальности" = "Не использовать" https://www.hostedredmine.com/issues/927892
КонецПопытки;
КонецЕсли;
КонецПроцедуры
#КонецЕсли