////////////////////////////////////////////////////////////////////////////////
// Подсистема "Инструменты разработчика"
// Авторское право (с) 2007-2017, Старых С.А.
// Разрешается повторное распространение и использование как в виде исходника так и в двоичной форме,
// с модификациями или без, при соблюдении следующих условий:
// - При повторном распространении исходного кода должно оставаться указанное выше уведомление об авторском
// праве, этот список условий и нижеследующий отказ от гарантий.
// - При повторном распространении двоичного кода должно воспроизводиться указанное выше уведомление об
// авторском праве, этот список условий и нижеследующий отказ от гарантий в документации и/или в других
// материалах, поставляемых при распространении.
//
// ЭТО ПРОГРАММА ПРЕДОСТАВЛЕНА БЕСПЛАТНО ДЕРЖАТЕЛЯМИ АВТОРСКИХ ПРАВ И/ИЛИ ДРУГИМИ СТОРОНАМИ "КАК ОНА ЕСТЬ"
// БЕЗ КАКОГО-ЛИБО ВИДА ГАРАНТИЙ, ВЫРАЖЕННЫХ ЯВНО ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ,
// ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ КОММЕРЧЕСКОЙ ЦЕННОСТИ И ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. НИ В КОЕМ СЛУЧАЕ,
// ЕСЛИ НЕ ТРЕБУЕТСЯ СООТВЕТСТВУЮЩИМ ЗАКОНОМ, ИЛИ НЕ УСТАНОВЛЕНО В УСТНОЙ ФОРМЕ, НИ ОДИН ДЕРЖАТЕЛЬ АВТОРСКИХ
// ПРАВ И НИ ОДНО ДРУГОЕ ЛИЦО, КОТОРОЕ МОЖЕТ ИЗМЕНЯТЬ И/ИЛИ ПОВТОРНО РАСПРОСТРАНЯТЬ ПРОГРАММУ, КАК БЫЛО
// РАЗРЕШЕНО ВЫШЕ, НЕ ОТВЕТСТВЕННЫ ПЕРЕД ВАМИ ЗА УБЫТКИ, ВКЛЮЧАЯ ЛЮБЫЕ ОБЩИЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ ИЛИ
// ПОСЛЕДОВАВШИЕ УБЫТКИ, ПРОИСТЕКАЮЩИЕ ИЗ ИСПОЛЬЗОВАНИЯ ИЛИ НЕВОЗМОЖНОСТИ ИСПОЛЬЗОВАНИЯ ПРОГРАММЫ (ВКЛЮЧАЯ,
// НО НЕ ОГРАНИЧИВАЯСЬ ПОТЕРЕЙ ДАННЫХ, ИЛИ ДАННЫМИ, СТАВШИМИ НЕПРАВИЛЬНЫМИ, ИЛИ ПОТЕРЯМИ ПРИНЕСЕННЫМИ ИЗ-ЗА
// ВАС ИЛИ ТРЕТЬИХ ЛИЦ, ИЛИ ОТКАЗОМ ПРОГРАММЫ РАБОТАТЬ СОВМЕСТНО С ДРУГИМИ ПРОГРАММАМИ), ДАЖЕ ЕСЛИ ТАКОЙ
// ДЕРЖАТЕЛЬ ИЛИ ДРУГОЕ ЛИЦО БЫЛИ ИЗВЕЩЕНЫ О ВОЗМОЖНОСТИ ТАКИХ УБЫТКОВ.
//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирПривилегированный Экспорт;
////////////////////////////////////////////////////////////////////////////////
// ОТЛАДКА
#Если Не ТонкийКлиент И Не ВебКлиент Тогда
// Присваивает первому параметру второй.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
//
// Параметры:
// П1 – Произвольный – параметр1;
// П2 – Произвольный – параметр2;
//
// Возвращаемое значение:
// П2 – Не используется.
//
Функция ПрЛкс(п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Объект - открывает Запрос или ADODB.Command или ADODB.Connection в консоли запросов
// ПостроительЗапроса - открывает результирующий запрос построителя запросов в консоли запросов
// ПостроительОтчета - открывает построитель отчета в консоли построителей отчетов, откуда можно открыть результирующий запрос построителя отчета в консоли запросов
// СхемаКомпоновки - открывает схему компоновки в консоли компоновки данных, откуда можно открыть результирующие (из макета компоновки) запросы в консоли запросов
//
// Параметры:
// Объект – Запрос, ПостроительЗапроса, ПостроительОтчета, СхемаКомпоновкиДанных, COMОбъект.ADODB.Command - исследуемый объект;
// Модально – Булево - открывать окно модально, должно быть Истина для использования функции в отладчике;
// НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц - НастройкиКомпоновкиДанных, Строка, *Неопределено -
// если первый параметр СхемаКомпоновкиДанных, то настройки компоновки,
// если первый параметр WMI или ADODB.Connection, то текст запроса,
// если первый параметр Запрос, имена временных таблиц разделенных запятыми;
// ВнешниеНаборыДанных - Структура, *Неопределено - внешние наборы данных для схемы компоновки;
// ОтложеннаяОтладка - Булево - на сервере игнорируется (равно Истина), вместо открытия инструмента отладки сразу выполняется помещение
// объектов отладки во временное хранилище;
// ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки - Число, *500000 - допустимое количество строк во всех временных таблицах запроса
// для отложенной отладки, больше этого количества строки не сохраняются, о чем сообщается в результате;
// Наименование - Строка - наименование сохраняемого объекта отложенной отладки;
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОтладитьЛкс(Объект, Модально = Ложь, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = Неопределено, ВнешниеНаборыДанных = Неопределено,
ОтложенноеВыполнение = Ложь, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки = 500000, выхОбъектДляОтладки = Неопределено, Наименование = "") Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольЗапросов) Тогда
Возврат "Нет права использования функции";
КонецЕсли;
КонецЕсли;
Если ТипЗнч(Модально) <> Тип("Булево") Тогда
ВызватьИсключение "Неправильный тип второго параметра (Модально) метода Отладить. Должен быть Булево";
КонецЕсли;
#Если Не Клиент Тогда
ОтложенноеВыполнение = Истина;
#КонецЕсли
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ОтложенноеВыполнение = Истина;
КонецЕсли;
#КонецЕсли
Если Не ОтложенноеВыполнение Тогда
Если Ложь
Или ТипЗнч(Объект) = Тип("Запрос")
Или ТипЗнч(Объект) = Тип("COMОбъект")
Тогда
КонсольЗапросов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
Результат = КонсольЗапросов.ОткрытьДляОтладки(Объект, , , Модально, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительЗапроса") Тогда
КонсольЗапросов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
Результат = КонсольЗапросов.ОткрытьДляОтладки(Объект.ПолучитьЗапрос(), , , Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("МакетКомпоновкиДанных") Тогда
КонсольЗапросов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
Результат = КонсольЗапросов.ОткрытьПоМакетуКомпоновки(Объект, Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительОтчета") Тогда
КонсольПостроителейОтчетов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольПостроителейОтчетов");
#Если Сервер И Не Сервер Тогда
КонсольПостроителейОтчетов = Обработки.ирКонсольПостроителейОтчетов.Создать();
#КонецЕсли
Результат = КонсольПостроителейОтчетов.ОткрытьДляОтладки(Объект, Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("СхемаКомпоновкиДанных") Тогда
КонсольКомпоновокДанных = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Отчет.ирКонсольКомпоновокДанных");
#Если Сервер И Не Сервер Тогда
КонсольКомпоновокДанных = Отчеты.ирКонсольКомпоновокДанных.Создать();
#КонецЕсли
Результат = КонсольКомпоновокДанных.ОткрытьДляОтладки(Объект, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ВнешниеНаборыДанных, Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("ДинамическийСписок") Тогда
Возврат "Отладка динамического списка доступна только на сервере";
Иначе
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(Объект));
Если ОбъектМД <> Неопределено Тогда
Если Метаданные.Отчеты.Индекс(ОбъектМД) <> -1 Тогда
Если Объект.СхемаКомпоновкиДанных = Неопределено Тогда
Возврат "У отчета не установлена схема компоновки данных";
КонецЕсли;
КонсольКомпоновокДанных = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Отчет.ирКонсольКомпоновокДанных");
#Если Сервер И Не Сервер Тогда
КонсольКомпоновокДанных = Отчеты.ирКонсольКомпоновокДанных.Создать();
#КонецЕсли
Результат = КонсольКомпоновокДанных.ОткрытьДляОтладки(Объект.СхемаКомпоновкиДанных, Объект.КомпоновщикНастроек.ПолучитьНастройки(), ВнешниеНаборыДанных, Модально);
КонецЕсли;
КонецЕсли;
Если Результат = Неопределено Тогда
Возврат "Не поддерживаемый тип """ + ТипЗнч(Объект) + """ первого параметра";
КонецЕсли;
КонецЕсли;
Иначе
СтруктураПараметров = Новый Структура("Объект, Модально, НастройкаКомпоновки, ВнешниеНаборыДанных", , Модально);
Результат = Неопределено;
Если ТипЗнч(Объект) = Тип("Запрос") Тогда
СтруктураЗапроса = Новый Структура("Текст, Параметры, ВременныеТаблицы, ТипЗапроса");
ВременныеТаблицы = Неопределено;
Если Объект.МенеджерВременныхТаблиц <> Неопределено Тогда
ВременныеТаблицы = ПолВТЛкс(Объект, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки);
Результат = "";
Для Каждого КлючИЗначение Из ВременныеТаблицы Цикл
Если Результат <> "" Тогда
Результат = Результат + ", ";
КонецЕсли;
Если КлючИЗначение.Значение.Количество() = ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки Тогда
Результат = Результат + КлючИЗначение.Ключ;
КонецЕсли;
КонецЦикла;
Если Результат <> "" Тогда
Результат = "Временные таблицы " + Результат + " были сохранены частично!";
КонецЕсли;
СтруктураЗапроса.ВременныеТаблицы = ВременныеТаблицы;
КонецЕсли;
СтруктураЗапроса.Текст = Объект.Текст;
СтруктураЗапроса.ТипЗапроса = "Обычный";
СтруктураЗапроса.Параметры = ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(Объект.Параметры);
СтруктураПараметров.Объект = СтруктураЗапроса;
ИначеЕсли ТипЗнч(Объект) = Тип("COMОбъект") Тогда
Попытка
Пустышка = Объект.CommandText;
ЭтоКомандаADO = Истина;
Исключение
ЭтоКомандаADO = Ложь;
Попытка
Пустышка = Объект.ConnectionString;
ЭтоСоединениеADO = Истина;
Исключение
ЭтоСоединениеADO = Ложь;
КонецПопытки;
КонецПопытки;
СтруктураЗапроса = Новый Структура("Текст, Параметры, ВременныеТаблицы, ТипЗапроса");
Если Ложь
Или ЭтоКомандаADO
Или ЭтоСоединениеADO
Тогда
Если ЭтоСоединениеADO Тогда
СтруктураЗапроса.Текст = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц;
Иначе
СтруктураЗапроса.Текст = Объект.CommandText;
// Антибаг платформы 8.2.18. Некорректная серилизация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СтруктураЗапроса.Параметры = ПолучитьКопиюОбъектаЛкс(Объект.Параметры);
СтруктураЗапроса.Параметры = Новый Структура();
Для Каждого Parameter Из Объект.Parameters Цикл
КлючПараметра = Parameter.Name;
Если Не ЛиИмяПеременнойЛкс(КлючПараметра) Тогда
КлючПараметра = "_" + КлючПараметра;
КонецЕсли;
Если Не ЛиИмяПеременнойЛкс(КлючПараметра) Тогда
КлючПараметра = КлючПараметра + XMLСтрока(СтруктураЗапроса.Параметры.Количество());
КонецЕсли;
Если СтруктураЗапроса.Параметры.Свойство(КлючПараметра) Тогда
ВызватьИсключение "Не удалось назначить параметру уникальное имя";
КонецЕсли;
СтруктураЗапроса.Параметры.Вставить(КлючПараметра, ЗначениеВСтрокуВнутр(Parameter.Value));
КонецЦикла;
КонецЕсли;
СтруктураЗапроса.ТипЗапроса = "ADO";
//ВременныеТаблицы = Неопределено;
//ВременныеТаблицы = ПолВТ(Объект, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки);
//Результат = "";
//Для Каждого КлючИЗначение Из ВременныеТаблицы Цикл
// Если Результат <> "" Тогда
// Результат = Результат + ", ";
// КонецЕсли;
// Если КлючИЗначение.Значение.Количество() = ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки Тогда
// Результат = Результат + КлючИЗначение.Ключ;
// КонецЕсли;
//КонецЦикла;
//Если Результат <> "" Тогда
// Результат = Результат + Символы.ПС + "Временные таблицы " + Результат + " были сохранены частично!";
//КонецЕсли;
//СтруктураЗапроса.ВременныеТаблицы = ВременныеТаблицы;
СтруктураПараметров.Объект = СтруктураЗапроса;
Иначе
СтруктураЗапроса.ТипЗапроса = "WQL";
СтруктураЗапроса.Текст = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц;
КонецЕсли;
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительЗапроса") Тогда
СтруктураЗапроса = Новый Структура("Текст, Параметры");
ЗаполнитьЗначенияСвойств(СтруктураЗапроса, Объект.ПолучитьЗапрос());
СтруктураЗапроса.Параметры = ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(СтруктураЗапроса.Параметры);
СтруктураПараметров.Объект = СтруктураЗапроса;
ИначеЕсли ТипЗнч(Объект) = Тип("МакетКомпоновкиДанных") Тогда
СтруктураПараметров.Вставить("Объект", Объект);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительОтчета") Тогда
Результат = "Отложенная отладка построителя отчета не поддерживается";
ИначеЕсли ТипЗнч(Объект) = Тип("СхемаКомпоновкиДанных") Тогда
СтруктураПараметров.Вставить("Объект", Объект);
СтруктураПараметров.Вставить("НастройкаКомпоновки", НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц);
СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных);
ИначеЕсли ТипЗнч(Объект) = Тип("ДинамическийСписок") Тогда
#Если Не Сервер Тогда
Возврат "Отладка динамического списка доступна только на сервере";
#КонецЕсли
НастройкаКомпоновки = Неопределено;
Схема = Неопределено;
ПолучитьСхемуИНастройкиКомпоновкиДинамическогоСпискаЛкс(Объект, НастройкаКомпоновки, Схема);
СтруктураПараметров.Вставить("Объект", Схема);
СтруктураПараметров.Вставить("НастройкаКомпоновки", НастройкаКомпоновки);
Иначе
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(Объект));
Если ОбъектМД <> Неопределено Тогда
Если Метаданные.Отчеты.Индекс(ОбъектМД) <> -1 Тогда
Если Объект.СхемаКомпоновкиДанных = Неопределено Тогда
Возврат "У отчета не установлена схема компоновки данных";
Иначе
СтруктураПараметров.Вставить("Объект", Объект.СхемаКомпоновкиДанных);
СтруктураПараметров.Вставить("НастройкаКомпоновки", Объект.КомпоновщикНастроек.ПолучитьНастройки());
СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СтруктураПараметров.Объект <> Неопределено Тогда
СтруктураПараметров.Вставить("ТипОперации", "Отладить");
Результат = ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки, Наименование);
Иначе
Если Результат = Неопределено Тогда
Результат = "Отложенная отладка объекта такого типа не поддерживается";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Обертка ОтладитьЛкс(). Модально открывает нужную консоль для редактирования объекта.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
Функция ОтЛкс(Объект, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = Неопределено, ВнешниеНаборыДанных = Неопределено, ОтложеннаяОтладка = Ложь, Наименование = "") Экспорт
Результат = ОтладитьЛкс(Объект, Истина, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ВнешниеНаборыДанных, ОтложеннаяОтладка,,, Наименование);
Возврат Результат;
КонецФункции // ОО()
// Открывает исследователь объектов.
//
// Параметры:
// Объект – Произвольный, *Неопределено - объект, который будет исследован;
// Модально – Булево - открывать окно модально;
// КакКоллекцию – Булево, *Ложь - исследовать как коллекцию вместо объекта.
//
// Возвращаемое значение:
// Сам объект.
//
Функция ИсследоватьЛкс(Объект = Неопределено, Модально = Ложь, КакКоллекцию = Ложь, ОтложенноеВыполнение = Ложь) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирИсследовательОбъектов) Тогда
Возврат "Нет права использования функции";
КонецЕсли;
КонецЕсли;
#Если Не Клиент Тогда
ОтложенноеВыполнение = Истина;
#КонецЕсли
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ОтложенноеВыполнение = Истина;
КонецЕсли;
#КонецЕсли
Если Не ОтложенноеВыполнение Тогда
ИсследовательОбъектов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИсследовательОбъектов");
#Если Сервер И Не Сервер Тогда
ИсследовательОбъектов = Обработки.ирИсследовательОбъектов.Создать();
#КонецЕсли
Если КакКоллекцию Тогда
Результат = ИсследовательОбъектов.ИсследоватьКоллекцию(Объект, Модально);
Иначе
Результат = ИсследовательОбъектов.ИсследоватьОбъект(Объект, Модально);
КонецЕсли;
Если Результат <> Неопределено Тогда
Объект = Результат;
КонецЕсли;
Иначе
СтруктураПараметров = Новый Структура("Объект, Модально, КакКоллекцию", Объект, Модально, КакКоллекцию);
Попытка
ОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(СтруктураПараметров);
Исключение
ОбъектXDTO = Неопределено;
КонецПопытки;
Если ОбъектXDTO <> Неопределено Тогда
СтруктураПараметров.Вставить("ТипОперации", "Исследовать");
выхОбъектДляОтладки = Неопределено;
Результат = ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки);
Иначе
Результат = "Отложенная отладка объекта такого типа не поддерживается";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // Исследовать()
// Обертка Исследовать. Модально открывает объект в исследователе объектов
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
Функция ИсЛкс(Объект = Неопределено, КакКоллекцию = Ложь, ОтложенноеВыполнение = Ложь) Экспорт
Возврат ИсследоватьЛкс(Объект, Истина, КакКоллекцию, ОтложенноеВыполнение);
КонецФункции // Ис()
#КонецЕсли
// ОТЛАДКА
////////////////////////////////////////////////////////////////////////////////
// Выполняет текст алгоритма.
//
// Параметры:
// ТекстДляВыполнения – Строка;
// _АлгоритмОбъект - СправочникОбъект
// *СтруктураПараметров - Структура, *Неопределено.
//
Функция ВыполнитьАлгоритм(_ТекстДляВыполнения, _АлгоритмОбъект = Null, _Режим = Null,
_П0 = Null, _П1 = Null, _П2 = Null, _П3 = Null, _П4 = Null, _П5 = Null, _П6 = Null, _П7 = Null, _П8 = Null, _П9 = Null) Экспорт
Перем Результат;
Выполнить(_ТекстДляВыполнения);
Возврат Результат;
КонецФункции
Процедура ВыполнитьАлгоритмБезРезультата(_ТекстДляВыполнения) Экспорт
Выполнить(_ТекстДляВыполнения);
КонецПроцедуры
Функция ВычислитьВыражение(Выражение, Параметры = Неопределено) Экспорт
Возврат Вычислить(Выражение);
КонецФункции
Функция ПолучитьПриглашениеОткрытьОтладчикЛкс() Экспорт
Возврат "Нажмите кнопку ""Подробно"", а затем ""Конфигуратор"", чтобы начать отладку!";
КонецФункции
Процедура ОткрытьОтладчикЛкс() Экспорт
#Если ВебКлиент Тогда
Сообщить("Команда недоступна в вебклиенте");
#Иначе
ВызватьИсключение ПолучитьПриглашениеОткрытьОтладчикЛкс();
#КонецЕсли
КонецПроцедуры
Процедура ОбработкаПолученияФормыЛкс(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка) Экспорт
#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
#Иначе
ВыбраннаяФорма = "Обработка.ирПортативный.Форма.ФормаУправляемая";
СтандартнаяОбработка = Ложь;
#КонецЕсли
КонецПроцедуры
Функция ПолучитьОписаниеТиповОдногоТипаИзОписанияТиповЛкс(Тип, ОписаниеТипов) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов = Новый ОписаниеТипов;
#КонецЕсли
Массив = Новый Массив;
Массив.Добавить(Тип);
Результат = Новый ОписаниеТипов(Массив, ОписаниеТипов.КвалификаторыЧисла, ОписаниеТипов.КвалификаторыСтроки, ОписаниеТипов.КвалификаторыДаты, ОписаниеТипов.КвалификаторыДвоичныхДанных);
Возврат Результат;
КонецФункции
// Функция разбивает строку разделителем.
//
// Параметры:
// пСтрока - Строка - которую разбиваем;
// *пРазделитель - Строка, "." - символ-разделитель;
// *ОбрезатьНепечатныеСимволы - Булево, *Ложь - делать СокрЛП.
// *ОставлятьПустуюСтроку - Булево, *Истина - если передана пустая строка, то добавлять ее в массив.
//
// Возвращаемое значение:
// Массив - фрагментов.
//
Функция ПолучитьМассивИзСтрокиСРазделителемЛкс(Знач Стр, Разделитель = ".", ОбрезатьНепечатныеСимволы = Ложь, ОставлятьПустуюСтроку = Истина) Экспорт
МассивСтрок = Новый Массив;
Если Истина
И Не ОставлятьПустуюСтроку
И ПустаяСтрока(Стр)
Тогда
Возврат МассивСтрок;
КонецЕсли;
//лСтрока = СтрЗаменить(Стр, Разделитель, Символы.ПС);
//// Баг платформы. СтрЧислоСтрок не учитывает терминальный перевод строки.
//ЧислоСтрок = СтрЧислоСтрок(лСтрока + " ");
//Для Счетчик = 1 По ЧислоСтрок Цикл
// Фрагмент = СтрПолучитьСтроку(лСтрока, Счетчик);
// Если ОбрезатьНепечатныеСимволы Тогда
// Фрагмент = СокрЛП(Фрагмент);
// КонецЕсли;
// МассивСтрок.Добавить(Фрагмент);
//КонецЦикла;
Если Разделитель = " " Тогда
Стр = СокрЛП(Стр);
Пока 1=1 Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = СокрЛ(Сред(Стр,Поз));
КонецЦикла;
Иначе
ДлинаРазделителя = СтрДлина(Разделитель);
Пока 1=1 Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
Фрагмент = Стр;
Если ОбрезатьНепечатныеСимволы Тогда
Фрагмент = СокрЛП(Фрагмент);
КонецЕсли;
МассивСтрок.Добавить(Фрагмент);
Возврат МассивСтрок;
КонецЕсли;
Фрагмент = Лев(Стр,Поз-1);
Если ОбрезатьНепечатныеСимволы Тогда
Фрагмент = СокрЛП(Фрагмент);
КонецЕсли;
МассивСтрок.Добавить(Фрагмент);
Стр = Сред(Стр,Поз+ДлинаРазделителя);
КонецЦикла;
КонецЕсли;
Возврат МассивСтрок;
КонецФункции // ПолучитьМассивИзСтрокиСРазделителемЛкс()
// Получает подстроку заключенную между первым вхождением начального маркера и первым вхождением
// в правой части конечного маркера. Сами маркеры не включаются в результат. Опционально - если
// маркер не найден, то границей считается граница строки.
//
// Параметры:
// пСтрока - Строка - в которой ищем;
// *пНачальныйМаркер - Строка, *Неопределено - начальный маркер подстроки;
// *пКонечныйМаркер - Строка, *Неопределено - конечный маркер подстроки;
// *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина - разрешение использования границ строки
// в случае, если маркер не найден;
// *пЛиВключатьМаркеры - Булево, *Ложь - включение маркеров в результат.
//
// Возвращаемое значение:
// Неопределено - обязательные условия не выполнены;
// Строка – найденная подстрока.
//
Функция ПолучитьСтрокуМеждуМаркерамиЛкс(пСтрока, пНачальныйМаркер = Неопределено, пКонечныйМаркер = Неопределено,
пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина, пЛиВключатьМаркеры = Ложь) Экспорт
ПозицияНачальногоМаркера = Найти(пСтрока, пНачальныйМаркер);
Если Истина
И ПозицияНачальногоМаркера = 0
И пЛиИспользоватьГраницуЕслиМаркерНеНайден = Ложь
Тогда
Возврат Неопределено;
КонецЕсли;
Если Ложь
ИЛИ пНачальныйМаркер = Неопределено
ИЛИ ПозицияНачальногоМаркера = 0
Тогда
ПозицияНачальногоМаркера = - СтрДлина(пНачальныйМаркер);
КонецЕсли;
Стр = Сред(пСтрока, ПозицияНачальногоМаркера + СтрДлина(пНачальныйМаркер));
ПозицияКонечногоМаркера = Найти(Стр, пКонечныйМаркер);
Если Истина
И ПозицияКонечногоМаркера = 0
И пЛиИспользоватьГраницуЕслиМаркерНеНайден = Ложь
Тогда
Возврат Неопределено;
КонецЕсли;
Если Ложь
ИЛИ пКонечныйМаркер = Неопределено
ИЛИ ПозицияКонечногоМаркера = 0
Тогда
ПозицияКонечногоМаркера = СтрДлина(Стр) + 1;
КонецЕсли;
Результат = Лев(Стр, ПозицияКонечногоМаркера - 1);
Если пЛиВключатьМаркеры Тогда
Если пНачальныйМаркер <> Неопределено Тогда
Результат = пНачальныйМаркер + Результат;
КонецЕсли;
Если пКонечныйМаркер <> Неопределено Тогда
Результат = Результат + пКонечныйМаркер;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьСтрокуМеждуМаркерамиЛкс()
Функция ЭтоИмяЛокальногоСервераЛкс(ИмяКомпьютера) Экспорт
Результат = Ложь
Или Не ЗначениеЗаполнено(ИмяКомпьютера)
Или ИмяКомпьютера = "."
Или СтрокиРавныЛкс(ИмяКомпьютера, "localhost")
Или ИмяКомпьютера = "127.0.0.1"
#Если Не ВебКлиент Тогда
Или СтрокиРавныЛкс(ИмяКомпьютера, ИмяКомпьютера())
#КонецЕсли
;
Возврат Результат;
КонецФункции
Функция ИмяКомпьютераКластераЛкс() Экспорт
Результат = ирОбщий.ПолучитьПервыйФрагментЛкс(НСтр(СтрокаСоединенияИнформационнойБазы(), "Srvr"), ":");
Возврат Результат;
КонецФункции
#Если Не ТонкийКлиент И Не ВебКлиент Тогда
Процедура ОбновитьТипЗначенияВСтрокеТаблицыЛкс(ТекущаяСтрока, Знач ИмяКолонкиЗначения = "Значение", Знач ИмяКолонкиИлиОписаниеТипов = "ОписаниеТипов",
Знач ИмяКолонкиТипаЗначения = "ТипЗначения", Знач ИмяКолонкиИмяТипаЗначения = "ИмяТипаЗначения", Знач Колонки = Неопределено) Экспорт
Если Колонки = Неопределено Тогда
Колонки = ТекущаяСтрока.Владелец().Колонки;
КонецЕсли;
ТипЗначения = ТипЗнч(ТекущаяСтрока[ИмяКолонкиЗначения]);
Если ТипЗнч(ИмяКолонкиИлиОписаниеТипов) <> Тип("ОписаниеТипов") Тогда
КолонкаОписанияТипов = Колонки.Найти(ИмяКолонкиИлиОписаниеТипов);
Если КолонкаОписанияТипов <> Неопределено Тогда
ИмяКолонкиИлиОписаниеТипов = ТекущаяСтрока[ИмяКолонкиИлиОписаниеТипов];
Иначе
ИмяКолонкиИлиОписаниеТипов = Неопределено;
КонецЕсли;
КонецЕсли;
Если Колонки.Найти(ИмяКолонкиТипаЗначения) <> Неопределено Тогда
ТекущаяСтрока[ИмяКолонкиТипаЗначения] = ПредставлениеТипаЛкс(ТипЗначения, ИмяКолонкиИлиОписаниеТипов, Ложь);
КонецЕсли;
Если Колонки.Найти(ИмяКолонкиИмяТипаЗначения) <> Неопределено Тогда
ТекущаяСтрока[ИмяКолонкиИмяТипаЗначения] = ПредставлениеТипаЛкс(ТипЗначения, ИмяКолонкиИлиОписаниеТипов, Истина);
КонецЕсли;
КонецПроцедуры
Функция ПолучитьПараметрыЗапускаПриложения1СТекущейБазыЛкс(Знач ИмяПользователяИнфобазы = "", Знач ПарольПользователяИнфобазы = "", КодРазрешения = "", РежимКонфигуратора = Ложь,
РежимЗапуска = "ОбычноеПриложение", РазрешитьОтладку = Истина, ОчисткаКэшаКлиентСерверныхВызовов = Ложь, ДополнительныеПараметры = "", СообщитьСтрокуПараметров = Истина,
СтрокаСоединения = "", ОткрытьПортативныеИнструменты = Ложь, РежимИнтерфейсаТакси = Ложь, РазделениеДанных = "") Экспорт
Если Не ЗначениеЗаполнено(СтрокаСоединения) Тогда
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
КонецЕсли;
ПараметрыЗапуска = "";
Если РежимКонфигуратора Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " CONFIG";
Иначе
ПараметрыЗапуска = ПараметрыЗапуска + " ENTERPRISE";
КонецЕсли;
ПараметрыЗапуска = ПараметрыЗапуска + " /IBConnectionString""" + СтрЗаменить(СтрокаСоединения, """", """""") + """";
Если ЗначениеЗаполнено(ИмяПользователяИнфобазы) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /WA- /N""" + ИмяПользователяИнфобазы + """";
КонецЕсли;
Если ЗначениеЗаполнено(ПарольПользователяИнфобазы) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /P""" + ПарольПользователяИнфобазы + """";
КонецЕсли;
ПараметрыЗапуска = ПараметрыЗапуска + " /UC""" + КодРазрешения + """";
Если РазрешитьОтладку Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ИдентификаторПроцессаОС = мПлатформа.ПолучитьИдентификаторПроцессаОС();
ПараметрыЗапускаДляОтладки = ПараметрыЗапускаСеансаДляПодключенияКТекущемуОтладчикуЛкс(ИдентификаторПроцессаОС);
ПараметрыЗапуска = ПараметрыЗапуска + " " + ПараметрыЗапускаДляОтладки;
КонецЕсли;
Если ОчисткаКэшаКлиентСерверныхВызовов Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /ClearCache";
КонецЕсли;
Если РежимИнтерфейсаТакси Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /iTaxi";
КонецЕсли;
Если ЗначениеЗаполнено(РазделениеДанных) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /Z""" + РазделениеДанных + """";
КонецЕсли;
Если ОткрытьПортативныеИнструменты И ирКэш.ЛиПортативныйРежимЛкс() Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /Execute""" + ирПортативный.ИспользуемоеИмяФайла + """";
КонецЕсли;
Если ЗначениеЗаполнено(ДополнительныеПараметры) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " " + ДополнительныеПараметры;
КонецЕсли;
Если СтрокиРавныЛкс(РежимЗапуска, "Авто") Тогда
// Из-за этого иногда долго стартует почему то
ПараметрыЗапуска = ПараметрыЗапуска + " /AppAutoCheckMode"; // Автоматический выбор типа приложения для запуска
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "ОбычноеПриложение") Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /RunModeOrdinaryApplication";
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "УправляемоеПриложениеТолстый") Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /RunModeManagedApplication";
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "УправляемоеПриложениеТонкий") Тогда
//ПараметрыЗапуска = ПараметрыЗапуска + "/IBConnectionString""" + СтрЗаменить(СтрокаСоединения, """", """""") + """";
КонецЕсли;
Если СообщитьСтрокуПараметров Тогда
Сообщить(ПараметрыЗапуска);
КонецЕсли;
Возврат ПараметрыЗапуска;
КонецФункции
Функция СоздатьСсылочныйОбъектПоМетаданнымЛкс(ОбъектМД, ЭтоГруппаДляНового = Ложь, ИдентификаторСсылки = Неопределено) Экспорт
Если ЭтоГруппаДляНового Тогда
Менеджер = ПолучитьМенеджерЛкс(ОбъектМД);
Объект = Менеджер.СоздатьГруппу();
Иначе
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ИмяТипа = ИмяТипаИзПолногоИмениМДЛкс(ПолноеИмяМД, "Объект");
Объект = Новый (ИмяТипа);
КонецЕсли;
//Если ПолучитьПервыйФрагментЛкс(ПолноеИмяМД) <> "ВнешнийИсточникДанных" Тогда
Если ИдентификаторСсылки = Неопределено Тогда
ИдентификаторСсылки = Новый УникальныйИдентификатор();
КонецЕсли;
Объект = ЗаменитьИдентификаторОбъектаЛкс(Объект, ИдентификаторСсылки);
//КонецЕсли;
Возврат Объект;
КонецФункции
Функция ИмяТипаИзПолногоИмениМДЛкс(Знач ПолноеИмяИлиОбъектМД, Знач Подтип = "Ссылка") Экспорт
Если ТипЗнч(ПолноеИмяИлиОбъектМД) <> Тип("Строка") Тогда
ПолноеИмяИлиОбъектМД = ПолноеИмяИлиОбъектМД.ПолноеИмя();
КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяИлиОбъектМД);
Если Фрагменты.Количество() = 3 Тогда
ИмяТипа = ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяИлиОбъектМД);
Иначе
ПервоеСлово = "";
ИменаМД = "";
Для Счетчик = 1 По Фрагменты.Количество() / 2 Цикл
ПервоеСлово = ПервоеСлово + Фрагменты[(Счетчик - 1) * 2];
ИменаМД = ИменаМД + "." + Фрагменты[(Счетчик - 1) * 2 + 1];
КонецЦикла;
ИмяТипа = ПервоеСлово + Подтип + ИменаМД;
КонецЕсли;
Возврат ИмяТипа;
КонецФункции
Функция ИмяТипаИзПолногоИмениТаблицыБДЛкс(ИмяТаблицыБД, Знач Подтип = "Ссылка") Экспорт
ОписаниеТаблицыБД = ПолучитьОписаниеТаблицыБДИис(ИмяТаблицыБД);
Если Истина
И ОписаниеТаблицыБД <> Неопределено
И ОписаниеТаблицыБД.Тип = "Точки"
Тогда
Если Подтип = "Ссылка" Тогда
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИмяТаблицыБД);
Результат = "ТочкаМаршрутаБизнесПроцессаСсылка." + Фрагменты[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);
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(МассивОбъектов.Количество(), "Изменение регистрации");
Иначе
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(КлючОбъекта);
КонецЕсли;
Если ТипЗнч(УзелИлиМассив) = Тип("Массив") Тогда
Если УзелИлиМассив.Количество() > 0 Тогда
ОдинУзелОбмена = УзелИлиМассив[0];
Иначе
ОдинУзелОбмена = Неопределено;
КонецЕсли;
МассивУзлов = УзелИлиМассив;
Иначе
ОдинУзелОбмена = УзелИлиМассив;
МассивУзлов = Новый Массив;
МассивУзлов.Добавить(УзелИлиМассив);
КонецЕсли;
Если Не ЗначениеЗаполнено(ОдинУзелОбмена) Тогда
Сообщить("Не указан узел для регистрации изменений");
Возврат Ложь;
КонецЕсли;
Если ПроверятьНаличиеТаблицыИзмененийДляКаждогоУзла Тогда
УзлыДляРегистрации = ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(ОбъектМД, МассивУзлов);
Если УзлыДляРегистрации.Количество() = 0 Тогда
Возврат Истина;
КонецЕсли;
Иначе
УзлыДляРегистрации = МассивУзлов;
КонецЕсли;
Успех = Истина;
ирПлатформа = ирКэш.Получить();
Для Каждого Объект Из МассивОбъектов Цикл
Если Индикатор <> Неопределено Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
Если НовоеЗначение Тогда
ПланыОбмена.ЗарегистрироватьИзменения(УзлыДляРегистрации, Объект);
// Антибаг платформы 8.2.17-8.3.4
Если Истина
И ирПлатформа.ВерсияПлатформы < 803005
И ТипЗнч(Объект) <> Тип("ОбъектМетаданных")
И Не ПланыОбмена.ИзменениеЗарегистрировано(ОдинУзелОбмена, Объект)
Тогда
Успех = Ложь;
Сообщить("Не удалось зарегистрировать изменение """ + Объект + """ из-за ошибки платформы, исправленной в 8.3.5");
КонецЕсли;
Иначе
ПланыОбмена.УдалитьРегистрациюИзменений(УзлыДляРегистрации, Объект);
КонецЕсли;
Если РегистрироватьДвиженияВместеСДокументом И ЭтоДокумент Тогда
ОбъектыМД = ирОбщий.ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(ОбъектМД, ДвиженияВместеСПоследовательностями, Истина);
Для Каждого МетаРегистр из ОбъектыМД Цикл
Если Не ОдинУзелОбмена.Метаданные().Состав.Содержит(МетаРегистр) Тогда
Если ПропускатьДвиженияВнеПланаОбмена Тогда
Продолжить;
Иначе
ВызватьИсключение "Движение документа по регистру " + МетаРегистр.ПолноеИмя() + " не может быть зарегистрировано в плане обмена " + ОдинУзелОбмена.Метаданные().Имя;
КонецЕсли;
КонецЕсли;
ИмяТаблицыБДРегистра = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(МетаРегистр);
НаборЗаписей = ирОбщий.СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ИмяТаблицыБДРегистра);
НаборЗаписей.Отбор[0].Установить(Объект.Ссылка);
Если НовоеЗначение Тогда
ПланыОбмена.ЗарегистрироватьИзменения(УзлыДляРегистрации, НаборЗаписей);
// Антибаг платформы 8.2.17-8.3.4
Если Истина
И ирПлатформа.ВерсияПлатформы < 803005
И Не ПланыОбмена.ИзменениеЗарегистрировано(ОдинУзелОбмена, НаборЗаписей)
Тогда
Успех = Ложь;
Сообщить("Не удалось зарегистрировать изменение " + Объект + " из-за ошибки платформы, исправленной в 8.3.5");
КонецЕсли;
Иначе
ПланыОбмена.УдалитьРегистрациюИзменений(УзлыДляРегистрации, НаборЗаписей);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Если Индикатор <> Неопределено Тогда
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
Возврат Успех;
КонецФункции
Функция ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(ОбъектМД, МассивУзлов, ТолькоУзлыСАвторегистрацией = Ложь) Экспорт
УзлыДляРегистрации = Новый Массив;
Для Каждого ПроверяемыйУзел Из МассивУзлов Цикл
ЭлементСостава = ПроверяемыйУзел.Метаданные().Состав.Найти(ОбъектМД);
Если Истина
И ЭлементСостава <> Неопределено
И (Ложь
Или Не ТолькоУзлыСАвторегистрацией
Или ЭлементСостава.АвтоРегистрация = АвтоРегистрацияИзменений.Разрешить)
Тогда
УзлыДляРегистрации.Добавить(ПроверяемыйУзел);
КонецЕсли;
КонецЦикла;
Возврат УзлыДляРегистрации;
КонецФункции
// Копирует регистрацию изменений с узла источника на узлы приемники. Опционально каждый тип данных отдельно равномерно распределяется по узлам приемникам.
// Параметры:
// НомерСообщения - Неопределено - брать номер отправленного с узла, Null - не фильтровать но номеру сообщения, иначе выбираются все изменения с номером равным или меньшим заданного
// Возвращаемое значение: Массив - количество изменений зарегистрированных по каждому узлу
Функция СкопироватьРаспределитьРегистрациюИзмененийПоУзламЛкс(УзелИсточник, УзлыПриемники, Распределять = Ложь, НомерСообщения = Null, МассивМетаданных = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
УзелИсточник = ПланыОбмена.ПолныйИис.ПустаяСсылка();
УзлыПриемники = Новый Массив;
#КонецЕсли
#Если Клиент Тогда
Состояние("Выбираем все изменения для узла...");
#КонецЕсли
Если НомерСообщения = Неопределено Тогда
НомерСообщения = УзелИсточник.НомерОтправленного;
КонецЕсли;
Результат = Новый Массив;
Для Счетчик = 1 По УзлыПриемники.Количество() Цикл
Если Распределять И ТипЗнч(УзлыПриемники[Счетчик - 1]) <> ТипЗнч(УзелИсточник) Тогда
ВызватьИсключение "Нельзя распределять на узлы другого плана обмена";
КонецЕсли;
Результат.Добавить(0);
КонецЦикла;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Узел", УзелИсточник);
Запрос.УстановитьПараметр("НомерСообщения", НомерСообщения);
МетаПланОбмена = УзелИсточник.Метаданные();
ТекстЗапроса = "";
ТипыДанныхЗапросов = Новый Массив;
Для Каждого ЭлементСостава Из МетаПланОбмена.Состав Цикл
МетаОбъект = ЭлементСостава.Метаданные;
Если Ложь
Или МетаОбъект = Неопределено
Или (Истина
И МассивМетаданных <> Неопределено
И МассивМетаданных.Найти(МетаОбъект) = Неопределено)
Тогда
Продолжить;
КонецЕсли;
Если ТекстЗапроса <> "" Тогда
ТекстЗапроса = ТекстЗапроса + ";" + Символы.ПС;
КонецЕсли;
ПолноеИмяМД = МетаОбъект.ПолноеИмя();
ТипыДанныхЗапросов.Добавить(ПолноеИмяМД);
ИмяТаблицыДляПоискаЗарегистрированных = СтрЗаменить(ПолноеИмяМД, ".Перерасчет.", ".") + ".Изменения";
ТекстЗапроса = ТекстЗапроса + "ВЫБРАТЬ *
|ИЗ
| " + ИмяТаблицыДляПоискаЗарегистрированных + " КАК РегистрацияИзменений
|ГДЕ
| РегистрацияИзменений.Узел = &Узел";
Если НомерСообщения <> Null Тогда
ТекстЗапроса = ТекстЗапроса = " И НомерСообщения <= &НомерСообщения";
КонецЕсли;
КонецЦикла;
Если ТекстЗапроса <> "" Тогда
Запрос.Текст = ТекстЗапроса;
РезультатПакета = Запрос.ВыполнитьПакет();
ИндикаторСостава = ПолучитьИндикаторПроцессаЛкс(РезультатПакета.Количество(), "Распределение изменений");
Для ИндексЗапроса = 0 По РезультатПакета.ВГраница() Цикл
ОбработатьИндикаторЛкс(ИндикаторСостава);
РезультатЗапроса = РезультатПакета[ИндексЗапроса];
#Если Сервер И Не Сервер Тогда
РезультатЗапроса1 = Новый Запрос;
РезультатЗапроса = РезультатЗапроса1.Выполнить();
#КонецЕсли
ПолноеИмяМД = ТипыДанныхЗапросов[ИндексЗапроса];
//Если Ложь
// Или РезультатЗапроса.Колонки.Найти("НомерСообщения1") <> Неопределено
// Или РезультатЗапроса.Колонки.Найти("Узел1") <> Неопределено
//Тогда
// ВызватьИсключение "В таблице " + ПолноеИмяМД + " в основной отбор включены измерения с запрещенными именами (НомерСообщения, Узел)";
//КонецЕсли;
ТаблицаКорректна = Истина;
Для Каждого КолонкаРезультата Из РезультатЗапроса.Колонки Цикл
Если Не ЭтоКорректноеПолеТаблицыИзмененийЛкс(ПолноеИмяМД, КолонкаРезультата.Имя) Тогда
Сообщить("Изменения таблицы " + ПолноеИмяМД + " не были скопированы, т.к. она имеет некорректное поле " + КолонкаРезультата.Имя + ", порожденное конфликтом имен полей");
ТаблицаКорректна = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ТаблицаКорректна Тогда
Продолжить;
КонецЕсли;
МакетныйОбъект = "";
ТекущаяГруппаТипаМетаданных = "";
Выборка = РезультатЗапроса.Выбрать();
ИндексУзла = 0;
КоличествоЭлементов = Выборка.Количество();
Если КоличествоЭлементов > 0 Тогда
Если Распределять Тогда
УзлыРегистрации = УзлыПриемники;
Иначе
УзлыРегистрации = ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(Метаданные.НайтиПоПолномуИмени(ПолноеИмяМД), УзлыПриемники);
Если УзлыРегистрации.Количество() < УзлыПриемники.Количество() Тогда
Сообщить("Изменения таблицы " + ПолноеИмяМД + " были скопированы не на все узлы, т.к. некоторые планы обмена приемников не содержат ее.");
КонецЕсли;
КонецЕсли;
Если УзлыРегистрации.Количество() > 0 Тогда
ИндикаторТаблицы = ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, ПолноеИмяМД);
ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяМД, МакетныйОбъект, ТекущаяГруппаТипаМетаданных); //, КлючевыеПоля
Пока Выборка.Следующий() Цикл
ОбработатьИндикаторЛкс(ИндикаторТаблицы);
Объект = ПолучитьОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(Выборка, МакетныйОбъект, ТекущаяГруппаТипаМетаданных, Ложь, "НомерСообщения, Узел");
// Регистрация
Если Распределять Тогда
УзелПриемник = УзлыРегистрации[ИндексУзла];
ПланыОбмена.ЗарегистрироватьИзменения(УзелПриемник, Объект);
Результат[ИндексУзла] = Результат[ИндексУзла] + 1;
ИндексУзла = ИндексУзла + 1;
Если ИндексУзла = УзлыРегистрации.Количество() Тогда
ИндексУзла = 0;
КонецЕсли;
Иначе
ПланыОбмена.ЗарегистрироватьИзменения(УзлыРегистрации, Объект);
Результат[0] = Результат[0] + 1;
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЭтоКорректноеПолеТаблицыИзмененийЛкс(ПолноеИмяМД, ИмяПоля) Экспорт
Если Ложь
Или ирОбщий.СтрокиРавныЛкс(ИмяПоля, "Узел1")
Или ирОбщий.СтрокиРавныЛкс(ИмяПоля, "НомерСообщения1")
Тогда
//ПолноеИмяРегистра = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ПолноеИмяТаблицыБД,, ".Изменения");
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмяМД);
Если ЛиКорневойТипРегистраБДЛкс(КорневойТип) Тогда
ОбъектМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмяМД);
Если ОбъектМД <> Неопределено Тогда
Если ОбъектМД.Измерения.Найти("" + ИмяПоля) = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Истина;
КонецФункции
// ИгнорироватьКолонки - Строка - имена колонок через запятую, которые не будут учитываться
Функция ПолучитьОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(Знач Выборка, Знач МакетныйОбъект, Знач ТекущаяГруппаТипаМетаданных, СчитатьДанныеОбъекта = Истина,
Знач ИгнорироватьКолонки = "", Заблокировать = Ложь) Экспорт
Если ТекущаяГруппаТипаМетаданных = "Ссылочный" Тогда
Объект = Выборка.Ссылка;
Если Заблокировать Тогда
ЗаблокироватьСсылкуВТранзакцииЛкс(Объект);
КонецЕсли;
Если СчитатьДанныеОбъекта Тогда
Объект = Объект.ПолучитьОбъект();
КонецЕсли;
ИначеЕсли ТекущаяГруппаТипаМетаданных = "Регистр" Тогда
Объект = МакетныйОбъект;
Если ЗначениеЗаполнено(ИгнорироватьКолонки) Тогда
ИгнорироватьКолонки = Нрег(ИгнорироватьКолонки) + ",";
КонецЕсли;
Для Каждого ЭлементОтбора Из Объект.Отбор Цикл
Если Найти(ИгнорироватьКолонки, НРег(ЭлементОтбора.Имя) + ",") > 0 Тогда
Продолжить;
КонецЕсли;
Попытка
ЗначениеПоля = Выборка[ЭлементОтбора.Имя];
Исключение
// Независимый регистр сведений, у измерения не включен ОсновнойОтбор
Продолжить;
КонецПопытки;
ЭлементОтбора.Значение = ЗначениеПоля;
ЭлементОтбора.Использование = Истина;
КонецЦикла;
Если Заблокировать Тогда
ЗаблокироватьНаборЗаписейПоОтборуЛкс(Объект);
КонецЕсли;
Если СчитатьДанныеОбъекта Тогда
Объект.Прочитать();
КонецЕсли;
ИначеЕсли ТекущаяГруппаТипаМетаданных = "Константа" Тогда
Объект = МакетныйОбъект;
Если Заблокировать Тогда
ЗаблокироватьКонстантуЛкс(Объект);
КонецЕсли;
Если СчитатьДанныеОбъекта Тогда
Объект.Прочитать();
КонецЕсли;
КонецЕсли;
Возврат Объект;
КонецФункции
// Добавляет глобальные переменные и методы в контекст поля текстового документа с контекстной подсказкой.
//
// Параметры
// ПолеТекстовогоДокументаСКонтекстнойПодсказкой - ОбработкаОбъект.ПолеТекстовогоДокументаСКонтекстнойПодсказкой.
//
Процедура ИнициализироватьГлобальныйКонтекстПодсказкиЛкс(ПолеТекстовогоДокументаСКонтекстнойПодсказкой) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекстовогоДокументаСКонтекстнойПодсказкой = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать();
#КонецЕсли
Если ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ЯзыкПрограммы = 1 Тогда
Возврат;
КонецЕсли;
ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ОчиститьТаблицуСловЛокальногоКонтекста();
ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьПравилоВычисленияФункции(
"ирКПА", "ПравилоВычисленияТипаЗначенияКПА");
МассивГлобальныхПеременных = Новый Массив;
МассивГлобальныхПеременных.Добавить("ирПлатформа");
Для Каждого ИмяГлобальнойПеременной Из МассивГлобальныхПеременных Цикл
Попытка
ГлобальнаяПеременная = ВычислитьВыражение(ИмяГлобальнойПеременной);
Исключение
// ирПлатформа может отсутствовать
Продолжить;
КонецПопытки;
МассивТипов = Новый Массив;
МассивТипов.Добавить(ТипЗнч(ГлобальнаяПеременная));
ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьСловоЛокальногоКонтекста(
ИмяГлобальнойПеременной, "Свойство", Новый ОписаниеТипов(МассивТипов), ГлобальнаяПеременная, Истина);
КонецЦикла;
СтруктураГлобальныхФункций = Новый Структура;
СтруктураГлобальныхФункций.Вставить("Исследовать", Тип("Число"));
СтруктураГлобальныхФункций.Вставить("Отладить", Тип("Число"));
СтруктураГлобальныхФункций.Вставить("Оперировать", Тип("Число"));
СтруктураГлобальныхФункций.Вставить("Наблюдать");
Для Каждого ЭлементГлобальнойФункции Из СтруктураГлобальныхФункций Цикл
Если ТипЗнч(ЭлементГлобальнойФункции.Значение) = Тип("Тип") Тогда
МассивТипов = Новый Массив;
МассивТипов.Добавить(ЭлементГлобальнойФункции.Значение);
ОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
ИначеЕсли ТипЗнч(ЭлементГлобальнойФункции.Значение) = Тип("ОписаниеТипов") Тогда
ОписаниеТипов = ЭлементГлобальнойФункции.Значение;
КонецЕсли;
ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьСловоЛокальногоКонтекста(
ЭлементГлобальнойФункции.Ключ, "Метод", ОписаниеТипов);
КонецЦикла;
КонецПроцедуры // ИнициализироватьГлобальныйКонтекстПодсказкиЛкс()
// Параметры - ТаблицаЗначений с колонкой Имя
Функция ЛиПараметрыАлгоритмыКорректныЛкс(Параметры) Экспорт
Результат = Истина;
Если Параметры.Количество() = 0 Тогда
Возврат Результат;
КонецЕсли;
Для Каждого СтрокаПараметра Из Параметры Цикл
Если Не ЛиИмяПеременнойЛкс(СтрокаПараметра.Имя) Тогда
Результат = Ложь;
Сообщить("Имя параметра """ + СтрокаПараметра.Имя + """ не отвечает правилам формирования имен встроенного языка",
СтатусСообщения.Внимание);
КонецЕсли;
КонецЦикла;
НеуникальныеИмена = ПолучитьНеуникальныеЗначенияКолонкиТаблицыЛкс(Параметры, "Имя");
Для Каждого НеуникальноеИмя Из НеуникальныеИмена Цикл
Сообщить("Параметр """ + НеуникальноеИмя + """ встречается более одного раза", СтатусСообщения.Внимание);
Результат = Ложь;
КонецЦикла;
Возврат Результат;
КонецФункции // ПараметрыКорректны()
// Возможно нужно объединить с ПолучитьМетаданныеЛкс
Функция ПолучитьМетаданныеПоПолномуИмениЛкс(ПолноеИмяМД) Экспорт
Объект = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД);
Результат = Объект.Метаданные();
Возврат Результат;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С МЕТАДАННЫМИ И ТИПАМИ
// Получает тип из описания типов, типа или значения.
//
// Параметры:
// пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Тип - найденный тип.
//
Функция ПолучитьТипОбъектаЛкс(пОбъект)
ТипОбъекта = Тип("Неопределено");
ТипПараметра = ТипЗнч(пОбъект);
Если ТипПараметра = Тип("ОписаниеТипов") Тогда
Если пОбъект.Типы().Количество() > 0 Тогда
ТипОбъекта = пОбъект.Типы()[0];
КонецЕсли;
ИначеЕсли ТипПараметра <> Тип("Тип") Тогда
ТипОбъекта = ТипПараметра;
Иначе
ТипОбъекта = пОбъект;
КонецЕсли;
Возврат ТипОбъекта;
КонецФункции // ПолучитьТипОбъектаЛкс()
// Проверяет, является ли строка именем корневого типа объекта БД.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина – тип является корневым типом объекта БД;
// Ложь – иначе.
//
Функция ЛиКорневойТипСсылочногоОбъектаБДЛкс(Знач КорневойТип) Экспорт
Если Найти(КорневойТип, ".") > 0 Тогда
КорневойТип = ПолучитьПервыйФрагментЛкс(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "БизнесПроцесс"
ИЛИ КорневойТип = "Задача"
ИЛИ КорневойТип = "Документ"
ИЛИ КорневойТип = "ПланВидовРасчета"
ИЛИ КорневойТип = "ПланВидовХарактеристик"
ИЛИ КорневойТип = "ПланОбмена"
ИЛИ КорневойТип = "ПланСчетов"
ИЛИ КорневойТип = "Справочник"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипКонстантыЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "Константа"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипПланаОбменаЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "ПланОбмена"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипДокументаЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "Документ"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Проверяет, является ли строка именем корневого типа ссылки.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина – тип является корневым типом ссылки;
// Ложь – иначе.
//
Функция ЛиКорневойТипСсылкиЛкс(Знач КорневойТип, ИсключаяСсылкиМетаданных = Ложь) Экспорт
Если Найти(КорневойТип, ".") > 0 Тогда
КорневойТип = ПолучитьПервыйФрагментЛкс(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ Не ИсключаяСсылкиМетаданных И КорневойТип = "Перечисление"
ИЛИ Не ИсключаяСсылкиМетаданных И КорневойТип = "Точки" // Грязно
ИЛИ КорневойТип = "ВнешнийИсточникДанных" // Грязно
ИЛИ ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипСсылкиЛкс()
// Проверяет, является ли строка именем корневого типа регистра БД.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина – тип является корневым типом регистра БД;
// Ложь – иначе.
//
Функция ЛиКорневойТипРегистраБДЛкс(КорневойТип, СчитатьПоследовательностьРегистром = Истина) Экспорт
Если Ложь
ИЛИ КорневойТип = "РегистрСведений"
ИЛИ КорневойТип = "РегистрНакопления"
ИЛИ КорневойТип = "РегистрБухгалтерии"
ИЛИ КорневойТип = "ДвиженияССубконто"
ИЛИ КорневойТип = "РегистрРасчета"
ИЛИ КорневойТип = "Перерасчет"
ИЛИ (Истина
И СчитатьПоследовательностьРегистром
И КорневойТип = "Последовательность")
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипРегистраРасчетаЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "РегистрРасчета"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипРегистраСведенийЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "РегистрСведений"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипПеречисленияЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "Перечисление"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиТипТаблицыМетассылкиЛкс(ТипТаблицы) Экспорт
Если Ложь
ИЛИ ТипТаблицы = "Перечисление"
ИЛИ ТипТаблицы = "Точки"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипПоследовательностиЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "Последовательность"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "ЖурналДокументов"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипКритерияОтбораЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "КритерийОтбора"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С МЕТАДАННЫМИ И ТИПАМИ
Функция ЛиКорневойТипТаблицыБДЛкс(КорневойТип) Экспорт
Если Ложь
Или ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип)
Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип)
Или ЛиКорневойТипРегистраБДЛкс(КорневойТип)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Проверяет, является ли строка именем типа вложенной таблицы БД.
//
// Параметры:
// ТипТаблицы - Строка, Неопределено - имя типа таблицы.
//
// Возвращаемое значение:
// Булево.
//
Функция ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Экспорт
Если Ложь
ИЛИ ТипТаблицы = "ТабличнаяЧасть"
ИЛИ ЛиИмяПредопределеннойТабличнойЧастиЛкс(ТипТаблицы)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиТипВложеннойТаблицыБДЛкс()
Функция ЛиИмяПредопределеннойТабличнойЧастиЛкс(ТипТаблицы) Экспорт
Если Ложь
ИЛИ ТипТаблицы = "ВидыСубконто"
ИЛИ ТипТаблицы = "БазовыеВидыРасчета"
ИЛИ ТипТаблицы = "ВедущиеВидыРасчета"
ИЛИ ТипТаблицы = "ВытесняющиеВидыРасчета"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиТипВложеннойТаблицыБДЛкс()
// Проверяет, корневой тип на наличие реквизита "Код".
//
// Параметры:
// КорневойТип - Строка, Произвольный.
//
// Возвращаемое значение:
// Истина – реквизит "Код" имеется;
// Ложь – иначе.
//
Функция ЛиКорневойТипОбъектаСКодомЛкс(КорневойТип) Экспорт
Если Ложь
Или КорневойТип = "ПланВидовХарактеристик"
Или КорневойТип = "ПланОбмена"
Или КорневойТип = "ПланСчетов"
Или КорневойТип = "ПланРасчета"
Или КорневойТип = "Справочник"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипОбъектаСКодомЛкс()
// Проверяет, корневой тип на наличие реквизита "Предопределенный".
//
// Параметры:
// КорневойТип - Строка, Произвольный.
//
// Возвращаемое значение:
// Истина – реквизит "Предопределенный" имеется;
// Ложь – иначе.
//
Функция ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Экспорт
Если Ложь
Или КорневойТип = "Справочник"
Или КорневойТип = "ПланСчетов"
Или КорневойТип = "ПланВидовХарактеристик"
Или КорневойТип = "ПланВидовРасчета"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипОбъектаСПредопределеннымЛкс()
// Проверяет, метаданные на иерархию.
// Иначе говоря проверяется начилие реквизита "Родитель".
//
// Параметры:
// пМетаданныеТипа - ОбъектМетаданных, Неопределено.
//
// Возвращаемое значение:
// Истина – метаданные с иерархией;
// Ложь – иначе.
//
Функция ЛиМетаданныеИерархическогоОбъектаЛкс(пМетаданныеТипа) Экспорт
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданныеТипа);
Если Ложь
Или КорневойТип = "ПланСчетов"
Или (Истина
И (Ложь
Или КорневойТип = "Справочник"
Или КорневойТип = "ПланВидовХарактеристик")
И пМетаданныеТипа.Иерархический)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМетаданныеИерархическогоОбъектаЛкс()
// Проверяет, метаданные на иерархию.
// Иначе говоря проверяется начилие реквизита "Родитель".
//
// Параметры:
// пМетаданныеТипа - ОбъектМетаданных, Неопределено.
//
// Возвращаемое значение:
// Истина – метаданные с иерархией;
// Ложь – иначе.
//
Функция ЛиМетаданныеПодчиненногоОбъектаЛкс(пМетаданныеТипа) Экспорт
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданныеТипа);
Если Истина
И (Ложь
Или КорневойТип = "Справочник"
Или КорневойТип = "ПланВидовХарактеристик")
И пМетаданныеТипа.Владельцы.Количество() > 0
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМетаданныеИерархическогоОбъектаЛкс()
// Проверяет, метаданные на иерархию с группами.
// Иначе говоря проверяется начилие реквизита "ЭтоГруппа".
//
// Параметры:
// пМетаданныеТипа - ОбъектМетаданных, Неопределено.
//
// Возвращаемое значение:
// Истина – метаданные с иерархией групп;
// Ложь – иначе.
//
Функция ЛиМетаданныеОбъектаСГруппамиЛкс(пМетаданныеТипа) Экспорт
//ТипТаблицы = ПолучитьТипТаблицыБДЛкс(пМетаданныеТипа);
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданныеТипа, Истина);
Если Ложь
Или (Истина
И КорневойТип = "Справочник"
И пМетаданныеТипа.Иерархический
И пМетаданныеТипа.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов)
Или (Истина
И КорневойТип = "ПланВидовХарактеристик"
И пМетаданныеТипа.Иерархический)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМетаданныеОбъектаСГруппамиЛкс()
// Проверяет, является ли значение ссылкой на объект БД.
//
// Параметры:
// пЗначение – ОбъектМетаданных, Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – значение является ссылкой на объект БД;
// Ложь – значение не является ссылкой на объект БД.
//
Функция ЛиСсылкаНаОбъектБДЛкс(пЗначение, ИсключаяСсылкиМетаданных = Истина) Экспорт
//Результат = ЛиКорневойТипСсылочногоОбъектаБДЛкс(ПолучитьКорневойТипКонфигурацииЛкс(пЗначение, Истина));
Результат = ЛиТипСсылкиБДЛкс(ТипЗнч(пЗначение), ИсключаяСсылкиМетаданных);
Возврат Результат;
КонецФункции // ЛиСсылкаНаОбъектБДЛкс
Функция ЛиТипСсылкиБДЛкс(Тип, ИсключаяСсылкиМетаданных = Истина) Экспорт
Результат = Ложь;
ХмлТип = XMLТип(Тип);
Если ХмлТип <> Неопределено Тогда
Если Найти(ХмлТип.ИмяТипа, "Ref.") > 0 Тогда
Если Ложь
Или Не ИсключаяСсылкиМетаданных
Или (Истина
И Найти(ХмлТип.ИмяТипа, "BusinessProcessRoutePointRef.") = 0
И Найти(ХмлТип.ИмяТипа, "EnumRef.") = 0)
Тогда
Результат = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиТипОбъектаБДЛкс(Тип) Экспорт
Результат = Ложь;
ХмлТип = XMLТип(Тип);
Если ХмлТип <> Неопределено Тогда
Если Ложь
Или Найти(ХмлТип.ИмяТипа, "Object.") > 0
Или Найти(ХмлТип.ИмяТипа, "RecordSet.") > 0
Или Найти(ХмлТип.ИмяТипа, "ValueManager.") > 0
Тогда
Результат = Истина;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиТипСсылкиТочкиМаршрутаЛкс(Тип) Экспорт
XMLТип = XMLТип(Тип);
Если XMLТип <> Неопределено Тогда
Если Найти(XMLТип.ИмяТипа, "BusinessProcessRoutePointRef.") > 0 Тогда
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Получить структуру отбора по связям И параметрам выбора
//
// Параметры:
// ЭтаФорма - <тип> -
// ПолеФормыИлиРеквизитМетаданных - <тип> -
// ДляОчистки - <тип>, Ложь -
//
// Возвращаемое значение:
//
Функция ПолучитьСтруктуруОтбораПоСвязямИПараметрамВыбораЛкс(ЭтотОбъект, ПолеФормыИлиРеквизитМетаданных, ОбъектВладелец = Неопределено, ДляОчистки = Ложь) Экспорт
Попытка
СвязиПараметровВыбора = ПолеФормыИлиРеквизитМетаданных.СвязиПараметровВыбора;
Исключение
Возврат Новый Структура();
КонецПопытки;
ПараметрыВыбора = ПолеФормыИлиРеквизитМетаданных.ПараметрыВыбора;
Отбор = Новый Структура();
МаркерОтбора = НРег("Отбор.");
Для Каждого СвязьПараметраВыбора Из СвязиПараметровВыбора Цикл
#Если Сервер И Не Сервер Тогда
СвязьПараметраВыбора = Новый СвязьПараметраВыбора;
#КонецЕсли
Если Истина
И ДляОчистки
И СвязьПараметраВыбора.ИзменениеЗначения = РежимИзмененияСвязанногоЗначения.НеИзменять
Тогда
Продолжить;
КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(СвязьПараметраВыбора.ПутьКДанным);
ИмяРеквизита = Фрагменты[Фрагменты.ВГраница()];
Если Фрагменты.Количество() = 1 Тогда
Если ОбъектВладелец = Неопределено Тогда
ОбъектДляРеквизита = ЭтотОбъект;
Иначе
ОбъектДляРеквизита = ОбъектВладелец;
КонецЕсли;
Иначе
ОбъектДляРеквизита = ЭтотОбъект;
КонецЕсли;
Попытка
ЗначениеДанных = Вычислить("ОбъектДляРеквизита." + ИмяРеквизита);
Исключение
// Например поле таблицы или на сервере текущая строка таблицы
Продолжить;
КонецПопытки;
Если Найти(НРег(СвязьПараметраВыбора.Имя), МаркерОтбора) <> 1 Тогда
// Там можно писать любой текст и даже сам дизайнер иногда вставляет "_Отбор" вместо "Отбор"
Продолжить;
КонецЕсли;
Отбор.Вставить(Сред(СвязьПараметраВыбора.Имя, СтрДлина(МаркерОтбора) + 1), ЗначениеДанных);
КонецЦикла;
Для Каждого ПараметрВыбора Из ПараметрыВыбора Цикл
#Если Сервер И Не Сервер Тогда
ПараметрВыбора = Новый ПараметрВыбора;
#КонецЕсли
Если Найти(НРег(ПараметрВыбора.Имя), МаркерОтбора) <> 1 Тогда
// Там можно писать любой текст и даже сам дизайнер иногда вставляет "_Отбор" вместо "Отбор"
Продолжить;
КонецЕсли;
Отбор.Вставить(Сред(ПараметрВыбора.Имя, СтрДлина(МаркерОтбора) + 1), ПараметрВыбора.Значение);
КонецЦикла;
Возврат Отбор;
КонецФункции
// Проверяет, является ли значение ссылкой на значение перечисления.
//
// Параметры:
// пЗначение – Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – значение является ссылкой на объект БД;
// Ложь – значение не является ссылкой на объект БД.
//
Функция ЛиСсылкаНаПеречислениеЛкс(пЗначение) Экспорт
Возврат (ПолучитьКорневойТипКонфигурацииЛкс(пЗначение) = "Перечисление");
КонецФункции // ЛиСсылкаНаПеречислениеЛкс()
// Проверяет, является ли ключом записи регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – тип ключа записи регистра подтвержден;
// Ложь – тип ключа записи регистра не подтвержден.
//
Функция ЛиКлючЗаписиРегистраЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "ключ записи:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКлючЗаписиРегистраЛкс()
// Проверяет, является ли записью регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – тип записи регистра подтвержден;
// Ложь – тип записи регистра не подтвержден.
//
Функция ЛиЗаписьРегистраЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "запись:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛксЛиКлючЗаписиБД()
// Проверяет, является ли набором записей регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – тип набора записей регистра подтвержден;
// Ложь – тип набора записей регистра не подтвержден.
//
Функция ЛиНаборЗаписейРегистраЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "набор записей:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиНаборЗаписейРегистраЛкс()
// Проверяет, является ли субконтом описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – тип субконто подтвержден;
// Ложь – тип субконто не подтвержден.
//
Функция ЛиСубконтоЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "субконто:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиСубконтоЛкс()
// Проверяет, является ли менеджером записи регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – тип менеджер записи регистра подтвержден;
// Ложь – тип менеджер записи регистра не подтвержден.
//
Функция ЛиМенеджерЗаписиРегистраЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "менеджер записи:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМенеджерЗаписиРегистраЛкс()
// Проверяет, является ли значение табличной частью внешней обработки.
//
// Параметры:
// пЗначение – Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – значение является табличной частью внешней обработки;
// Ложь – значение не является табличной частью внешней обработки.
//
Функция ЛиТабличнаяЧастьВнешнейОбработкиЛкс(пЗначение) Экспорт
СтрокаТипЗначения = ПолучитьПервыйФрагментЛкс(Строка(пЗначение));
Возврат (СтрокаТипЗначения = "ВнешняяОбработкаТабличнаяЧасть");
КонецФункции // ЛксЛиВнешняяОбработка()
// Получает ссылочный тип по метаданным.
//
// Параметры:
// пМетаданные – ОбъектМетаданных.
//
// Возвращаемое значение:
// – Тип - ссылочный;
// Неопределено – тип нельзя получить.
//
Функция ПолучитьСсылочныйТипПоМетаданнымЛкс(пМетаданные) Экспорт
Результат = Неопределено;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданные, Истина);
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
Результат = Тип(КорневойТип + "Ссылка." + пМетаданные.Имя);
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьСсылочныйТипПоМетаданнымЛкс()
// Получает метаданные по полному имени, описанию типов, типу, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Произвольный – для чего получаем метаданные.
//
// Возвращаемое значение:
// – Метаданные - полученные;
// Неопределено - не удалось получить метаданные.
//
Функция ПолучитьМетаданныеЛкс(пОбъект) Экспорт
Если ТипЗнч(пОбъект) = Тип("Строка") Тогда
Если ПустаяСтрока(пОбъект) Тогда
Результат = Неопределено;
Иначе
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(пОбъект);
Если Фрагменты.Количество() = 3 Тогда
// ВидыСубконто, Изменения
ПолноеИмяМД = Фрагменты[0] + "." + Фрагменты[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 Тогда
СписокРеквизитов.Добавить("Наименование", "Наименование", , КартинкаРеквизита);
КонецЕсли;
Если ЛиМетаданныеИерархическогоОбъектаЛкс(ОбъектМетаданных) Тогда
СписокРеквизитов.Добавить("Родитель", "Родитель", , КартинкаРеквизита);
Если ЛиМетаданныеОбъектаСГруппамиЛкс(ОбъектМетаданных) Тогда
ИерархияГрупп = Истина;
Если Не ЛиВключатьНедоступные Тогда
ЭтоГруппа = пОбъект.ЭтоГруппа;
КонецЕсли;
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("ЭтоГруппа", "Это группа", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("Предопределенный", "Предопределенный", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
СписокРеквизитов.Добавить("ПометкаУдаления", "Пометка удаления", , КартинкаРеквизита);
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("Ссылка", "Ссылка", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
#Если Клиент Тогда
Если ЛиСКартинками Тогда
КартинкаРеквизита = БиблиотекаКартинок.Реквизит;
КонецЕсли;
#КонецЕсли
Для Каждого МетаРеквизит Из ОбъектМетаданных.Реквизиты Цикл
Если Ложь
Или ЛиВключатьНедоступные
Или Не ИерархияГрупп
Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента
Или (Истина
И ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы)
Или (Истина
И Не ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента)
Тогда
СписокРеквизитов.Добавить(МетаРеквизит.Имя, МетаРеквизит.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
Если ирКэш.Получить().ВерсияПлатформы >= 802014 Тогда
Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл
Если ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Тогда
СписокРеквизитов.Добавить(ОбщийРеквизит.Имя, ОбщийРеквизит.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЛиСТабличнымиЧастями Тогда
#Если Клиент Тогда
Если ЛиСКартинками Тогда
КартинкаРеквизита = БиблиотекаКартинок.ТабличнаяЧасть;
КонецЕсли;
#КонецЕсли
Для Каждого МетаТабличнаяЧасть Из ОбъектМетаданных.ТабличныеЧасти Цикл
Если Ложь
Или ЛиВключатьНедоступные
Или Не ИерархияГрупп
Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента
Или (Истина
И ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы)
Или (Истина
И Не ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента)
Тогда
СписокРеквизитов.Добавить(МетаТабличнаяЧасть.Имя, МетаТабличнаяЧасть.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЛиСортировать Тогда
СписокРеквизитов.СортироватьПоПредставлению();
КонецЕсли;
Возврат СписокРеквизитов;
КонецФункции // ПолучитьСписокРеквизитовОбъектаБДЛкс()
// Получает строку для установки порядка. Пример "Контрагент убыв, Номенклатура.Код возр".
//
// Параметры:
// Порядок – Порядок.
//
// Возвращаемое значение:
// Строка - для установки порядка.
//
Функция ПолучитьСтрокуПорядкаЛкс(Порядок) Экспорт
Строка = "";
Для Каждого ЭлементПорядка Из Порядок Цикл
Строка = Строка + ", " + ЭлементПорядка.ПутьКДанным + " ";
Если ЭлементПорядка.Направление = НаправлениеСортировки.Возр Тогда
Строка = Строка + "возр";
Иначе
Строка = Строка + "убыв";
КонецЕсли;
КонецЦикла;
Возврат Сред(Строка, 2);
КонецФункции // ПолучитьСтрокуПорядкаЛкс()
// Выполняет текст на внутреннем языке. Применяется для безопасного выполнения произвольного кода.
// Безопасность заключается в том, что нет свойств локального контекста
// и недоступны доопределенные Свойства глобального контекста.
//
// Параметры:
// ТекстДляВыполнения – Строка;
// *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля.
//
Процедура ВыполнитьВКонтекстеОбщегоМодуляЛкс(ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт
Выполнить(ТекстДляВыполнения);
КонецПроцедуры // ВыполнитьВКонтекстеОбщегоМодуляЛкс()
// Получает копию произвольного объекта. Копирование производится через сериализацию.
//
// Параметры:
// пОбъект – Произвольное – сохраняемое значение;
//
// Возвращаемое значение:
// Произвольный - копия объекта.
//
Функция ПолучитьКопиюОбъектаЛкс(пОбъект, ИспользоватьXDTO = Ложь) Экспорт
Если ИспользоватьXDTO Тогда
НовыйОбъект = СериализаторXDTO.ПрочитатьXDTO(СериализаторXDTO.ЗаписатьXDTO(пОбъект));
Иначе
НовыйОбъект = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(пОбъект));
КонецЕсли;
Возврат НовыйОбъект;
КонецФункции // ПолучитьКопиюОбъектаЛкс()
// Находит элемент коллекции по свойству "ПутьКДанным".
//
// Параметры:
// пКоллекция – Коллекция – все элементы которой имеют свойство "ПутьКДанным";
// пПутьКДанным – Строка – искомое значение.
//
// Возвращаемое значение:
// – ЭлементКоллекции;
// Неопределено - не найден.
//
Функция НайтиЭлементКоллекцииПоПутиКДаннымЛкс(пКоллекция, пПутьКДанным) Экспорт
СуществующаяСтрока = Неопределено;
Для Каждого ЭлементКоллеции Из пКоллекция Цикл
Если ЭлементКоллеции.ПутьКДанным = пПутьКДанным Тогда
СуществующаяСтрока = ЭлементКоллеции;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат СуществующаяСтрока;
КонецФункции // НайтиЭлементКоллекцииПоПутиКДаннымЛкс()
// Находит поле настройки по пути к данным.
//
// Параметры:
// пПоляНастройки – ПоляНастройки;
// пПутьКДанным – Строка – путь к данным поля в виде разыменовывания;
// *пПутьКТекущемуПолю - Строка, "" - путь к текущему полю.
//
// Возвращаемое значение:
// ПолеНастройки – найденное поле;
// Неопределено - иначе.
//
Функция НайтиПолеНастройкиПоПутиКДаннымЛкс(пПоляНастройки, пПутьКДанным, пПутьКТекущемуПолю = "") Экспорт
ПоляНастройки = пПоляНастройки;
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(пПутьКДанным);
ТекущееПоле = Неопределено;
Для Каждого Фрагмент Из МассивФрагментов Цикл
пПутьКТекущемуПолю = пПутьКТекущемуПолю + ?(пПутьКТекущемуПолю = "", "", ".") + Фрагмент;
ТекущееПоле = НайтиЭлементКоллекцииПоПутиКДаннымЛкс(ПоляНастройки, пПутьКТекущемуПолю);
Если ТекущееПоле = Неопределено Тогда
Прервать;
КонецЕсли;
ПоляНастройки = ТекущееПоле.Поля;
КонецЦикла;
Возврат ТекущееПоле;
КонецФункции // НайтиПолеНастройкиПоПутиКДаннымЛкс()
// Копирует один элемент отбора в другой. Если Использование = Ложь, то копируется только оно.
//
// Параметры:
// пЭлементОтбораПриемник – ЭлементОтбора – куда копируем;
// пЭлементОтбораИсточник - ЭлементОтбора - откуда копируем.
//
Процедура СкопироватьЭлементОтбораЛкс(пЭлементОтбораПриемник, пЭлементОтбораИсточник) Экспорт
ЗаполнитьЗначенияСвойств(пЭлементОтбораПриемник, пЭлементОтбораИсточник, "Представление, Использование");
МассивСвойствЭлементаОтбора = Новый Массив;
МассивСвойствЭлементаОтбора.Добавить("ВидСравнения");
МассивСвойствЭлементаОтбора.Добавить("Значение");
МассивСвойствЭлементаОтбора.Добавить("ЗначениеС");
МассивСвойствЭлементаОтбора.Добавить("ЗначениеПо");
Для Каждого Свойство Из МассивСвойствЭлементаОтбора Цикл
Значение = пЭлементОтбораИсточник[Свойство];
Если пЭлементОтбораПриемник[Свойство] <> Значение Тогда
пЭлементОтбораПриемник[Свойство] = Значение;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // СкопироватьЭлементОтбораЛкс()
// Порт СкопироватьОтборЛкс.
Процедура СкопироватьОтборДинамическогоСпискаЛкс(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие = Ложь,
ТолькоИспользуемые = Ложь) Экспорт
СкопироватьОтборЛкс(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие, ТолькоИспользуемые);
КонецПроцедуры // СкопироватьОтборДинамическогоСпискаЛкс()
// Порт СкопироватьОтборЛкс.
Процедура СкопироватьОтборСтатическийЛкс(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие = Ложь,
ТолькоИспользуемые = Ложь) Экспорт
СкопироватьОтборЛкс(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие, ТолькоИспользуемые);
КонецПроцедуры // СкопироватьОтборСтатическийЛкс()
// Копирует отбор.
// Если нужно, в приемнике создаются отсутствующие элементы отбора.
//
// Параметры:
// пОтборПриемник – Отбор – куда копируем;
// пОтборИсточник - Отбор, Структура - откуда копируем;
// пСоздаватьОтсутствующие - Булево, *Ложь - признак создания отсутствующих элементов отбора в источнике.
//
Процедура СкопироватьОтборЛкс(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие = Ложь,
ТолькоИспользуемые = Ложь) Экспорт
//Если пСоздаватьОтсутствующие Тогда
// ДоступныеПоля = пОтборПриемник.ПолучитьДоступныеПоля();
//КонецЕсли;
Для Каждого ЭлементОтбораИсточника Из пОтборИсточник Цикл
Если Истина
И ТолькоИспользуемые
И Не ЭлементОтбораИсточника.Использование
Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементОтбораИсточника) = Тип("КлючИЗначение") Тогда
ЭлементОтбораИсточника = ЭлементОтбораИсточника.Значение;
КонецЕсли;
//Если ЭлементОтбораИсточника.Имя = "" Тогда
// Сообщить("Невозможно определить элемент отбора приемника при копировании отбора.",
// СтатусСообщения.Внимание);
// Продолжить;
//КонецЕсли;
ЭлементОтбораПриемника = пОтборПриемник.Найти(ЭлементОтбораИсточника.Имя);
Если ЭлементОтбораПриемника = Неопределено Тогда
Если Истина
И пСоздаватьОтсутствующие
//И НайтиПолеНастройкиПоПутиКДаннымЛкс(ДоступныеПоля, ЭлементОтбораИсточника.ПутьКДанным) <> Неопределено
Тогда
Попытка
ЭлементОтбораПриемника = пОтборПриемник.Добавить(ЭлементОтбораИсточника.ПутьКДанным, ЭлементОтбораИсточника.Имя);
Исключение
Продолжить;
КонецПопытки;
Иначе
Продолжить;
КонецЕсли;
КонецЕсли;
СкопироватьЭлементОтбораЛкс(ЭлементОтбораПриемника, ЭлементОтбораИсточника);
КонецЦикла;
КонецПроцедуры // СкопироватьОтборЛкс()
// Получает инвертированный вид сравнения.
//
// Параметры:
// ВидСравнения – ВидСравнения.
//
// Возвращаемое значение:
// ВидСравнения;
//
Функция ПолучитьИнвертированныйВидСравненияЛкс(пВидСравнения) Экспорт
МассивИнвертируемыхТиповСравнения = Новый Массив;
МассивИнвертируемыхТиповСравнения.Добавить("ВИерархии");
МассивИнвертируемыхТиповСравнения.Добавить("ВСписке");
МассивИнвертируемыхТиповСравнения.Добавить("Равно");
МассивИнвертируемыхТиповСравнения.Добавить("Содержит");
МассивИнвертируемыхТиповСравнения.Добавить("ВСпискеПоИерархии");
Для Каждого ТипСравнения Из МассивИнвертируемыхТиповСравнения Цикл
ПрямойТипСравнения = Вычислить("ВидСравнения." + ТипСравнения);
Если ПрямойТипСравнения = пВидСравнения Тогда
Возврат Вычислить("ВидСравнения.Не" + ТипСравнения);
КонецЕсли;
ОбратныйТипСравнения = Вычислить("ВидСравнения.Не" + ТипСравнения);
Если ОбратныйТипСравнения = пВидСравнения Тогда
Возврат Вычислить("ВидСравнения." + ТипСравнения);
КонецЕсли;
КонецЦикла;
Возврат пВидСравнения;
КонецФункции // ПолучитьИнвертированныйВидСравненияЛкс()
// Копирует один порядок в другой. Приемник перед копированием очищается.
//
// Параметры:
// пПорядокПриемник – Порядок – куда копируем;
// пПорядокИсточник - Порядок - откуда копируем.
//
Процедура СкопироватьПорядокЛкс(пПорядокПриемник, пПорядокИсточник) Экспорт
пПорядокПриемник.Очистить();
Для Каждого ЭлементПорядка Из пПорядокИсточник Цикл
пПорядокПриемник.Добавить(ЭлементПорядка.ПутьКДанным, ЭлементПорядка.Имя, , ЭлементПорядка.Направление);
КонецЦикла;
КонецПроцедуры // СкопироватьПорядокЛкс()
// Возвращает текущее время в миллисекундах.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Число.
//
Функция ПолучитьТекущееВремяВМиллисекундахЛкс() Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Результат = мПлатформа.ПолучитьТекущееВремяВМиллисекундах();
Возврат Результат;
КонецФункции
// Выполняет запрос. Опционально сообщает его текст и время выполнения.
// Удобно для оптимизации.
//
// Параметры:
// Запрос – Запрос;
// *ЛиОтладка - Булево, *Ложь - показывать тексты запросов и время выполнения.
// *Заголовок - Строка, *"" - название запроса.
//
// Возвращаемое значение:
// РезультатЗапроса.
//
Функция ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка = Ложь, Заголовок = "") Экспорт
Если ЛиОтладка Тогда
ВремяНачала = ПолучитьТекущееВремяВМиллисекундахЛкс();
КонецЕсли;
Результат = Запрос.Выполнить();
Если ЛиОтладка Тогда
Текст = Новый ТекстовыйДокумент;
Текст.УстановитьТекст(Запрос.Текст);
Текст.Показать(Заголовок + " - " + Строка(ПолучитьТекущееВремяВМиллисекундахЛкс() - ВремяНачала) + " мс");
КонецЕсли;
Возврат Результат;
КонецФункции // ВыполнитьЗамеритьЗапросЛкс()
// Получает константу языка запросов заданного типа с учетом квалификаторов описания типов.
//
// Параметры:
// ТипПоля – Тип;
// ОписаниеТипов - ОписаниеТипов - для обращения к квалифицаторам.
//
// Возвращаемое значение:
// Строка.
//
Функция ПолучитьКонстантуТипаЗапросаЛкс(ТипПоля, ОписаниеТипов = Неопределено) Экспорт
Если ТипПоля = Тип("Строка") Тогда
Результат = "ВЫРАЗИТЬ("""" КАК СТРОКА(" + Формат(ОписаниеТипов.КвалификаторыСтроки.Длина, "ЧН=; ЧГ=") + "))";
ИначеЕсли ТипПоля = Тип("Число") Тогда
Результат = "ВЫРАЗИТЬ(0 КАК ЧИСЛО(" + Формат(ОписаниеТипов.КвалификаторыЧисла.Разрядность, "ЧН=; ЧГ=") + ", "
+ Формат(ОписаниеТипов.КвалификаторыЧисла.РазрядностьДробнойЧасти, "ЧН=; ЧГ=") + "))";
ИначеЕсли ТипПоля = Тип("Дата") Тогда
Если ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Дата Тогда
Результат = "ДАТАВРЕМЯ(1,1,1)";
Иначе
Результат = "ДАТАВРЕМЯ(1,1,1,0,0,0)";
КонецЕсли;
ИначеЕсли ТипПоля = Тип("Булево") Тогда
Результат = "ИСТИНА";
ИначеЕсли ТипПоля = Тип("NULL") Тогда
Результат = "NULL";
ИначеЕсли ТипПоля = Тип("НЕОПРЕДЕЛЕНО") Тогда
Результат = "НЕОПРЕДЕЛЕНО";
ИначеЕсли ТипПоля = Тип("ВидДвиженияНакопления") Тогда
Результат = "ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)";
ИначеЕсли ТипПоля = Тип("ВидДвиженияБухгалтерии") Тогда
Результат = "ЗНАЧЕНИЕ(ВидДвиженияБухгалтерии.Дебет)";
ИначеЕсли ТипПоля = Тип("ВидСчета") Тогда
Результат = "ЗНАЧЕНИЕ(ВидСчета.Активный)";
Иначе
МетаданныеТипаПоля = Метаданные.НайтиПоТипу(ТипПоля);
Если МетаданныеТипаПоля <> Неопределено Тогда
// Баг платформы 8.1.10.50
Если ПолучитьКорневойТипКонфигурацииЛкс(МетаданныеТипаПоля) = "ПланОбмена" Тогда
Результат = "НЕОПРЕДЕЛЕНО";
Возврат Результат;
КонецЕсли;
Результат = "ЗНАЧЕНИЕ(" + МетаданныеТипаПоля.ПолноеИмя() + ".ПустаяСсылка)";
Иначе
//Сообщить("Неизвестный тип поля при формировании имитатора результата: " + ТипПоля, СтатусСообщения.Важное);
Результат = "NULL";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьКонстантуТипаЗапроса()
// Возвращает текст запроса только из констант, дающий идентичный переданному набор колонок.
//
// Параметры:
// КоллекцияПолей – КоллекцияКолонокРезультатаЗапроса.
//
// Возвращаемое значение:
// Текст.
//
Функция ПолучитьЗапросИмитаторКоллекцииПолейЛкс(КоллекцияПолей) Экспорт
// Формирование запроса-имитатора
ОписаниеПолей = "";
Для Каждого Колонка Из КоллекцияПолей Цикл
ОписаниеПолей = ОписаниеПолей + ", ";
МассивТипов = Колонка.ТипЗначения.Типы();
НачальноеКоличество = МассивТипов.Количество();
Для СчетчикМассивТипов = 1 По НачальноеКоличество Цикл
ТипПоля = МассивТипов[НачальноеКоличество - СчетчикМассивТипов];
Если ТипПоля = Тип("NULL") Тогда
МассивТипов.Удалить(НачальноеКоличество - СчетчикМассивТипов);
КонецЕсли;
КонецЦикла;
Если МассивТипов.Количество() = 0 Тогда
ОписаниеПолей = ОписаниеПолей + "НЕОПРЕДЕЛЕНО";
ИначеЕсли МассивТипов.Количество() = 1 Тогда
ТипПоля = МассивТипов[0];
ОписаниеПолей = ОписаниеПолей + ПолучитьКонстантуТипаЗапросаЛкс(ТипПоля, Колонка.ТипЗначения);
Иначе
ОписаниеПолей = ОписаниеПолей + "ВЫБОР";
Для Каждого ТипПоля Из МассивТипов Цикл
ОписаниеПолей = ОписаниеПолей + " КОГДА ЛОЖЬ ТОГДА " + ПолучитьКонстантуТипаЗапросаЛкс(ТипПоля, Колонка.ТипЗначения);
КонецЦикла;
ОписаниеПолей = ОписаниеПолей + " КОНЕЦ";
КонецЕсли;
ОписаниеПолей = ОписаниеПолей + " КАК " + Колонка.Имя; // запрещенные имена например "Соединение" так вызывают ошибку?
КонецЦикла;
Результат = "ВЫБРАТЬ " + Сред(ОписаниеПолей, 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;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции // ПолучитьИндексКартинкиСсылкиЛкс()
// Добавляет в таблицу значений строки из другой таблицы значений и
// в них значения колонок с совпадающими наименованиями.
//
// Параметры:
// ТаблицаИсточник - таблица значений, откуда берутся значения;
// ТаблицаПриемник - таблица значений, куда добавляются строки;
// *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк;
// *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет.
//
Процедура ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИсточник, ТаблицаПриемник,
СтруктураЗначенийПоУмолчанию = Неопределено, СтруктураНовыхЗначений = Неопределено) Экспорт
СтрокаСовпадающихКолонок = "";
Разделитель = ",";
Если ТипЗнч(ТаблицаИсточник) = Тип("ТаблицаЗначений") Тогда
КолонкиИсточника = ТаблицаИсточник.Колонки;
Иначе
КолонкиИсточника = Метаданные.НайтиПоТипу(ТипЗнч(ТаблицаИсточник)).Реквизиты;
КонецЕсли;
ЛиПриемникТЧ = ТипЗнч(ТаблицаПриемник) <> Тип("ТаблицаЗначений");
Если ЛиПриемникТЧ Тогда
КолонкиПриемника = ТаблицаПриемник.ВыгрузитьКолонки().Колонки;
Иначе
КолонкиПриемника = ТаблицаПриемник.Колонки;
КонецЕсли;
Для каждого Колонка Из КолонкиПриемника Цикл
Если СтруктураНовыхЗначений <> Неопределено Тогда
Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если Истина
И (Ложь
Или Не ЛиПриемникТЧ
Или Колонка.Имя <> "НомерСтроки")
И КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено
Тогда
СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя;
КонецЕсли;
КонецЦикла;
СтрокаСовпадающихКолонок = Сред(СтрокаСовпадающихКолонок, СтрДлина(Разделитель) + 1);
Для каждого СтрокаТаблицыИсточника Из ТаблицаИсточник Цикл
СтрокаТаблицыПриемника = ТаблицаПриемник.Добавить();
Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураЗначенийПоУмолчанию);
КонецЕсли;
// Заполним значения в совпадающих колонках.
ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтрокаТаблицыИсточника, СтрокаСовпадающихКолонок);
//Для каждого ЭлементМассива Из МассивСовпадающихКолонок Цикл
// СтрокаТаблицыПриемника[ЭлементМассива] = СтрокаТаблицыИсточника[ЭлементМассива];
//КонецЦикла;
Если СтруктураНовыхЗначений <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураНовыхЗначений);
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ЗагрузитьВТаблицуЗначенийЛкс()
// Непростетирована. Добавляет в дерево значений строки из другой таблицы значений и
// в них значения колонок с совпадающими наименованиями.
//
// Параметры:
// ТаблицаИсточник - таблица значений, откуда берутся значения;
// ТаблицаПриемник - таблица значений, куда добавляются строки;
// *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк;
// *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет.
//
Процедура ЗагрузитьВДеревоЗначенийЛкс(ДеревоИсточник, ДеревоПриемник,
СтруктураЗначенийПоУмолчанию = Неопределено, СтруктураНовыхЗначений = Неопределено) Экспорт
СтрокаСовпадающихКолонок = "";
Разделитель = ",";
КолонкиИсточника = ДеревоИсточник.Колонки;
Для каждого Колонка Из ДеревоПриемник.Колонки Цикл
Если СтруктураНовыхЗначений <> Неопределено Тогда
Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено Тогда
СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя;
КонецЕсли;
КонецЦикла;
СтрокаСовпадающихКолонок = Сред(СтрокаСовпадающихКолонок, СтрДлина(Разделитель) + 1);
ЗагрузитьВСтрокиДереваЗначенийЛкс(ДеревоИсточник, ДеревоПриемник, СтруктураЗначенийПоУмолчанию,
СтруктураНовыхЗначений, СтрокаСовпадающихКолонок);
КонецПроцедуры // ЗагрузитьВДеревоЗначенийЛкс()
// Непростетирована. Добавляет в дерево значений строки из другой таблицы значений и
// в них значения колонок с совпадающими наименованиями.
//
// Параметры:
// ТаблицаИсточник - таблица значений, откуда берутся значения;
// ТаблицаПриемник - таблица значений, куда добавляются строки;
// *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк;
// *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет.
//
Процедура ЗагрузитьВСтрокиДереваЗначенийЛкс(СтрокаРодительИсточника, СтрокаРодительПриемника,
СтруктураЗначенийПоУмолчанию, СтруктураНовыхЗначений, СтрокаСовпадающихКолонок) Экспорт
СтрокиПриемника = СтрокаРодительПриемника.Строки;
Для каждого СтрокаИсточника Из СтрокаРодительИсточника.Строки Цикл
СтрокаПриемника = СтрокиПриемника.Добавить();
Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтруктураЗначенийПоУмолчанию);
КонецЕсли;
// Заполним значения в совпадающих колонках.
ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтрокаИсточника, СтрокаСовпадающихКолонок);
Если СтруктураНовыхЗначений <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтруктураНовыхЗначений);
КонецЕсли;
ЗагрузитьВСтрокиДереваЗначенийЛкс(СтрокаИсточника, СтрокаПриемника, СтруктураЗначенийПоУмолчанию,
СтруктураНовыхЗначений, СтрокаСовпадающихКолонок);
КонецЦикла;
КонецПроцедуры // ЗагрузитьВДеревоЗначенийЛкс()
// Выводит сообщение пользователю. Способ вывода определяется модальным режимом.
// В модальном режиме используется Предупреждение(), в немодальном Сообщить().
//
// Параметры:
// ТекстСообщения – Строка;
// МодальныйРежим – Булево, *Ложь;
// *Статус - СтатусСообщения, *Неопределено.
//
Процедура СообщитьСУчетомМодальностиЛкс(ТекстСообщения, МодальныйРежим = Ложь, Статус = Неопределено) Экспорт
Если Статус = Неопределено Тогда
Статус = СтатусСообщения.Обычное;
КонецЕсли;;
#Если Клиент Тогда
Если МодальныйРежим Тогда
Предупреждение(ТекстСообщения);
Иначе
#КонецЕсли
Сообщить(ТекстСообщения, Статус);
#Если Клиент Тогда
КонецЕсли;
#КонецЕсли
КонецПроцедуры // СообщитьСУчетомМодальностиЛкс()
// Сообщает итог индикации (длительность).
//
// Параметры:
// Индикатор – Структура – индикатора, полученная методом ПолучитьИндикаторПроцессаЛкс.
//
Процедура СообщитьИтогИндикацииЛкс(Индикатор) Экспорт
ТекущаяДата = ТекущаяДата();
ПрошлоВремени = ТекущаяДата - Индикатор.ДатаНачалаПроцесса;
//Часов = Цел(ПрошлоВремени / 3600);
//Осталось = ПрошлоВремени - (Часов * 3600);
//Минут = Цел(ПрошлоВремени / 60);
//Секунд = Цел(Цел(ПрошлоВремени - (Минут * 60)));
//ПрошлоВремениСтрока = Формат(Часов, "ЧЦ=2; ЧН=00; ЧВН=") + ":"
// + Формат(Минут, "ЧЦ=2; ЧН=00; ЧВН=") + ":"
// + Формат(Секунд, "ЧЦ=2; ЧН=00; ЧВН=");
ПрошлоВремениСтрока = формат(Дата(1,1,1) + ПрошлоВремени, "ДЛФ=T; ДП=");
ТекстСообщения = Индикатор.ПредставлениеПроцесса + " завершено, обработано " + Индикатор.Счетчик + " элементов за " + ПрошлоВремениСтрока + " (" + ПрошлоВремени + " сек).";
Если Индикатор.Счетчик > 0 Тогда
ТекстСообщения = ТекстСообщения + " Грубое среднее время обработки элемента - " + Формат(ПрошлоВремени / Индикатор.Счетчик * 1000, "ЧЦ=15; ЧДЦ=2; ЧН=") + " мс";
КонецЕсли;
Сообщить(ТекстСообщения);
КонецПроцедуры // ОбработатьИндикаторЛкс()
// Получает более подробное представление значения, чем штатное приведение к строковому типу.
//
// Параметры:
// Значение – Произвольный – что нужно представить.
//
// Возвращаемое значение:
// Строка – представление.
//
Функция РасширенноеПредставлениеЗначенияЛкс(Значение, КолонкаТабличногоПоля = Неопределено, ДобавлятьПредставлениеТипа = Ложь, РасширенноеПредставлениеХранилищЗначений = Ложь) Экспорт
Результат = "";
Разделитель = ", ";
КоличествоЭлементов = ПолучитьКоличествоЭлементовКоллекцииЛкс(Значение);
Если КоличествоЭлементов <> Неопределено Тогда
Результат = "(" + КоличествоЭлементов + ")";
КонецЕсли;
Если ТипЗнч(Значение) = Тип("Граница") Тогда
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + Значение.ВидГраницы + ", " + Значение.Значение;
ИначеЕсли ЛиТипСсылкиТочкиМаршрутаЛкс(ТипЗнч(Значение)) Тогда
Результат = "" + Значение;
Если Не ЗначениеЗаполнено(Результат) Тогда
Результат = "(" + Значение.Имя + ")";
КонецЕсли;
ИначеЕсли ТипЗнч(Значение) = Тип("ОписаниеТипов") Тогда
#Если Сервер И Не Сервер Тогда
Значение = Новый ОписаниеТипов;
#КонецЕсли
ПредставлениеКоллекции = "";
МаксимальноеЧислоДляПредставления = 20;
Коллекция = Значение.Типы();
Для Каждого Тип Из Коллекция Цикл
Если ПредставлениеКоллекции <> "" Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель;
КонецЕсли;
ПредставлениеКоллекции = ПредставлениеКоллекции + ПредставлениеТипаЛкс(Тип, Значение);
МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1;
Если МаксимальноеЧислоДляПредставления = 0 Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "...";
Прервать;
КонецЕсли;
КонецЦикла;
Если Коллекция.Количество() > 1 Тогда
Результат = "(" + XMLСтрока(Коллекция.Количество()) + ")";
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
КонецЕсли;
Результат = Результат + ПредставлениеКоллекции;
ИначеЕсли Ложь
Или ТипЗнч(Значение) = Тип("Массив")
Или ТипЗнч(Значение) = Тип("ФиксированныйМассив")
Или ТипЗнч(Значение) = Тип("СписокЗначений")
Тогда
ПредставлениеКоллекции = "";
МаксимальноеЧислоДляПредставления = 20;
Для Каждого ЭлементМассива Из Значение Цикл
Если ПредставлениеКоллекции <> "" Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель;
КонецЕсли;
ПредставлениеКоллекции = ПредставлениеКоллекции + ЭлементМассива;
МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1;
Если МаксимальноеЧислоДляПредставления = 0 Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "...";
Прервать;
КонецЕсли;
КонецЦикла;
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + ПредставлениеКоллекции;
ИначеЕсли Ложь
Или ТипЗнч(Значение) = Тип("Структура")
Или ТипЗнч(Значение) = Тип("Соответствие")
Тогда
ПредставлениеКоллекции = "";
МаксимальноеЧислоДляПредставления = 20;
Для Каждого КлючИЗначение Из Значение Цикл
Если ПредставлениеКоллекции <> "" Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель;
КонецЕсли;
ПредставлениеКоллекции = ПредставлениеКоллекции + КлючИЗначение.Ключ + " = " + КлючИЗначение.Значение;
МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1;
Если МаксимальноеЧислоДляПредставления = 0 Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "...";
Прервать;
КонецЕсли;
КонецЦикла;
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + ПредставлениеКоллекции;
ИначеЕсли ТипЗнч(Значение) = Тип("COMОбъект") Тогда
ирПлатформа = ирКэш.Получить();
ИмяОбщегоТипа = ирПлатформа.ПолучитьПолноеИмяТипаCOMОбъекта(Значение);
ПолноеИмяОсновногоКласса = ПолучитьСтрокуМеждуМаркерамиЛкс(ИмяОбщегоТипа, "{", "}", Ложь);
ИмяОбщегоТипа = СтрЗаменить(ИмяОбщегоТипа, ".{" + ПолноеИмяОсновногоКласса + "}", "");
Результат = Результат + ИмяОбщегоТипа;
ИначеЕсли Истина
И РасширенноеПредставлениеХранилищЗначений
И ТипЗнч(Значение) = Тип("ХранилищеЗначения")
Тогда
Результат = Результат + ТипЗнч(Значение);
ВложенноеЗначение = Значение.Получить();
Результат = Результат + ": " + ВложенноеЗначение;
ИначеЕсли ТипЗнч(Значение) = Тип("Файл") Тогда
Результат = Результат + ТипЗнч(Значение);
Результат = Результат + ": " + Значение.ПолноеИмя;
//ИначеЕсли ТипЗнч(Значение) = Тип("Строка") Тогда
// Результат = Результат + """" + Значение + """";
Иначе
СтрокаФормата = "";
Если КолонкаТабличногоПоля <> Неопределено Тогда
СтрокаФормата = КолонкаТабличногоПоля.Формат;
// Отключено из-за потери дробной части при 0,0. Зачем это было сделано изначально, пока не разобрался
//Если Истина
// И ПустаяСтрока(СтрокаФормата)
// И ТипЗнч(КолонкаТабличногоПоля.ЭлементУправления) = Тип("ПолеВвода")
//Тогда
// КвалификаторыЧисла = КолонкаТабличногоПоля.ЭлементУправления.ТипЗначения.КвалификаторыЧисла;
// СтрокаФормата = "ЧЦ = " + КвалификаторыЧисла.Разрядность + "; ЧДЦ = " + КвалификаторыЧисла.РазрядностьДробнойЧасти;
//КонецЕсли;
КонецЕсли;
Результат = Результат + Формат(Значение, СтрокаФормата);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПредставлениеТипаЛкс(Знач Тип, Знач ОписаниеТипов = Неопределено, ИспользоватьИмя = Ложь)
Если ИспользоватьИмя Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзКонкретногоТипа(Тип);
ПредставлениеТипа = мПлатформа.ПолучитьСтрокуКонкретногоТипа(СтруктураТипа);
Иначе
ПредставлениеТипа = "" + Тип;
КонецЕсли;
Если ОписаниеТипов <> Неопределено Тогда
Если Тип = Тип("Число") Тогда
ПредставлениеТипа = ПредставлениеТипа + "(" + ОписаниеТипов.КвалификаторыЧисла.Разрядность + "," + ОписаниеТипов.КвалификаторыЧисла.РазрядностьДробнойЧасти + ")";
ИначеЕсли Тип = Тип("Строка") Тогда
ПредставлениеТипа = ПредставлениеТипа + "(" + XMLСтрока(ОписаниеТипов.КвалификаторыСтроки.Длина) + ")";
ИначеЕсли Тип = Тип("Дата") Тогда
Если ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Время Тогда
ПредставлениеКвалификатора = "В";
ИначеЕсли ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда
ПредставлениеКвалификатора = "ДВ";
ИначеЕсли ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Дата Тогда
ПредставлениеКвалификатора = "Д";
КонецЕсли;
ПредставлениеТипа = ПредставлениеТипа + "(" + ПредставлениеКвалификатора + ")";
КонецЕсли;
КонецЕсли;
Возврат ПредставлениеТипа;
КонецФункции // ЛксПолучитьПредставлениеЗначение()
// Сравнивает значения свойств объекта <Первый> со значениями свойств объекта <Второй>. Сопоставление производится по именам свойств.
// Отсутствие свойства приравнивается к значению Неопределено.
//
// Параметры:
// Первый – Произвольный – первый объект для сравнения;
// Второй – Произвольный – первый объект для сравнения;
// СвойстваДляСравнения - Строка - перечисленные через запятую свойства для сравнения.
//
// Возвращаемое значение:
// Булево – Равны ли значения всех указанных свойств.
//
Функция СравнитьЗначенияСвойствЛкс(Первый, Второй, СвойстваДляСравнения) Экспорт
Структура1 = Новый Структура(СвойстваДляСравнения);
ЗаполнитьЗначенияСвойств(Структура1, Первый);
Структура2 = Новый Структура(СвойстваДляСравнения);
ЗаполнитьЗначенияСвойств(Структура2, Второй);
Результат = ЗначениеВСтрокуВнутр(Структура1) = ЗначениеВСтрокуВнутр(Структура2);
Возврат Результат;
КонецФункции // СравнитьЗначенияСвойствЛкс()
#Если Клиент Тогда
Процедура ИзменитьОтборКлиентаПоМетаданнымЛкс(ТабличноеПоле, Знач ИмяКолонкиСреднегоИмениМД = "Метаданные", ЭтоКолонкаПолногоИмениМД = Ложь) Экспорт
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
лСтруктураПараметров.Вставить("ОтображатьРегистры", Истина);
лСтруктураПараметров.Вставить("ОтображатьПерерасчеты", Истина);
лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина);
лСтруктураПараметров.Вставить("ОтображатьТабличныеЧасти", Истина);
лСтруктураПараметров.Вставить("ОтображатьКонстанты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", Истина);
лСтруктураПараметров.Вставить("ОтображатьРегламентныеЗадания", Истина);
лСтруктураПараметров.Вставить("ОтображатьОтчеты", Истина);
лСтруктураПараметров.Вставить("ОтображатьОбработки", Истина);
лСтруктураПараметров.Вставить("ОтображатьПоследовательности", Истина);
лСтруктураПараметров.Вставить("МножественныйВыбор", Истина);
лДоступныеОбъекты = ТабличноеПоле.Значение.Выгрузить();
лДоступныеОбъекты.Свернуть(ИмяКолонкиСреднегоИмениМД);
лДоступныеОбъекты = лДоступныеОбъекты.ВыгрузитьКолонку(ИмяКолонкиСреднегоИмениМД);
Если ЭтоКолонкаПолногоИмениМД Тогда
ДоступныеОбъекты = Новый Массив;
Для Каждого ПолноеИмяМД Из лДоступныеОбъекты Цикл
СреднееИмяМД = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
ДоступныеОбъекты.Добавить(СреднееИмяМД);
КонецЦикла;
Иначе
//лСтруктураПараметров.Вставить("ОтображатьВиртуальныеТаблицы", Истина);
//лСтруктураПараметров.Вставить("ОтображатьТаблицыИзменений", Истина);
ДоступныеОбъекты = лДоступныеОбъекты;
КонецЕсли;
ЭлементОтбора = ТабличноеПоле.ОтборСтрок[ИмяКолонкиСреднегоИмениМД];
Если Истина
И ЭлементОтбора.Использование
И ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке
Тогда
лНачальноеЗначениеВыбора = ЭлементОтбора.Значение.ВыгрузитьЗначения();
Если ЭтоКолонкаПолногоИмениМД Тогда
НачальноеЗначениеВыбора = Новый Массив;
Для Каждого ПолноеИмяМД Из лНачальноеЗначениеВыбора Цикл
СреднееИмяМД = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
НачальноеЗначениеВыбора.Добавить(СреднееИмяМД);
КонецЦикла;
Иначе
НачальноеЗначениеВыбора = лНачальноеЗначениеВыбора;
КонецЕсли;
Иначе
НачальноеЗначениеВыбора = ДоступныеОбъекты;
КонецЕсли;
мПлатформа = ирКэш.Получить();
Форма = мПлатформа.ПолучитьФорму("ВыборОбъектаМетаданных");
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора);
лСтруктураПараметров.Вставить("ДоступныеОбъекты", ДоступныеОбъекты);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
ЗначениеВыбора = Форма.ОткрытьМодально();
Если ЗначениеВыбора <> Неопределено Тогда
Если ЭтоКолонкаПолногоИмениМД Тогда
ТаблицаВсехТаблицБД = ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс();
МассивИменМД = Новый Массив;
Для Каждого СреднееИмяМД Из ЗначениеВыбора Цикл
СтрокаОписанияТаблицы = ТаблицаВсехТаблицБД.Найти(СреднееИмяМД, "ПолноеИмя");
Если СтрокаОписанияТаблицы <> Неопределено Тогда
МассивИменМД.Добавить(СтрокаОписанияТаблицы.ПолноеИмяМД);
Иначе
МассивИменМД.Добавить(СреднееИмяМД);
КонецЕсли;
КонецЦикла;
Иначе
МассивИменМД = ЗначениеВыбора;
КонецЕсли;
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(МассивИменМД);
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке;
ЭлементОтбора.Значение = СписокЗначений;
ЭлементОтбора.Использование = Истина;
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьДиалогЗаменыИдентификаторовОбъектовЛкс(Знач Объекты) Экспорт
ФормаОбработки = ирОбщий.ПолучитьФормуЛкс("Обработка.ирПоискДублейИЗаменаСсылок.Форма");
Дерево = Новый ДеревоЗначений;
Дерево.Колонки.Добавить("Объект");
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Объекты.Количество(), "Создание дублей объектов");
НачатьТранзакцию();
Попытка
Для Каждого Объект Из Объекты Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КопияОбъекта = Объект.Ссылка.ПолучитьОбъект();
ирОбщий.ЗаменитьИдентификаторОбъектаЛкс(КопияОбъекта);
Попытка
КопияОбъекта.ОбменДанными.Загрузка = Истина;
Исключение
Сообщить("Для узлов планов обмена групповая замена внутренних идентификаторов не поддерживается");
Возврат;
КонецПопытки;
КопияОбъекта.Записать();
СтрокаГруппы = Дерево.Строки.Добавить();
СтрокаЭлемента = СтрокаГруппы.Строки.Добавить();
СтрокаЭлемента[0] = КопияОбъекта.Ссылка;
СтрокаЭлемента = СтрокаГруппы.Строки.Добавить();
СтрокаЭлемента[0] = Объект;
КонецЦикла;
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
ЗафиксироватьТранзакцию();
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
ФормаОбработки.ОткрытьДляЗаменыПоДеревуСсылок(Дерево,, Ложь);
ФормаОбработки.ОтключатьКонтрольЗаписи = Истина;
ФормаОбработки.РазрешитьУдалениеСНарушениемСсылочнойЦелостности = Ложь;
КонецПроцедуры // ПередОткрытием()
// Оформляет ячейку табличного поля, допускающую значения, не имеющие стандартного отображения в платформе и хранимые отдельно.
// Иными словам колонка отображает данные, хранимые отдельно.
//
// Параметры:
// ОформлениеЯчейки – ОформлениеЯчейки
// Значение - Произвольный - значение для отображения.
//
Процедура ОформитьЯчейкуСРасширеннымЗначениемЛкс(ОформлениеЯчейки, Знач Значение = Неопределено, КолонкаТабличногоПоля = Неопределено, ВыводитьПиктограммуТипа = Истина) Экспорт
Если Значение = Неопределено Тогда
Значение = ОформлениеЯчейки.Значение;
КонецЕсли;
Если ВыводитьПиктограммуТипа Тогда
ТипЗначения = ТипЗнч(Значение);
Если Истина
И ТипЗначения = Тип("Булево")
И ОформлениеЯчейки.ОтображатьФлажок
Тогда
//
Иначе
КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения);
Если КартинкаТипа <> Неопределено Тогда
ОформлениеЯчейки.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
РасширенноеПредставление = РасширенноеПредставлениеЗначенияЛкс(Значение, КолонкаТабличногоПоля);
Если Ложь
Или ОформлениеЯчейки.Текст = РасширенноеПредставление
Тогда
Возврат;
КонецЕсли;
//ОформлениеЯчейки.ТолькоПросмотр = Истина;
//ОформлениеЯчейки.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаРасширенногоПредставленияЗначения");
ОформлениеЯчейки.УстановитьТекст(РасширенноеПредставление);
КонецПроцедуры // ОформитьЯчейкуСРасширеннымЗначениемЛкс()
// Находит файлы в иерархии заданного каталога локальной файловой системы.
//
// Параметры:
// Путь – Строка;
// Маска – Строка.
//
// Возвращаемое значение:
// Массив – элементы типа Файл.
//
Функция НайтиФайлыВИерархииЛкс(Путь, Маска) Экспорт
НайденныеКаталоги = НайтиФайлы(Путь, "*.*");
МассивРезультатов = Новый Массив;
Для каждого НайденныйФайл Из НайденныеКаталоги Цикл
Если НайденныйФайл.ЭтоКаталог() Тогда
МассивРезультатов.Добавить(НайтиФайлыВИерархииЛкс(НайденныйФайл.ПолноеИмя, Маска));
КонецЕсли;
КонецЦикла;
МассивРезультатов.Добавить(НайтиФайлы(Путь, Маска));
Результат = Новый Массив;
Для Каждого ЭлементРезультат Из МассивРезультатов Цикл
Для Каждого Файл Из ЭлементРезультат Цикл
Результат.Добавить(Файл);
КонецЦикла;
КонецЦикла;
Возврат Результат;
КонецФункции // НайтиФайлыВИерархииЛкс()
// Проверяет, является ли тип типом элемента формы.
//
// Параметры:
// пТип – Тип – проверяемый тип.
//
// Возвращаемое значение:
// Истина – тип элемента формы подтвержден;
// Ложь – тип элемента формы не подтвержден.
//
Функция ЛиТипЭлементаФормыЛкс(пТип) Экспорт
Если Ложь
ИЛИ пТип = Тип("Индикатор")
ИЛИ пТип = Тип("Кнопка")
ИЛИ пТип = Тип("КоманднаяПанель")
ИЛИ пТип = Тип("Надпись")
ИЛИ пТип = Тип("Панель")
ИЛИ пТип = Тип("Переключатель")
ИЛИ пТип = Тип("ПолеВвода")
ИЛИ пТип = Тип("ПолеВыбора")
ИЛИ пТип = Тип("ПолеСписка")
ИЛИ пТип = Тип("ПолеТекстовогоДокумента")
ИЛИ пТип = Тип("ПолеТабличногоДокумента")
ИЛИ пТип = Тип("ПолосаРегулирования")
ИЛИ пТип = Тип("ТабличноеПоле")
ИЛИ пТип = Тип("РамкаГруппы")
ИЛИ пТип = Тип("Флажок")
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиТипЭлементаФормыЛкс()
// Получает структуру свойств объекта по имени типа или объекту.
// Свойства должны располагаться в порядке:
// - общие,
// - ролевые в порядке невлияния на предшествующие.
//
// Параметры:
// пОбъект - Произвольный - имя типа или сам объект;
// пЛиДляСохранения - Булево, *Ложь - признак получения свойств для сохранения.
//
// Возвращаемое значение:
// – Структура – свойств.
//
Функция ПолучитьСтруктуруСвойствОбъектаЛкс(пОбъект, пЛиДляСохранения = Ложь) Экспорт
СтруктураСвойств = Новый Структура;
ТипОбъекта = ТипЗнч(пОбъект);
МетаОбъект = ПолучитьМетаданныеЛкс(ТипОбъекта);
Если МетаОбъект <> Неопределено Тогда
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(МетаОбъект, Истина);
Если Ложь
ИЛИ КорневойТип = "Обработка"
ИЛИ КорневойТип = "Отчет"
Тогда
Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
Для Каждого МетаРеквизит Из МетаОбъект.ТабличныеЧасти Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
КонецЕсли;
Если ПолучитьКорневойТипСтрокиТабличнойЧастиЛкс(ТипОбъекта) <> Неопределено Тогда
Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
КонецЕсли;
Если Истина
И ТипОбъекта <> Тип("Тип")
И ТипОбъекта <> Тип("ОписаниеТипов")
И ТипОбъекта <> Тип("ОбъектМетаданных")
Тогда
Если ПолучитьКорневойТипСпискаЛкс(ТипОбъекта) <> Неопределено Тогда
СтруктураСвойств.Вставить("Колонки");
СтруктураСвойств.Вставить("Порядок");
СтруктураСвойств.Вставить("Отбор");
ИначеЕсли ЛиНаборЗаписейРегистраЛкс(ТипОбъекта) Тогда
СтруктураСвойств.Вставить("Отбор");
КонецЕсли;
КонецЕсли;
//ИначеЕсли Ложь
// ИЛИ ТипОбъекта = Тип("КнопкиКоманднойПанели")
// ИЛИ ТипОбъекта = Тип("КолонкиТабличногоПоля")
// ИЛИ ТипОбъекта = Тип("СтраницыПанели")
// ИЛИ ТипОбъекта = Тип("ЭлементыФормы")
// ИЛИ ТипОбъекта = Тип("ПоляНастройки")
//Тогда
// Для Каждого Элемент Из пОбъект Цикл
// СтруктураСвойств.Вставить(Элемент.Имя);
// КонецЦикла;
//
ИначеЕсли Ложь
Или ТипОбъекта = Тип("СтрокаТаблицыЗначений")
Или ТипОбъекта = Тип("СтрокаДереваЗначений")
Тогда
Для Каждого МетаРеквизит Из пОбъект.Владелец().Колонки Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
ИначеЕсли ЛиТипЭлементаФормыЛкс(ТипОбъекта) Тогда
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("Видимость");
СтруктураСвойств.Вставить("ИзменяетДанные");
СтруктураСвойств.Вставить("ПервыйВГруппе");
СтруктураСвойств.Вставить("ПропускатьПриВводе");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("КонтекстноеМеню");
Если НЕ пЛиДляСохранения Тогда
СтруктураСвойств.Вставить("Лево");
СтруктураСвойств.Вставить("Верх");
СтруктураСвойств.Вставить("Высота");
СтруктураСвойств.Вставить("Ширина");
КонецЕсли;
СтруктураСвойств.Вставить("Подсказка");
СтруктураСвойств.Вставить("ПорядокОбхода");
СтруктураСвойств.Вставить("ПорядокОтображения");
СтруктураСвойств.Вставить("ПрозрачныйФон");
СтруктураСвойств.Вставить("Рамка");
Если ТипОбъекта = Тип("Кнопка") Тогда
СтруктураСвойств.Вставить("РежимМеню");
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("МногострочныйРежим");
СтруктураСвойств.Вставить("ПоложениеКартинки");
СтруктураСвойств.Вставить("РазмерКартинки");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаКнопки");
СтруктураСвойств.Вставить("ЦветФонаКнопки");
СтруктураСвойств.Вставить("Шрифт");
СтруктураСвойств.Вставить("Кнопки");
ИначеЕсли ТипОбъекта = Тип("КоманднаяПанель") Тогда
СтруктураСвойств.Вставить("АвтоЗаполнение");
СтруктураСвойств.Вставить("Вспомогательная");
СтруктураСвойств.Вставить("ВыравниваниеКнопок");
СтруктураСвойств.Вставить("ИсточникДействий");
СтруктураСвойств.Вставить("Кнопки");
СтруктураСвойств.Вставить("Ориентация");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаКнопки");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("ЦветФонаКнопки");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Надпись") Тогда
СтруктураСвойств.Вставить("БегущаяСтрока");
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("ВыделятьОтрицательные");
СтруктураСвойств.Вставить("ГиперСсылка");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("ПоложениеКартинкиНадписи");
СтруктураСвойств.Вставить("РазмерКартинки");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("Формат");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Панель") Тогда
СтруктураСвойств.Вставить("Страницы");
СтруктураСвойств.Вставить("АвтоПорядокОбхода");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("ОтображениеЗакладок");
СтруктураСвойств.Вставить("ПорядокОбхода");
СтруктураСвойств.Вставить("РазмерКартинки");
СтруктураСвойств.Вставить("РаспределятьПоСтраницам");
СтруктураСвойств.Вставить("РежимПрокручиваемыхСтраниц");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("ТекущаяСтраница");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Переключатель") Тогда
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("ВыбираемоеЗначение");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("ПоложениеЗаголовка");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("ПолеВвода") Тогда
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ОграничениеТипа");
СтруктураСвойств.Вставить("КнопкаВыбора");
СтруктураСвойств.Вставить("РежимВыбораИзСписка");
СтруктураСвойств.Вставить("КнопкаСпискаВыбора");
СтруктураСвойств.Вставить("СписокВыбора");
СтруктураСвойств.Вставить("АвтоВыборНезаполненного");
СтруктураСвойств.Вставить("АвтоОтметкаНезаполненного");
СтруктураСвойств.Вставить("АвтоПереносСтрок");
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("БыстрыйВыбор");
СтруктураСвойств.Вставить("ВыбиратьТип");
СтруктураСвойств.Вставить("ВыборГруппИЭлементов");
СтруктураСвойств.Вставить("ВыборНезаполненного");
СтруктураСвойств.Вставить("ВыборПоВладельцу");
СтруктураСвойств.Вставить("ВыделенныйТекст");
СтруктураСвойств.Вставить("ВыделятьОтрицательные");
СтруктураСвойств.Вставить("ВысотаСпискаВыбора");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("КартинкаКнопкиВыбора");
СтруктураСвойств.Вставить("КнопкаОткрытия");
СтруктураСвойств.Вставить("КнопкаОчистки");
СтруктураСвойств.Вставить("КнопкаРегулирования");
СтруктураСвойств.Вставить("МаксимальноеЗначение");
СтруктураСвойств.Вставить("Маска");
СтруктураСвойств.Вставить("МинимальноеЗначение");
СтруктураСвойств.Вставить("МногострочныйРежим");
СтруктураСвойств.Вставить("ОтметкаНезаполненного");
СтруктураСвойств.Вставить("РасширенноеРедактирование");
СтруктураСвойств.Вставить("РедактированиеТекста");
СтруктураСвойств.Вставить("РежимВыбораНезаполненного");
СтруктураСвойств.Вставить("РежимПароля");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("Формат");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаКнопки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаКнопки");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("ШиринаСпискаВыбора");
СтруктураСвойств.Вставить("Шрифт");
СтруктураСвойств.Вставить("ЭлементСвязиПоТипу");
СтруктураСвойств.Вставить("Значение");
ИначеЕсли ТипОбъекта = Тип("ПолеВыбора") Тогда
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ВысотаСпискаВыбора");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("КартинкаКнопкиВыбора");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("КнопкаВыбора");
СтруктураСвойств.Вставить("КнопкаОткрытия");
СтруктураСвойств.Вставить("КнопкаОчистки");
СтруктураСвойств.Вставить("КнопкаРегулирования");
СтруктураСвойств.Вставить("СписокВыбора");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("ШиринаСпискаВыбора");
СтруктураСвойств.Вставить("Значение");
ИначеЕсли ТипОбъекта = Тип("ПолеСписка") Тогда
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ОтображатьКартинку");
СтруктураСвойств.Вставить("ОтображатьПометку");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ТекущаяСтрока");
ИначеЕсли ТипОбъекта = Тип("ТабличноеПоле") Тогда
// **** Доделать
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("АвтоВводНовойСтроки");
СтруктураСвойств.Вставить("АвтоКонтекстноеМеню");
СтруктураСвойств.Вставить("АвтоОбновление");
СтруктураСвойств.Вставить("АктивизироватьПоУмолчанию");
СтруктураСвойств.Вставить("ВосстанавливатьТекущуюСтроку");
СтруктураСвойств.Вставить("Дерево");
СтруктураСвойств.Вставить("ИерархическийПросмотр");
СтруктураСвойств.Вставить("ИзменятьАвтоОбновление");
СтруктураСвойств.Вставить("ИзменятьИерархическийПросмотр");
СтруктураСвойств.Вставить("ИзменятьСпособРедактирования");
СтруктураСвойств.Вставить("ИзменятьТекущегоРодителя");
СтруктураСвойств.Вставить("ПериодАвтоОбновления");
СтруктураСвойств.Вставить("ПроверкаОтображенияНовойСтроки");
СтруктураСвойств.Вставить("РодительВерхнегоУровня");
СтруктураСвойств.Вставить("РежимВыбора");
СтруктураСвойств.Вставить("РежимВыделения");
СтруктураСвойств.Вставить("РежимВыделенияСтроки");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("СпособРедактирования");
СтруктураСвойств.Вставить("ТекущийРодитель");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("Колонки");
СтруктураСвойств.Вставить("НастройкаОтбора");
СтруктураСвойств.Вставить("НастройкаПорядка");
СтруктураСвойств.Вставить("ТекущаяКолонка");
СтруктураСвойств.Вставить("ТекущаяСтрока");
СтруктураСвойств.Вставить("ТекущиеДанные");
СтруктураСвойств.Вставить("ВыделенныеСтроки");
// ****
//ВертикальнаяПолосаПрокрутки
//ВертикальныеЛинии
//Вывод
//ВысотаПодвала
//ВысотаШапки
//ГоризонтальнаяПолосаПрокрутки
//ГоризонтальныеЛинии
//ИзменятьНастройкуКолонок
//ИзменятьПозициюКолонок
//ИзменятьПорядокСтрок
//ИзменятьСоставСтрок
//НачальноеОтображениеДерева
//НачальноеОтображениеСписка
//Подвал
//ПропускатьПриВводе
//РазрешитьНачалоПеретаскивания
//РазрешитьПеретаскивание
//РежимВводаСтрок
//ФиксацияСлева
//ФиксацияСправа
//ЦветТекста
//ЦветТекстаВыделения
//ЦветТекстаКнопки
//ЦветТекстаПодвала
//ЦветТекстаШапки
//ЦветФона
//ЦветФонаВыделения
//ЦветФонаКнопки
//ЦветФонаПодвала
//ЦветФонаЧередованияСтрок
//ЦветФонаШапки
//ЧередованиеЦветовСтрок
//Шапка
//Ширина
//Шрифт
//ШрифтПодвала
//ШрифтШапки
ИначеЕсли ТипОбъекта = Тип("ПолеТабличногоДокумента") Тогда
СтруктураСвойств.Вставить("ВертикальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("ГоризонтальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ОтображатьВыделение");
СтруктураСвойств.Вставить("РазрешитьНачалоПеретаскивания");
СтруктураСвойств.Вставить("РазрешитьПеретаскивание");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("ЦветРамки");
ИначеЕсли ТипОбъекта = Тип("РамкаГруппы") Тогда
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Флажок") Тогда
СтруктураСвойств.Вставить("ТриСостояния");
СтруктураСвойств.Вставить("ВертикальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("ГоризонтальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ПоложениеЗаголовка");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("ЦветФонаПоля");
КонецЕсли;
ИначеЕсли ТипОбъекта = Тип("КнопкаКоманднойПанели") Тогда
СтруктураСвойств.Вставить("ТипКнопки");
СтруктураСвойств.Вставить("Действие");
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("ИзменяетДанные");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("КнопкаПоУмолчанию");
СтруктураСвойств.Вставить("Кнопки");
СтруктураСвойств.Вставить("Отображение");
СтруктураСвойств.Вставить("Подсказка");
СтруктураСвойств.Вставить("Пометка");
СтруктураСвойств.Вставить("ПорядокКнопок");
СтруктураСвойств.Вставить("Пояснение");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("Текст");
ИначеЕсли ТипОбъекта = Тип("СтраницаПанели") Тогда
СтруктураСвойств.Вставить("Видимость");
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("КартинкаЗаголовка");
СтруктураСвойств.Вставить("Раскрыта");
ИначеЕсли ТипОбъекта = Тип("КолонкаТабличногоПоля") Тогда
СтруктураСвойств.Вставить("АвтоВысотаЯчейки");
СтруктураСвойств.Вставить("АвтоОтметкаНезаполненного");
СтруктураСвойств.Вставить("Видимость");
СтруктураСвойств.Вставить("ВыделятьОтрицательные");
СтруктураСвойств.Вставить("ВысотаЯчейки");
СтруктураСвойств.Вставить("ГиперСсылка");
СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВКолонке");
СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВПодвале");
СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВШапке");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ДанныеФлажка");
СтруктураСвойств.Вставить("ДополнительнаяКартинкаШапки");
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("КартинкаПодвала");
СтруктураСвойств.Вставить("КартинкаШапки");
СтруктураСвойств.Вставить("КартинкиСтрок");
СтруктураСвойств.Вставить("ОтображатьВПодвале");
СтруктураСвойств.Вставить("ОтображатьВШапке");
СтруктураСвойств.Вставить("ОтображатьИерархию");
СтруктураСвойств.Вставить("ПодсказкаВШапке");
СтруктураСвойств.Вставить("Положение");
СтруктураСвойств.Вставить("ПропускатьПриВводе");
СтруктураСвойств.Вставить("РежимРедактирования");
СтруктураСвойств.Вставить("ТекстПодвала");
СтруктураСвойств.Вставить("ТекстШапки");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("ТриСостоянияФлажка");
СтруктураСвойств.Вставить("Формат");
СтруктураСвойств.Вставить("ЦветТекстаПодвала");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветТекстаШапки");
СтруктураСвойств.Вставить("ЦветФонаПодвала");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("ЦветФонаШапки");
СтруктураСвойств.Вставить("Ширина");
СтруктураСвойств.Вставить("ШрифтПодвала");
СтруктураСвойств.Вставить("ШрифтТекста");
СтруктураСвойств.Вставить("ШрифтШапки");
СтруктураСвойств.Вставить("ЭлементУправления");
СтруктураСвойств.Вставить("ИзменениеРазмера");
СтруктураСвойств.Вставить("ИзменятьВидимость");
СтруктураСвойств.Вставить("ИзменятьНастройку");
СтруктураСвойств.Вставить("ИзменятьПозицию");
ИначеЕсли ТипОбъекта = Тип("Форма") Тогда
СтруктураСвойств.Вставить("АвтоЗаголовок");
СтруктураСвойств.Вставить("Высота");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("ЗакрыватьПриВыборе");
СтруктураСвойств.Вставить("ЗакрыватьПриЗакрытииВладельца");
СтруктураСвойств.Вставить("ИзменениеРазмера");
СтруктураСвойств.Вставить("ИзменятьСпособОтображенияОкна");
СтруктураСвойств.Вставить("ИмяСохраненияПоложенияОкна");
СтруктураСвойств.Вставить("КартинкаЗаголовка");
СтруктураСвойств.Вставить("КлючУникальности");
СтруктураСвойств.Вставить("МножественныйВыбор");
СтруктураСвойств.Вставить("Модифицированность");
СтруктураСвойств.Вставить("НачальноеЗначениеВыбора");
СтруктураСвойств.Вставить("Панель");
СтруктураСвойств.Вставить("ПоведениеКлавишиEnter");
СтруктураСвойств.Вставить("ПоложениеОкна");
СтруктураСвойств.Вставить("ПоложениеПрикрепленногоОкна");
СтруктураСвойств.Вставить("РазрешитьСоединятьОкно");
СтруктураСвойств.Вставить("РазрешитьСостояниеОбычное");
СтруктураСвойств.Вставить("РазрешитьСостояниеПрикрепленное");
СтруктураСвойств.Вставить("РазрешитьСостояниеПрячущееся");
СтруктураСвойств.Вставить("РазрешитьСостояниеСвободное");
СтруктураСвойств.Вставить("РежимВыбора");
СтруктураСвойств.Вставить("РежимРабочегоСтола");
СтруктураСвойств.Вставить("СоединяемоеОкно");
СтруктураСвойств.Вставить("СостояниеОкна");
СтруктураСвойств.Вставить("СпособОтображенияОкна");
СтруктураСвойств.Вставить("Стиль");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("Ширина");
СтруктураСвойств.Вставить("ЭлементыФормы");
СтруктураСвойств.Вставить("ТекущийЭлемент");
Если НЕ пЛиДляСохранения Тогда
СтруктураСвойств.Вставить("ВладелецФормы");
СтруктураСвойств.Вставить("МодальныйРежим");
КонецЕсли;
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ПостроительОтчета")
ИЛИ пОбъект = "ПостроительОтчета"
Тогда
СтруктураСвойств.Вставить("Текст");
СтруктураСвойств.Вставить("ДоступныеПоля");
СтруктураСвойств.Вставить("ВыбранныеПоля");
СтруктураСвойств.Вставить("ИзмеренияКолонки");
СтруктураСвойств.Вставить("ИзмеренияСтроки");
СтруктураСвойств.Вставить("Отбор");
СтруктураСвойств.Вставить("Параметры");
// не все
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ПолеНастройки")
ИЛИ пОбъект = "ПолеНастройки"
Тогда
СтруктураСвойств.Вставить("Измерение");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Отбор");
СтруктураСвойств.Вставить("Поле");
СтруктураСвойств.Вставить("Порядок");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
СтруктураСвойств.Вставить("СписокЗначений");
СтруктураСвойств.Вставить("ТипЗначения");
Если НЕ пЛиДляСохранения Тогда
СтруктураСвойств.Вставить("Поля");
СтруктураСвойств.Вставить("Родитель");
КонецЕсли;
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ИзмерениеПостроителяОтчета")
ИЛИ пОбъект = "ИзмерениеПостроителяОтчета"
Тогда
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
СтруктураСвойств.Вставить("ТипИзмерения");
// не все
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ПолеПостроителяОтчета")
ИЛИ пОбъект = "ПолеПостроителяОтчета"
Тогда
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ЭлементОтбора")
ИЛИ пОбъект = "ЭлементОтбора"
Тогда
СтруктураСвойств.Вставить("ВидСравнения");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ЗначениеПо");
СтруктураСвойств.Вставить("ЗначениеС");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Использование");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
СтруктураСвойств.Вставить("ТипЗначения");
КонецЕсли;
Возврат СтруктураСвойств;
КонецФункции // ПолучитьСтруктуруСвойствОбъектаЛкс()
// Сообщает об ошибке в тексте запроса и устанавливает выделение на ошибочную строку, если это возможно.
//
// Параметры:
// *ПолеТекстовогоДокумента - ПолеТекстовогоДокумента, *Неопределено;
// *СтартоваяСтрока - Число, *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 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НомерСтроки, 1, НомерСтроки, 1000);
КонецЕсли;
ТекстСообщения = ТекстСообщения + ПолучитьПредставлениеИзИдентификатораЛкс(ПолеТекстовогоДокумента.Имя) + ПредставлениеКонтекста;
ТекстСообщения = ТекстСообщения + ": " + ОписаниеОшибки;
ПолныйТекстСообщения = Вступление + ТекстСообщения;
Если ЛиМодально Тогда
Предупреждение(ТекстСообщения);
Иначе
Сообщить(ПолныйТекстСообщения, СтатусСообщения.Важное);
КонецЕсли;
Иначе
ПолныйТекстСообщения = Вступление + ТекстСообщения;
Если ЛиМодально Тогда
Предупреждение(ОписаниеОшибки);
Иначе
Сообщить(ПолныйТекстСообщения, СтатусСообщения.Важное);
КонецЕсли;
КонецЕсли;
Возврат ПолныйТекстСообщения;
КонецФункции
Функция ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(Знач ОписаниеОшибки, ЭтоПроизвольныйАлгоритм = Ложь, Знач ЛиМодально = Ложь) Экспорт
Результат = Ложь;
Если Истина
//И (Ложь
// Или Не ирКэш.ЛиПортативныйРежимЛкс()
// Или ирПортативный.ЛиСерверныйМодульДоступенЛкс())
И Найти(ОписаниеОшибки, "мутабельн") > 0
И Найти(ОписаниеОшибки, "Записать") > 0
Тогда
ТекстСообщения = "Чтобы избежать ошибки передачи мутабельного значения при записи объектов, используйте ";
Если ЭтоПроизвольныйАлгоритм Тогда
ТекстСообщения = ТекстСообщения + "функцию ""ирОбщий.ЗаписатьОбъектЛкс(Объект, Истина)""";
Иначе
ТекстСообщения = ТекстСообщения + "опцию ""Запись на сервере"" инструмента";
КонецЕсли;
Если ирКэш.ЛиПортативныйРежимЛкс() И Не ирПортативный.ЛиСерверныйМодульДоступенЛкс() Тогда
ТекстСообщения = ТекстСообщения + ", которая станет доступной после указания пользователя внешнего соединения в настройках инструментов";
КонецЕсли;
Если ЛиМодально Тогда
Предупреждение(ТекстСообщения);
Иначе
Сообщить(ТекстСообщения, СтатусСообщения.Внимание);
КонецЕсли;
Результат = Истина;
КонецЕсли;
Возврат Результат;
КонецФункции // ПоказатьОшибкуВЗапросеИлиПрограммномКодеЛкс()
// Рассчитыват и устанавливает ширину колонок табличного документа. Ориентирована на обработку
// результата построителя отчета.
//
// Параметры:
// ТабличныйДокумент – ТабличныйДокумент;
// *ЛиМинимальный – Булево, *Ложь – признак установки необходимой ширины, иначе достаточной;
// *ЛиИгнорироватьОбразание - Булево, *Ложь - признак игнорирования ячеек с обрезанием;
// *ШиринаОбластиПолей - Число, *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 Тогда
ЭлементОтбора = пПостроительОтчета.Отбор[ЭлементРасшифровки.Ключ];
Если ЭлементОтбора.ТипЗначения.СодержитТип(Тип("Строка")) Тогда
ЭлементОтбора.Значение = "<Отсутствует>";
Если ЭлементОтбора.ВидСравнения = ВидСравнения.ВИерархии Тогда
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
КонецЕсли;
Иначе
Сообщить("Запрос не поддерживает расшифровку по отсутствующему значению элемента отбора """ + ЭлементОтбора.Представление + """!");
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // УстановитьОтборПостроителяПриРасшифровкеЛкс()
// Получает копию построителя отчетов.
//
// Параметры:
// Оригинал – ПостроительОтчета.
//
// Возвращаемое значение:
// – <Тип.Вид> – <описание значения>
// <продолжение описания значения>;
// <Значение2> – <Тип.Вид> – <описание значения>
// <продолжение описания значения>.
//
Функция ПолучитьКопиюПостроителяОтчетаЛкс(Оригинал, ВосстанавливатьНастройки = Истина) Экспорт
Копия = Новый ПостроительОтчета;
Для Каждого ДоступноеПоле Из Оригинал.ДоступныеПоля Цикл
ЗаполнитьЗначенияСвойств(Копия.ДоступныеПоля.Добавить(ДоступноеПоле.Имя, ДоступноеПоле.Представление), ДоступноеПоле);
КонецЦикла;
Если ВосстанавливатьНастройки Тогда
Копия.Текст = Оригинал.Текст;
Копия.ЗаполнитьНастройки(); // Баг платформы. Без этого почему то иногда измерения не восстанавливаются!
Копия.УстановитьНастройки(Оригинал.ПолучитьНастройки());
КонецЕсли;
Возврат Копия;
КонецФункции // ПолучитьКопиюПостроителяОтчетаЛкс()
// Возвращает менеджер временных таблиц, в котором создана временная таблица по переданному источнику.
//
// Параметры:
// ВнешнийИсточник – ТаблицаЗначений;
// ИмяТаблицы – Строка;
// *МенеджерВременныхТаблиц – МенеджерВременныхТаблиц, *Неопределено.
//
// Возвращаемое значение:
// МенеджерВременныхТаблиц.
//
Функция ПолучитьВременнуюТаблицуЛкс(ВнешнийИсточник, ИмяТаблицы, МенеджерВременныхТаблиц = Неопределено) Экспорт
Если МенеджерВременныхТаблиц = Неопределено Тогда
МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
КонецЕсли;
ТекстВЫБРАТЬ = "";
Для Каждого Колонка Из ВнешнийИсточник.Колонки Цикл
ТекстВЫБРАТЬ = ТекстВЫБРАТЬ + ", " + Колонка.Имя;
КонецЦикла;
ТекстЗапроса = "ВЫБРАТЬ " + Сред(ТекстВЫБРАТЬ, 3);
ТекстЗапроса = ТекстЗапроса + " ПОМЕСТИТЬ " + ИмяТаблицы;
ТекстЗапроса = ТекстЗапроса + " ИЗ &ВнешнийИсточник КАК ВнешнийИсточник";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.УстановитьПараметр("ВнешнийИсточник", ВнешнийИсточник);
Запрос.Выполнить();
Возврат МенеджерВременныхТаблиц;
КонецФункции // ПолучитьВременнуюТаблицуЛкс()
Функция ПолучитьТекстСостоянияИндикатораЛкс(Индикатор) Экспорт
Счетчик = Индикатор.Счетчик;
Если Истина
И Индикатор.ЛиВыводитьВремя
И Счетчик > 0
И Счетчик < Индикатор.КоличествоПроходов
Тогда
ТекущаяДата = ТекущаяДата();
ПрошлоВремени = ТекущаяДата - Индикатор.ДатаНачалаПроцесса;
Осталось = ПрошлоВремени * (Индикатор.КоличествоПроходов / Счетчик - 1);
ОсталосьДней = Цел(Осталось / (24*60*60));
ТекстОсталось = ", Осталось: ~";
Если ОсталосьДней > 0 Тогда
ТекстОсталось = ТекстОсталось + ОсталосьДней + "д";
КонецЕсли;
ТекстОсталось = ТекстОсталось + формат(Дата(1,1,1) + Осталось, "ДЛФ=T");
Иначе
ТекстОсталось = "";
КонецЕсли;
Если Индикатор.КоличествоПроходов > 0 Тогда
ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": "
+ Формат(Счетчик / Индикатор.КоличествоПроходов * 100, "ЧЦ=3; ЧДЦ=0; ЧН=") + "%" + ТекстОсталось;
Иначе
ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Счетчик + " ";
КонецЕсли;
Возврат ТекстСостояния;
КонецФункции // ПолучитьТекстСостоянияИндикатораЛкс()
// Открывает справку по первой подсистеме метаданных переданного объекта
//
// Параметры:
// Объект - любой объект, имеющий метаданные.
//
Процедура ОткрытьСправкуПоПодсистемеЛкс(Объект = Неопределено) Экспорт
Если Ложь
Или ТипЗнч(Объект) = Тип("Неопределено")
Или ТипЗнч(Объект) = Тип("ОкноКлиентскогоПриложения")
Тогда
//
ИначеЕсли ТипЗнч(Объект) = Тип("Форма") Тогда
ПолноеИмяМД = ПолучитьДопСвойстваФормыЛкс(Объект).ИмяФормы;
ИначеЕсли ТипЗнч(Объект) = Тип("УправляемаяФорма") Тогда
ПолноеИмяМД = Объект.ИмяФормы;
Иначе
Если ТипЗнч(Объект) = Тип("Тип") Тогда
ОбъектМД = Метаданные.НайтиПоТипу(Объект);
Иначе
ОбъектМД = Объект.Метаданные();
КонецЕсли;
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ПолноеИмяМД = СтрЗаменить(ПолноеИмяМД, "ВнешняяОбработка.", "Обработка.");
ПолноеИмяМД = СтрЗаменить(ПолноеИмяМД, "ВнешнийОтчет.", "Отчет.");
КонецЕсли;
Форма = ирКэш.Получить().ПолучитьФорму("ОПодсистеме",, ПолноеИмяМД);
Форма.Открыть();
КонецПроцедуры // ОткрытьСправкуПоПодсистемеЛкс()
Процедура ПанельИнструментовОПодсистемеЛкс() Экспорт
ОткрытьСправкуПоПодсистемеЛкс();
КонецПроцедуры
// Открывает обработку ирПоискДублейИЗаменаСсылок и заполняет группы дублей по табличному полю, связанному с таблицой или деревом значений.
//
Процедура ОткрытьФормуЗаменыСсылокИзТабличногоПоляЛкс(ТабличноеПоле) Экспорт
Если ТабличноеПоле.ТекущаяКолонка = Неопределено Тогда
Возврат;
КонецЕсли;
ФормаОбработки = ПолучитьФормуЛкс("Обработка.ирПоискДублейИЗаменаСсылок.Форма");
Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений") Тогда
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
СписокВыбора = Новый СписокЗначений;
СписокВыбора.Добавить(0, "Создать группы дублей из пар неправильных значений текущей и правильных значений следующей колонок");
СписокВыбора.Добавить(1, "Создать одну группу дублей из значений текущей колонки выделенных строк");
//СписокВыбора.Добавить(2, "Создать правила замены значений из текущей колонки на значения следующей колонки");
ВыбранныйВариант = СписокВыбора.ВыбратьЭлемент("Выберите вариант");
Если ВыбранныйВариант = Неопределено Тогда
Возврат;
КонецЕсли;
Если ВыбранныйВариант.Значение = 1 Тогда
Если ВыделенныеСтроки.Количество() = 0 Тогда
Возврат ;
КонецЕсли;
ИмяКолонки = ТабличноеПоле.ТекущаяКолонка.Данные;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Возврат;
КонецЕсли;
МассивСсылок = Новый Массив;
Для Каждого Строка Из ВыделенныеСтроки Цикл
ЗначениеСтроки = Строка[ИмяКолонки];
ТипЗначения = ТипЗнч(ЗначениеСтроки);
Если Метаданные.НайтиПоТипу(ТипЗначения) = Неопределено Тогда
Продолжить;
КонецЕсли;
МассивСсылок.Добавить(ЗначениеСтроки);
КонецЦикла;
ФормаОбработки.ОткрытьДляЗаменыПоСпискуСсылок(МассивСсылок,, 0);
ИначеЕсли ВыбранныйВариант.Значение = 0 Тогда
ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка;
Если Ложь
Или ТекущаяКолонка = Неопределено
Или ТекущаяКолонка.Данные = ""
Тогда
Возврат;
КонецЕсли;
ИндексКолонки = ТабличноеПоле.Колонки.Индекс(ТекущаяКолонка);
Если ТабличноеПоле.Колонки.Количество() = ИндексКолонки + 1 Тогда
Возврат;
КонецЕсли;
СледующаяКолонка = ТабличноеПоле.Колонки[ИндексКолонки + 1];
Если СледующаяКолонка.Данные = "" Тогда
Возврат;
КонецЕсли;
ФормаОбработки.ОткрытьСЗаполнениемГруппДублейПоТаблицеПар(ТабличноеПоле.Значение, ТекущаяКолонка.Данные, СледующаяКолонка.Данные);
КонецЕсли;
ИначеЕсли ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда
ФормаОбработки.ОткрытьДляЗаменыПоДеревуСсылок(ТабличноеПоле.Значение, ТабличноеПоле.ТекущаяКолонка.Имя);
КонецЕсли;
КонецПроцедуры // ОткрытьФормуЗаменыСсылокИзТабличногоПоляЛкс()
////////////////////////////////////////////////////////////////////////////////
// ТЕХНОЛОГИЯ КОМПОНЕНТ
// Возвращает кнопку командной панели компоненты по ее имени из макета.
//
// Параметры:
// ОбъектКомпоненты - ОбработкаОбъект - компонента;
// КраткоеИмяКнопки – Строка - имя кнопки из макета компоненты;
// *КоманднаяПанель - КоманднаяПанель, *Неопределено - на случай, если у компоненты несколько командных панелей.
//
// Возвращаемое значение:
// Кнопка.
//
Функция ПолучитьКнопкуКоманднойПанелиЭкземпляраКомпонентыЛкс(ОбъектКомпоненты, КраткоеИмяКнопки,
Знач КоманднаяПанель = Неопределено) Экспорт
Если КоманднаяПанель = Неопределено Тогда
КоманднаяПанель = ОбъектКомпоненты.КоманднаяПанель;
КонецЕсли;
ПолноеИмяКнопки = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КраткоеИмяКнопки);
Кнопка = КоманднаяПанель.Кнопки.Найти(ПолноеИмяКнопки);
Если Кнопка = Неопределено Тогда
Для Каждого Подменю Из КоманднаяПанель.Кнопки Цикл
Если Подменю.ТипКнопки <> ТипКнопкиКоманднойПанели.Подменю Тогда
Продолжить;
КонецЕсли;
Кнопка = ПолучитьКнопкуКоманднойПанелиЭкземпляраКомпонентыЛкс(ОбъектКомпоненты, КраткоеИмяКнопки, Подменю);
Если Кнопка <> Неопределено Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Кнопка;
КонецФункции // ПолучитьКнопкуКоманднойПанелиЭкземпляраКомпонентыЛкс()
// Формирует имя элемента управления экземпляра компоненты.
//
// Параметры:
// ИмяКласса – Строка;
// ИмяЭкземпляра - Строка;
// КраткоеИмяЭлементаУправления – Строка.
//
// Возвращаемое значение:
// Строка - имя.
//
Функция СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КраткоеИмяЭлементаУправления) Экспорт
Возврат ПрефиксИменЭлементовЭкземпляраКомпонентыЛкс(ОбъектКомпоненты) + КраткоеИмяЭлементаУправления;
КонецФункции
Функция ПрефиксИменЭлементовЭкземпляраКомпонентыЛкс(ОбъектКомпоненты) Экспорт
Возврат ОбъектКомпоненты.ИмяКласса + "_" + ОбъектКомпоненты.Имя + "_";
КонецФункции // СформироватьИмяЭлементаУправленияЭкземпляраЛкс()
// <Описание функции>
//
// Параметры:
// <Параметр1> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// – <Тип.Вид> – <описание значения>
// <продолжение описания значения>;
// <Значение2> – <Тип.Вид> – <описание значения>
// <продолжение описания значения>.
//
Функция ПолучитьНовуюТаблицуСобытийЭлементаУправленияКомпонентыЛкс() Экспорт
ТаблицаСобытий = Новый ТаблицаЗначений;
ТаблицаСобытий.Колонки.Добавить("СобытиеОбъекта");
ТаблицаСобытий.Колонки.Добавить("БлижайшийВидАлгоритма");
ТаблицаСобытий.Колонки.Добавить("ИмяСобытия");
ТаблицаСобытий.Колонки.Добавить("Компонента");
ТаблицаСобытий.Колонки.Добавить("ВызовОбработчика");
Возврат ТаблицаСобытий;
КонецФункции // ПолучитьНовуюТаблицуСобытийЭлементаУправленияКомпонентыЛкс()
// Добавляет в кнопки командной панели приемника коллекцию кнопок командной панели источника.
//
// Параметры:
// ОбъектКомпоненты - ОбработкаОбъект - компонента;
// КнопкиМакета – КоллекцияКнопокКоманднойПанели – источник;
// КнопкиПриемника – КоллекцияКнопокКоманднойПанели – приемник;
// *ДействияКнопокКомпонент - ТаблицаЗначений, *Неопределено;
//
Процедура ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ОбъектКомпоненты, КнопкиМакета, КнопкаПриемника,
ДействияКнопокКомпонент = Неопределено, ОбщийПриемник = Неопределено) Экспорт
КнопкиПриемника = КнопкаПриемника.Кнопки;
ИмяКласса = ОбъектКомпоненты.ИмяКласса;
Если ДействияКнопокКомпонент = Неопределено Тогда
ДействиеТранслятор = Новый Действие("Клс" + ИмяКласса + "Нажатие");
Иначе
ЭтоКоманднаяПанель = (ТипЗнч(КнопкаПриемника) = Тип("КоманднаяПанель"));
ДопКнопкиКомандныхПанелей = ОбъектКомпоненты.ДопКнопкиКомандныхПанелей;
ДопКнопкиКоманднойПанели = Новый Массив;
ДопКнопкиКомандныхПанелей.Вставить(КнопкаПриемника.Имя, ДопКнопкиКоманднойПанели);
ДействиеТранслятор = Новый Действие("КнопкаКоманднойПанели_Действие")
КонецЕсли;
ИмяЭкземпляра = ОбъектКомпоненты.Имя;
Для Каждого КнопкаМакета Из КнопкиМакета Цикл
Кнопка = Неопределено;
Если КнопкаМакета.ТипКнопки = ТипКнопкиКоманднойПанели.Действие Тогда
Если Истина
И Строка(КнопкаМакета.Действие) = ""
Тогда
// Это пустое действие
Кнопка = КнопкиПриемника.Добавить(, КнопкаМакета.ТипКнопки);
ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Действие, Имя");
Кнопка.Имя = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КнопкаМакета.Имя);
//Попытка
Кнопка.Действие = ДействиеТранслятор;
//Исключение
// ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
// Возврат;
//КонецПопытки;
Если ДействияКнопокКомпонент <> Неопределено Тогда
СтрокаДействия = ДействияКнопокКомпонент.Добавить();
СтрокаДействия.Кнопка = Кнопка;
СтрокаДействия.Компонента = ОбъектКомпоненты;
ВызовОбработчика = "Действие_";
Если ОбщийПриемник = Неопределено Тогда
ВызовОбработчика = ВызовОбработчика + КнопкаМакета.Имя;
Иначе
ВызовОбработчика = ВызовОбработчика + ОбщийПриемник;
КонецЕсли;
СтрокаДействия.ВызовОбработчика = ВызовОбработчика + "(П0, П1)";
КонецЕсли;
Иначе
Кнопка = КнопкиПриемника.Добавить(КнопкаМакета.Имя, КнопкаМакета.ТипКнопки, , КнопкаМакета.Действие);
// Автокартинки предопределенных действий платформа подключает до вызова ПередОткрытием, а потом они уже пустые
Если КнопкаМакета.Картинка.Вид <> ВидКартинки.Пустая Тогда
Кнопка.Картинка = КнопкаМакета.Картинка;
КонецЕсли;
ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Имя, ТипКнопки, Картинка");
КонецЕсли;
КонецЕсли;
Если Кнопка = Неопределено Тогда
Кнопка = КнопкиПриемника.Добавить();
ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Действие, Имя");
Кнопка.Имя = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КнопкаМакета.Имя);
Если КнопкаМакета.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда
ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ОбъектКомпоненты, КнопкаМакета.Кнопки, Кнопка, ДействияКнопокКомпонент, ОбщийПриемник);
КонецЕсли;
КонецЕсли;
Если Истина
И ДействияКнопокКомпонент <> Неопределено
И ЭтоКоманднаяПанель
Тогда
ДопКнопкиКоманднойПанели.Добавить(Кнопка.Имя);
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс()
// Возвращает имя экземляра компоненты, которой принадлежит элемент управления.
//
// Параметры:
// ЭлементУправления – ЭлементУправления.
//
// Возвращаемое значение:
// Строка - имя.
//
Функция ПолучитьИмяЭкземпляраЛкс(ЭлементУправления) Экспорт
Результат = ПолучитьМассивИзСтрокиСРазделителемЛкс(ЭлементУправления.Имя, "_")[1];
Возврат Результат;
КонецФункции // ПолучитьИмяЭкземпляраЛкс()
// Устанавливает свойство у элементов именованной коллекции.
//
// Параметры:
// Коллекция – Любая индексированная коллекция;
// МассивИлиСтрока – Массив (индексов), Строка (имена элементов, разделенные запятыми), *Неопределено - фильтр;
// Свойство – Строка - имя Свойства которое нужно установить;
// ЗначениеСвойства – Произвольный.
//
Процедура УстановитьСвойствоВКоллекцииЛкс(Коллекция, МассивИлиСтрока = Неопределено, Свойство, ЗначениеСвойства) Экспорт
ДоступенИндексСвойств = Лев(Свойство, 1) <> "-";
Если МассивИлиСтрока <> Неопределено Тогда
Если ТипЗнч(МассивИлиСтрока) = Тип("Строка") Тогда
МассивИндексов = ПолучитьМассивИзСтрокиСРазделителемЛкс(МассивИлиСтрока, ",", Истина);
Иначе
МассивИндексов = МассивИлиСтрока;
КонецЕсли;
Для Каждого ИмяЭлемента Из МассивИндексов Цикл
ЭлементКоллекции = Коллекция[ИмяЭлемента];
Если ДоступенИндексСвойств Тогда
ЭлементКоллекции[Свойство] = ЗначениеСвойства;
Иначе
Выполнить("ЭлементКоллекции." + Сред(Свойство, 2) + " = ЗначениеСвойства");
КонецЕсли;
КонецЦикла;
Иначе
Для Каждого ЭлементКоллекции Из Коллекция Цикл
Если ДоступенИндексСвойств Тогда
ЭлементКоллекции[Свойство] = ЗначениеСвойства;
Иначе
Выполнить("ЭлементКоллекции." + Сред(Свойство, 2) + " = ЗначениеСвойства");
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры // УстановитьСвойствоВКоллекцииЛкс()
////////////////////////////////////////////////////////////////////////////////
// КОМПОНОВКА
// Глобальный обработчик события ПриПолученииДанных для табличных полей доступных полей компоновки.
//
// Параметры:
// ОформленияСтрок – ОформленияСтрок.
//
Процедура ПриПолученииДанныхДоступныхПолейКомпоновкиЛкс(ОформленияСтрок) Экспорт
Для каждого ОформлениеСтроки Из ОформленияСтрок Цикл
ИндексКартинки = Неопределено;
ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
Попытка
ЭтоПапка = ДанныеСтроки.Папка;
ЭтоРесурс = ДанныеСтроки.Ресурс;
Исключение
ЭтоПапка = Ложь;
ЭтоРесурс = Ложь;
КонецПопытки;
Если ЭтоПапка Тогда
ПапкаСРесурсами = ДанныеСтроки.Элементы.Количество() > 0;
Для каждого ДоступноеПоле Из ДанныеСтроки.Элементы Цикл
Если Не ДоступноеПоле.Ресурс Тогда
ПапкаСРесурсами = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПапкаСРесурсами Тогда
ИндексКартинки = 17;
КонецЕсли;
КонецЕсли;
Если Не ЭтоРесурс И Не ЭтоПапка Тогда
ИндексКартинки = ПолучитьИндексКартинкиТипаЛкс(ДанныеСтроки.ТипЗначения);
КонецЕсли;
Если ИндексКартинки <> Неопределено Тогда
ОформлениеСтроки.Ячейки[0].ОтображатьКартинку = Истина;
ОформлениеСтроки.Ячейки[0].ИндексКартинки = ИндексКартинки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ПриПолученииДанныхДоступныхПолейКомпоновкиЛкс()
// Подключает обработчики событий для табличного поля отбора компоновки данных.
//
// Параметры:
// ТабличноеПоле – ТабличноеПоле – отбора компоновки.
//
Процедура ПодключитьОбработчикиСобытийДоступныхПолейКомпоновкиЛкс(ТабличноеПоле) Экспорт
ТабличноеПоле.УстановитьДействие("ПриПолученииДанных", Новый Действие("ПриПолученииДанныхДоступныхПолей"));
ТабличноеПоле.Колонки[0].КартинкиСтрок = ПолучитьОбщуюКартинкуЛкс("ирТипыДоступныхПолейКомпоновки");
КонецПроцедуры // ПодключитьОбработчикиСобытийДоступныхПолейКомпоновкиЛкс()
// Получает линейную структуру наборов данных запросов компоновки. Работает и со схемой и с макетом.
// Содержит рекурсивный вызов.
//
// Параметры:
// НаборыДанных – НаборыДанныхСхемыКомпоновкиДанных, НаборыДанныхМакетаКомпоновкиДанных;
// *СтруктураНаборовДанных – Структура, *Неопрелено - Структура("Имя", Структура("КоллекцияВладелец, НаборДанных"))
//
// Возвращаемое значение:
// Структура.
//
Функция ПолучитьСтруктуруНаборовДанныхЗапросовЛкс(НаборыДанных, СтруктураНаборовДанных = Неопределено) Экспорт
Если СтруктураНаборовДанных = Неопределено Тогда
СтруктураНаборовДанных = Новый Структура;
КонецЕсли;
Для каждого НаборДанных Из НаборыДанных Цикл
Если Ложь
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных")
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросСхемыКомпоновкиДанных")
Тогда
Если Не ЗначениеЗаполнено(НаборДанных.Имя) Тогда
// Платформа генерит такие наборы для служебных целей
ИмяНабора = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", "");
Иначе
ИмяНабора = НаборДанных.Имя;
КонецЕсли;
СтруктураНаборовДанных.Вставить(ИмяНабора, Новый Структура("КоллекцияВладелец, НаборДанных", НаборыДанных, НаборДанных));
ИначеЕсли Ложь
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеМакетаКомпоновкиДанных")
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеСхемыКомпоновкиДанных")
Тогда
ПолучитьСтруктуруНаборовДанныхЗапросовЛкс(НаборДанных.Элементы, СтруктураНаборовДанных);
КонецЕсли;
КонецЦикла;
Возврат СтруктураНаборовДанных;
КонецФункции // ПолучитьСтруктуруНаборовДанныхЗапросовЛкс()
// Получает макет компоновки данных по схеме с использованием временных таблиц.
//
// Параметры:
// Схема – СхемаКомпоновкиДанных;
// Настройки - НастройкиКомпоновкиДанных;
// *ВнешниеНаборыДанных – Структура, *Неопределено - туда добавляются временные таблицы;
// *ДанныеРасшифровки - ДанныеРасшифровкиКомпоновкиДанных, *Неопределено;
// *ЛиОтладка - Булево, *Ложь - показывать тексты запросов и время выполнения этапов.
//
// Возвращаемое значение:
// МакетКомпоновкиДанных.
//
Функция ПолучитьМакетКомпоновкиДанныхСВременнымиТаблицамиЛкс(Схема, Настройки, ВнешниеНаборыДанных = Неопределено,
ДанныеРасшифровки = Неопределено, ЛиОтладка = Ложь, СвойМакетОформления = Неопределено, ПроверятьДоступностьПолей = Ложь) Экспорт
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Global = Истина;
RegExp.MultiLine = Истина;
RegExp.IgnoreCase = Истина;
// Допустим 1 уровень скобок.
шСкобки = "\([^\)\(]*?\)";
RegExp.Pattern = "\(ВЫБРАТЬ(?:" + шСкобки + "|[^$\(\)])*?""ВременнаяТаблица"" = ""(.*?)""\)";
Если ВнешниеНаборыДанных = Неопределено Тогда
ВнешниеНаборыДанных = Новый Структура;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
// Выполним создание всех временных таблиц. Временной таблицей считаем набор данных запрос,
// имя которого начинается с "@". Наборы данных временных таблиц удаляются из предварительной схемы.
ПредварительнаяСхема = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(Схема));
НаборыДанныхСхемы = ПредварительнаяСхема.НаборыДанных;
ЕстьВременныеТаблицы = Ложь;
НачальноеКоличество = НаборыДанныхСхемы.Количество();
Для СчетчикНаборыДанныхСхемы = 1 По НачальноеКоличество Цикл
НаборДанных = НаборыДанныхСхемы[НачальноеКоличество - СчетчикНаборыДанныхСхемы];
Если Истина
И Лев(НаборДанных.Имя, 1) = "@"
И ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросСхемыКомпоновкиДанных")
Тогда
ВременнаяСхема = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(Схема));
// Кривое копирование набора данных в новую схемы, где он будет один.
ВременнаяСхема.СвязиНаборовДанных.Очистить();
НаборыДанныхВременнойСхемы = ВременнаяСхема.НаборыДанных;
НаборыДанныхВременнойСхемыВГраница = НаборыДанныхВременнойСхемы.Количество() - 1;
Для СчетчикВременнойСхемы = 0 По НаборыДанныхВременнойСхемыВГраница Цикл
НаборДанныхВременнойСхемы = НаборыДанныхВременнойСхемы[НаборыДанныхВременнойСхемыВГраница - СчетчикВременнойСхемы];
Если НаборДанныхВременнойСхемы.Имя <> НаборДанных.Имя Тогда
НаборыДанныхВременнойСхемы.Удалить(НаборДанныхВременнойСхемы);
КонецЕсли;
КонецЦикла;
Для Каждого ПолеНабора Из НаборыДанныхВременнойСхемы[0].Поля Цикл
ПолеНабора.ОграничениеИспользования.Поле = Ложь;
ПолеНабора.ВыражениеПредставления = ПолеНабора.ПутьКДанным;
КонецЦикла;
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ВременнаяСхема));
КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
КомпоновщикНастроек.Настройки.Структура.Очистить();
КомпоновщикНастроек.Настройки.Выбор.Элементы.Очистить();
КомпоновщикНастроек.Восстановить();
ВременныеНастройки = КомпоновщикНастроек.Настройки;
// Установим использование параметров
Для Каждого ЭлементПараметра Из ВременныеНастройки.ПараметрыДанных.Элементы Цикл
ЭлементПараметра.Использование = Истина;
КонецЦикла;
// Установим структуру и выбранные поля
ЭлементСтруктуры = ВременныеНастройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
Для Каждого ДоступноеПоле Из ВременныеНастройки.ДоступныеПоляВыбора.Элементы Цикл
// Чтобы пропустить системные папки
Если Не ДоступноеПоле.Папка Тогда
НовоеВыбранноеПоле = ВременныеНастройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
НовоеВыбранноеПоле.Поле = ДоступноеПоле.Поле;
НовоеВыбранноеПоле.Использование = Истина;
КонецЕсли;
КонецЦикла;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ВременнаяСхема, ВременныеНастройки,,,, ПроверятьДоступностьПолей);
Запрос.Текст = МакетКомпоновкиДанных.НаборыДанных[0].Запрос;
Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл
Запрос.УстановитьПараметр(Параметр.Имя, Параметр.Значение);
КонецЦикла;
Запрос.Текст = RegExp.Replace(Запрос.Текст, "$1");
ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Предварительный запрос - " + НаборДанных.Имя);
//// Недоступные поля набора данных цепляются в настройках при совпадаении имен с выбранными полями
//// http://partners.v8.1c.ru/forum/thread.jsp?id=514094
//Для Каждого Поле Из НаборДанных.Поля Цикл
// Поле.ПутьКДанным = "_поле_" + Поле.ПутьКДанным;
//КонецЦикла;
НаборыДанныхСхемы.Удалить(НаборДанных);
ЕстьВременныеТаблицы = Истина;
КонецЕсли;
КонецЦикла;
Если Не ЕстьВременныеТаблицы Тогда
Если ЛиОтладка Тогда
ВремяНачалаКомпоновкиМакета = ПолучитьТекущееВремяВМиллисекундахЛкс();
КонецЕсли;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ПредварительнаяСхема, Настройки, ДанныеРасшифровки, СвойМакетОформления,, ПроверятьДоступностьПолей);
Если ЛиОтладка Тогда
Сообщить("Компоновка макета - "
+ Строка(ПолучитьТекущееВремяВМиллисекундахЛкс() - ВремяНачалаКомпоновкиМакета) + " мс");
КонецЕсли;
Иначе
// Выполним получение результата предварительного запроса
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ПредварительнаяСхема));
КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
КомпоновщикНастроек.Восстановить();
ПредварительныеНастройки = КомпоновщикНастроек.Настройки;
Если ЛиОтладка Тогда
ВремяНачалаКомпоновкиМакета = ПолучитьТекущееВремяВМиллисекундахЛкс();
КонецЕсли;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ПредварительнаяСхема, ПредварительныеНастройки, ДанныеРасшифровки, СвойМакетОформления,, ПроверятьДоступностьПолей);
Если ЛиОтладка Тогда
Сообщить("Компоновка макета - "
+ Строка(ПолучитьТекущееВремяВМиллисекундахЛкс() - ВремяНачалаКомпоновкиМакета) + " мс");
КонецЕсли;
Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл
Запрос.УстановитьПараметр(Параметр.Имя, Параметр.Значение);
КонецЦикла;
СтруктураНаборовДанныхЗапросовМакета = ПолучитьСтруктуруНаборовДанныхЗапросовЛкс(МакетКомпоновкиДанных.НаборыДанных);
Для Каждого ЭлементНаборДанныхМакета Из СтруктураНаборовДанныхЗапросовМакета Цикл
НаборДанных = ЭлементНаборДанныхМакета.Значение.НаборДанных;
Запрос.Текст = НаборДанных.Запрос;
Запрос.Текст = RegExp.Replace(Запрос.Текст, "$1");
РезультатЗапроса = ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Предварительный запрос - " + НаборДанных.Имя);
ВнешниеНаборыДанных.Вставить(НаборДанных.Имя, РезультатЗапроса);
КонецЦикла;
// Получение конечного макета
Для Каждого ЭлементНаборДанных Из СтруктураНаборовДанныхЗапросовМакета Цикл
КоллекцияВладелец = ЭлементНаборДанных.Значение.КоллекцияВладелец;
НаборДанныхЗапрос = ЭлементНаборДанных.Значение.НаборДанных;
НаборДанныхОбъект = КоллекцияВладелец.Добавить(Тип("НаборДанныхОбъектМакетаКомпоновкиДанных"));
// Копируем Свойства набора данных запроса в набор данных объекта
ЗаполнитьЗначенияСвойств(НаборДанныхОбъект, НаборДанныхЗапрос);
НаборДанныхОбъект.ИмяОбъекта = НаборДанныхЗапрос.Имя;
Для Каждого ПолеНабораДанныхОригинала Из НаборДанныхЗапрос.Поля Цикл
ПолеРезультата = НаборДанныхОбъект.Поля.Добавить();
ЗаполнитьЗначенияСвойств(ПолеРезультата, ПолеНабораДанныхОригинала);
ЗаполнитьЗначенияСвойств(ПолеРезультата.Роль, ПолеНабораДанныхОригинала.Роль);
КонецЦикла;
КоллекцияВладелец.Удалить(НаборДанныхЗапрос);
КонецЦикла;
КонецЕсли;
// Баг платформы. Пустая дата превращается в Неопределено.
Для Каждого ПараметрСхемы Из ПредварительнаяСхема.Параметры Цикл
Если ПараметрСхемы.ОграничениеИспользования Тогда
Если Не ПараметрСхемы.ДоступенСписокЗначений Тогда
ЗначениеПараметра = МакетКомпоновкиДанных.ЗначенияПараметров.Найти(ПараметрСхемы.Имя);
ЗначениеПараметра.Значение = ПараметрСхемы.ТипЗначения.ПривестиЗначение(ЗначениеПараметра.Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат МакетКомпоновкиДанных;
КонецФункции // ПолучитьМакетКомпоновкиДанныхСВременнымиТаблицамиЛкс()
// Выводит результат СКД с установкой вертикальной автофиксации.
// Параметры:
// Таб - ТабличныеДокумент, ПолеТабличногоДокумента - куда выводим отчет;
// ПроцессорКомпоновкиДанных - ПроцессорКомпоновкиДанных;
// ЭлементыРасшировки - ЭлементыРасшифровкиКомпоновкиДанных;
// МассивИгнорируемыхПолей - Массив, *Неопределено - массив имен игнорируемых полей;
// РазрешитьПрерывание - Булево, *Истина.
//
Процедура ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(Таб, ПроцессорКомпоновкиДанных, ЭлементыРасшировки,
Знач МассивИгнорируемыхПолей = Неопределено, РазрешитьПрерывание = Истина, Автофиксация = Истина, выхЭлементыРезультата = Неопределено) Экспорт
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Таб);
ПроцессорВывода.НачатьВывод();
ФиксацияВыполнена = Ложь;
Если МассивИгнорируемыхПолей = Неопределено Тогда
МассивИгнорируемыхПолей = Новый Массив;
КонецЕсли;
Пока Истина Цикл
ЭлементРезультатаКомпоновкиДанных = ПроцессорКомпоновкиДанных.Следующий();
Если ЭлементРезультатаКомпоновкиДанных = Неопределено Тогда
Прервать;
КонецЕсли;
Если РазрешитьПрерывание Тогда
ОбработкаПрерыванияПользователя();
КонецЕсли;
// Автофиксация
Если Истина
И Автофиксация
И Не ФиксацияВыполнена
Тогда
Для Каждого ЗначениеПараметра Из ЭлементРезультатаКомпоновкиДанных.ЗначенияПараметров Цикл
Если ТипЗнч(ЗначениеПараметра.Значение) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
ЗначенияПолейРасшифровки = ЭлементыРасшировки[ЗначениеПараметра.Значение].ПолучитьПоля();
Для Каждого ЗначениеПоляРасшифровки Из ЗначенияПолейРасшифровки Цикл
Если МассивИгнорируемыхПолей.Найти(ЗначениеПоляРасшифровки.Поле) = Неопределено Тогда
Таб.ФиксацияСверху = Таб.ВысотаТаблицы;
ФиксацияВыполнена = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ФиксацияВыполнена Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпоновкиДанных);
Если Истина
И выхЭлементыРезультата <> Неопределено
И выхЭлементыРезультата.Количество() < 10000
Тогда
выхЭлементыРезультата.Добавить(ЭлементРезультатаКомпоновкиДанных);
КонецЕсли;
Если РазрешитьПрерывание Тогда
ОбработкаПрерыванияПользователя();
КонецЕсли;
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();
КонецПроцедуры // ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс
#КонецЕсли
// Переустанавливает значения недоступных параметров из схемы (антибаг платформы).
//
// Параметры:
// СхемаКомпоновкиДанных – СхемаКомпоновкиДанных;
// КомпоновщикНастроек – КомпоновщикНастроекКомпоновкиДанных.
//
Процедура ОбновитьЗначенияНедоступныхПараметровИзСхемыЛкс(КомпоновщикНастроек, СхемаКомпоновкиДанных) Экспорт
#Если Сервер И Не Сервер Тогда
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
#КонецЕсли
Для Каждого ЗначениеПараметра Из КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы Цикл
ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти("" + ЗначениеПараметра.Параметр);
Если Истина
И ПараметрСхемы <> Неопределено
И ПараметрСхемы.ОграничениеИспользования
Тогда
//Если ЗначениеЗаполнено(ЗначениеПараметра.Выражение) Тогда
// Попытка
// ЗначениеПараметра.Значение = Вычислить();
// Исключение
// КонецПопытки;
//Иначе
ЗначениеПараметра.Значение = ПараметрСхемы.Значение;
//КонецЕсли;
//ЗначениеПараметра.Использование = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ОбновитьЗначенияНедоступныхПараметровИзСхемыЛкс()
Процедура ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновкиДанных) Экспорт
ПолеКоличества = "КоличествоСтрокАвто";
ВычисляемоеПоле = СхемаКомпоновкиДанных.ВычисляемыеПоля.Добавить();
ВычисляемоеПоле.Выражение = "1";
ВычисляемоеПоле.Заголовок = "Количество строк (авто)";
ВычисляемоеПоле.ПутьКДанным = ПолеКоличества;
РесурсКоличествоЗаписей = СхемаКомпоновкиДанных.ПоляИтога.Добавить();
РесурсКоличествоЗаписей.ПутьКДанным = ПолеКоличества;
РесурсКоличествоЗаписей.Выражение = "Сумма(1)";
КонецПроцедуры
// Создает новую или добавляет в существующую схему компоновки наборы данных объекты из структуры таблиц значений.
//
// Параметры:
// СтруктураТаблиц – Структура – <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>.
//
Функция СоздатьСхемуПоТаблицамЗначенийЛкс(СтруктураТаблиц, СхемаКомпоновкиДанных = Неопределено, СоздаватьПапкиПолей = Ложь,
СоздаватьРесурсыЧисловыхПолей = Ложь, ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок = Истина) Экспорт
Если СхемаКомпоновкиДанных = Неопределено Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
ИсточникДанных = ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных);
КонецЕсли;
Для Каждого КлючИЗначение Из СтруктураТаблиц Цикл
КолонкиНабора = КолонкиИсточникаДанныхЛкс(КлючИЗначение.Значение);
СоздатьИлиОбновитьНаборДанныхОбъектПоМетаданнымЛкс(СхемаКомпоновкиДанных, КолонкиНабора, КлючИЗначение.Ключ,
СоздаватьПапкиПолей, СоздаватьРесурсыЧисловыхПолей);
КонецЦикла;
Если ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок Тогда
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновкиДанных);
КонецЕсли;
Возврат СхемаКомпоновкиДанных;
КонецФункции
Функция КолонкиИсточникаДанныхЛкс(Знач ИсточникДанных)
Если Ложь
Или ТипЗнч(ИсточникДанных) = Тип("ДеревоЗначений")
Или ТипЗнч(ИсточникДанных) = Тип("ТаблицаЗначений")
Тогда
КолонкиНабора = ИсточникДанных.Колонки;
Иначе
КолонкиНабора = ИсточникДанных.ВыгрузитьКолонки().Колонки;
КонецЕсли;
Возврат КолонкиНабора;
КонецФункции // СоздатьСхемуПоТаблицамЗначенийЛкс()
// Создает новую или добавляет в существующую схему компоновки набор данных объект из полей настройки.
//
// Параметры:
// ПоляНастройки – ПоляНастройки – <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>.
//
Функция СоздатьСхемуПоПолямНастройкиЛкс(ПоляНастройки, СхемаКомпоновкиДанных = Неопределено, ИмяНабора = "НаборДанных1") Экспорт
Если СхемаКомпоновкиДанных = Неопределено Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
ИсточникДанных = ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных);
КонецЕсли;
НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
НаборДанных.Имя = ИмяНабора;
НаборДанных.ИсточникДанных = ИсточникДанных.Имя;
НаборДанных.ИмяОбъекта = ИмяНабора;
Для Каждого ПолеНастройки Из ПоляНастройки Цикл
Поле = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
Поле.ПутьКДанным = ПолеНастройки.Имя;
Поле.Поле = ПолеНастройки.ПутьКДанным;
Поле.Заголовок = ПолеНастройки.Представление;
Поле.ТипЗначения = ПолеНастройки.ТипЗначения;
ОграничениеИспользования = Поле.ОграничениеИспользования;
ОграничениеИспользования.Поле = Не ПолеНастройки.Поле;
ОграничениеИспользования.Условие = Не ПолеНастройки.Отбор;
ОграничениеИспользования.Порядок = Не ПолеНастройки.Порядок;
ОграничениеИспользования.Группировка = Не ПолеНастройки.Измерение;
ЗначениеОграничения = ПолеНастройки.Поля.Количество() = 0;
ОграничениеИспользованияРеквизитов = Поле.ОграничениеИспользованияРеквизитов;
ОграничениеИспользованияРеквизитов.Поле = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Условие = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Порядок = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Группировка = ЗначениеОграничения;
КонецЦикла;
Возврат СхемаКомпоновкиДанных;
КонецФункции // СоздатьСхемуПоПолямНастройкиЛкс()
// Параметры:
// Поле -
// Доступность -
// ПрименитьГруппировка -
// ПрименитьПоле -
// ПрименитьПорядок -
// ПрименитьУсловие -
// Возвращаемое значение:
//
Функция УстановитьОграниченияИспользованияПоляНабораДанныхСхемыКомпоновкиЛкс(Знач Поле, Знач Ограничивать = Ложь, Знач ПрименитьГруппировка = Истина,
Знач ПрименитьПоле = Истина, Знач ПрименитьПорядок = Истина, Знач ПрименитьУсловие = Истина) Экспорт
МассивГруппОграничений = Новый Массив;
МассивГруппОграничений.Добавить(Поле.ОграничениеИспользования);
Попытка
МассивГруппОграничений.Добавить(Поле.ОграничениеИспользованияРеквизитов);
Исключение
КонецПопытки;
Для Каждого ОграничениеИспользования Из МассивГруппОграничений Цикл
Если ПрименитьГруппировка Тогда
ОграничениеИспользования.Группировка = Ограничивать;
КонецЕсли;
Если ПрименитьПоле Тогда
ОграничениеИспользования.Поле = Ограничивать;
КонецЕсли;
Если ПрименитьПорядок Тогда
ОграничениеИспользования.Порядок = Ограничивать;
КонецЕсли;
Если ПрименитьУсловие Тогда
ОграничениеИспользования.Условие = Ограничивать;
КонецЕсли;
КонецЦикла;
КонецФункции
// Функция добавляет в схему компоновки источник данных с типом "Local"
Функция ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных) Экспорт
ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить();
ИсточникДанных.Имя = "ИсточникДанных1";
ИсточникДанных.ТипИсточникаДанных = "Local";
Возврат ИсточникДанных;
КонецФункции
// Функция добавляет набор данных - запрос в указанную в параметре коллекцию наборов данных
Функция ДобавитьНаборДанныхЗапросЛкс(НаборыДанных, ИсточникДанных, ИмяНабораДанных = "НаборДанных1") Экспорт
НаборДанных = НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
НаборДанных.Имя = ИмяНабораДанных;
НаборДанных.ИсточникДанных = ИсточникДанных.Имя;
Возврат НаборДанных;
КонецФункции
// Устаревшее! Новая - ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.ПолучитьВыражениеПорядкаКомпоновкиНаЯзыке
// Получает строку для установки порядка компоновки.
//
// Параметры:
// ПорядокКомпоновки – ПорядокКомпоновкиДанных.
//
// Возвращаемое значение:
// Строка - для установки порядка.
//
Функция ПолучитьСтрокуПорядкаКомпоновкиЛкс(ПорядокКомпоновки, ИсключаемоеПоле = "", СимволЗаменыТочки = Неопределено) Экспорт
Строка = "";
Для Каждого ЭлементПорядка Из ПорядокКомпоновки.Элементы Цикл
Если Ложь
Или Не ЭлементПорядка.Использование
Или ТипЗнч(ЭлементПорядка) = Тип("АвтоЭлементПорядкаКомпоновкиДанных")
Или ИсключаемоеПоле = "" + ЭлементПорядка.Поле
Тогда
Продолжить;
КонецЕсли;
ИмяПоля = "" + ЭлементПорядка.Поле;
Если СимволЗаменыТочки <> Неопределено Тогда
ИмяПоля = СтрЗаменить(ИмяПоля, ".", СимволЗаменыТочки);
КонецЕсли;
Строка = Строка + ", " + ИмяПоля + " ";
Если ЭлементПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда
Строка = Строка + "Возр";
Иначе
Строка = Строка + "Убыв";
КонецЕсли;
КонецЦикла;
Возврат Сред(Строка, 3);
КонецФункции // ПолучитьСтрокуПорядкаКомпоновкиЛкс()
// Трансформирует порядок в порядок компоновки.
//
// Параметры:
// ПорядокКомпоновки – ПорядокКомпоновкиДанных;
// Порядок - Порядок.
//
Процедура ТрансформироватьПорядокВПорядокКомпоновкиЛкс(ПорядокКомпоновки, Порядок) Экспорт
ЭлементыКомпоновки = ПорядокКомпоновки.Элементы;
ЭлементыКомпоновки.Очистить();
Для Каждого Элемент Из Порядок Цикл
ЭлементКомпоновки = ЭлементыКомпоновки.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
ЭлементКомпоновки.Использование = Истина;
ЭлементКомпоновки.Поле = Новый ПолеКомпоновкиДанных(Элемент.ПутьКДанным);
Если Элемент.Направление = НаправлениеСортировки.Возр Тогда
ЭлементКомпоновки.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр;
Иначе//Если Элемент.Направление = НаправлениеСортировки.Убыв Тогда
ЭлементКомпоновки.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ТрансформироватьПорядокВПорядокКомпоновкиЛкс()
// Конструктор массива через Параметры.
//
// Параметры:
// *п... – Произвольный – элементы массива.
//
// Возвращаемое значение:
// Массив - полученный массив.
//
Функция БыстрыйМассивЛкс(
п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); КонецЕсли;
Возврат М;
КонецФункции // БыстрыйМассивЛкс()
////////////////////////////////////////////////////////////////////////////////
// РАБОТА СО СТРОКАМИ
// <Описание функции>
//
// Параметры:
// <Параметр1> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// Строка - путь к файлу.
//
Функция ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение, Название, ПолучатьXMLПредставлениеДляНеизвестныхТипов = Истина) Экспорт
Если Ложь
Или ТипЗнч(Значение) = Тип("ТабличныйДокумент")
Или ТипЗнч(Значение) = Тип("ТекстовыйДокумент")
Тогда
Документ = Значение;
Иначе
Документ = Новый ТекстовыйДокумент;
Если ТипЗнч(Значение) = Тип("ХранилищеЗначения") Тогда
Значение = Значение.Получить();
КонецЕсли;
Если ТипЗнч(Значение) <> Тип("Строка") И ПолучатьXMLПредставлениеДляНеизвестныхТипов Тогда
Представление = СохранитьОбъектВВидеСтрокиXMLЛкс(Значение);
Иначе
Представление = Значение;
КонецЕсли;
Документ.УстановитьТекст(ПолучитьТекстИзXMLЛкс(Представление));
КонецЕсли;
Путь = ПолучитьИмяВременногоФайла(Название);
Документ.Записать(Путь);
Возврат Путь;
КонецФункции // ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс()
// Получает строку путем отсечения заданного числа последних символов.
//
// Параметры:
// пСтрока – Строка – исходная;
// пДлинаКонца - Число, *1 - количество отсекаемых символов;
//
// Возвращаемое значение:
// – Строка.
//
Функция ПолучитьСтрокуБезКонцаЛкс(пСтрока, пДлинаКонца = 1) Экспорт
Если СтрДлина(пСтрока) < пДлинаКонца Тогда
Возврат "";
Иначе
Возврат Лев(пСтрока, СтрДлина(пСтрока) - пДлинаКонца);
КонецЕсли;
КонецФункции // ПолучитьСтрокуБезКонцаЛкс()
// Функция собирает строку из элементов массива с разделителем.
//
// Параметры:
// пМассив - Массив - из которого формируем строку;
// *пРазделитель - Строка - символ-разделитель.
//
// Возвращаемое значение:
// Строка.
//
Функция ПолучитьСтрокуСРазделителемИзМассиваЛкс(пМассив, пРазделитель = ", ") Экспорт
Результат = "";
Для Каждого Элемент Из пМассив Цикл
Результат = Результат + пРазделитель + Строка(Элемент);
КонецЦикла;
Возврат Сред(Результат, СтрДлина(пРазделитель) + 1);
КонецФункции // ПолучитьСтрокуСРазделителемИзМассиваЛкс()
// Получает первый фрагмент, отделяемый разделителем от строки.
// Написана для оптимизации по скорости.
//
// Параметры:
// пСтрока - Строка - которую разбиваем;
// *пРазделитель - Строка, "." - символ-разделитель;
// *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина.
//
// Возвращаемое значение:
// - Строка - первый фрагмент строки;
// Неопределено - в строке не обнаружен разделитель.
//
Функция ПолучитьПервыйФрагментЛкс(пСтрока, пРазделитель = ".",
пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина) Экспорт
Позиция = Найти(пСтрока, пРазделитель);
Если Позиция > 0 Тогда
Возврат Лев(пСтрока, Позиция - 1);
Иначе
Если пЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда
Возврат пСтрока;
Иначе
Возврат "";
КонецЕсли;
КонецЕсли;
КонецФункции // ПолучитьПервыйФрагментЛкс()
// Получает последний фрагмент, отделяемый разделителем от строки.
//
// Параметры:
// пСтрока - Строка - в которой ищем;
// *пМаркер – Строка, "." – отсекающий маркер;
// *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина - разрешение использования границ строки
// в случае, если маркер не найден.
//
// Возвращаемое значение:
// Неопределено - маркер не найден;
// – Число – позиция маркера.
//
Функция ПолучитьПоследнийФрагментЛкс(пСтрока, пМаркер = ".",
пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина) Экспорт
Подстрока = пСтрока;
МаркерНайден = Ложь;
Пока пМаркер <> "" Цикл
Позиция = Найти(Подстрока, пМаркер);
Если Позиция = 0 Тогда
Прервать;
КонецЕсли;
МаркерНайден = Истина;
Подстрока = Сред(Подстрока, Позиция + СтрДлина(пМаркер));
КонецЦикла;
Если Истина
И Не МаркерНайден
И пЛиИспользоватьГраницуЕслиМаркерНеНайден
Тогда
Возврат пСтрока;
ИначеЕсли МаркерНайден Тогда
Возврат Подстрока;
Иначе
Возврат "";
КонецЕсли;
КонецФункции // ПолучитьПоследнийФрагментЛкс()
// Получает представление из идентификатора по правилу
// "Дебиторка_По_контрагентамСИнтерваламиСНГДля__Руководства" => "Дебиторка По контрагентам с интервалами СНГ для Руководства".
// После символа "_" регистр не меняется, а сам символ заменяется на " ".
//
// Параметры:
// ИсходнаяСтрока – Строка – идентификатор.
//
// Возвращаемое значение:
// – Строка – представление.
//
Функция ПолучитьПредставлениеИзИдентификатораЛкс(ИсходнаяСтрока) Экспорт
СтрокаВозврата = Сред(ИсходнаяСтрока, 1, 1);
Для Сч = 2 По СтрДлина(ИсходнаяСтрока) Цикл
ПредыдущийСимвол = Сред(ИсходнаяСтрока, Сч - 1, 1);
ТекущийСимвол = Сред(ИсходнаяСтрока, Сч, 1);
СледующийСимвол = Сред(ИсходнаяСтрока, Сч + 1, 1);
ПослеследующийСимвол = Сред(ИсходнаяСтрока, Сч + 2, 1);
Если ТекущийСимвол = "_" Тогда
СтрокаВозврата = СтрокаВозврата + " ";
Продолжить;
ИначеЕсли Истина
И ВРЕГ(ТекущийСимвол) = ТекущийСимвол
// В идентификаторе не должны встречаться пробелы. Поэтому было решено закомментировать следующую строку.
//И ПредыдущийСимвол <> " "
Тогда
Если Ложь
ИЛИ ВРЕГ(ПредыдущийСимвол) <> ПредыдущийСимвол
ИЛИ (Истина
И ПредыдущийСимвол <> "_"
И ВРЕГ(ПредыдущийСимвол) = ПредыдущийСимвол
И ВРЕГ(СледующийСимвол) <> СледующийСимвол)
Тогда
СтрокаВозврата = СтрокаВозврата + " ";
Если Ложь
ИЛИ ВРЕГ(СледующийСимвол) <> СледующийСимвол
ИЛИ ВРЕГ(ПослеследующийСимвол) <> ПослеследующийСимвол
Тогда
ТекущийСимвол = НРЕГ(ТекущийСимвол);
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтрокаВозврата = СтрокаВозврата + ТекущийСимвол;
КонецЦикла;
Возврат СтрокаВозврата;
КонецФункции // ПолучитьПредставлениеИзИдентификатораЛкс()
// Преобразует строку для использования в регулярных выражениях.
// Производится
//
// Параметры:
// пТекст – Строка.
//
// Возвращаемое значение:
// Строка – для вставки в регулярные выражения.
//
Функция ПреобразоватьТекстДляРегулярныхВыраженийЛкс(пТекст) Экспорт
Текст = пТекст;
СтрокаСпецСимволов = "\[]^$()?*+.";
Для Счетчик = 1 По СтрДлина(СтрокаСпецСимволов) Цикл
СпецСимвол = Сред(СтрокаСпецСимволов, Счетчик, 1);
Текст = СтрЗаменить(Текст, СпецСимвол, "\" + СпецСимвол);
КонецЦикла;
Возврат Текст;
КонецФункции // ПреобразоватьТекстДляРегулярныхВыраженийЛкс()
// Преобразует строку для правого операнда оператора ПОДОБНО языка запросов.
//
// Параметры:
// пТекст – Строка.
//
// Возвращаемое значение:
// Строка.
//
Функция ПреобразоватьСтрокуДляПОДОБНОЛкс(Знач Результат, Спецсимвол = "~") Экспорт
ЗарезервированныеСимволы = Новый Массив;
ЗарезервированныеСимволы.Добавить("~");
//ЗарезервированныеСимволы.Добавить("%");
ЗарезервированныеСимволы.Добавить("_");
ЗарезервированныеСимволы.Добавить("[");
ЗарезервированныеСимволы.Добавить("-");
ЗарезервированныеСимволы.Добавить("]");
Для Каждого ЗарезервированныйСимвол Из ЗарезервированныеСимволы Цикл
Результат = СтрЗаменить(Результат, ЗарезервированныйСимвол, Спецсимвол + ЗарезервированныйСимвол);
КонецЦикла;
Возврат Результат;
КонецФункции // ПреобразоватьСтрокуДляПОДОБНОЛкс()
// Получает строку путем повтора переданной строки заданное количество раз.
//
// Параметры:
// СтрокаДляПовтора – Строка;
// ЧислоПовторов – Число.
//
// Возвращаемое значение:
// Строка.
//
Функция ПолучитьСтрокуПовторомЛкс(СтрокаДляПовтора, ЧислоПовторов) Экспорт
Результат = "";
Для Счетчик = 1 По ЧислоПовторов Цикл
Результат = Результат + СтрокаДляПовтора;
КонецЦикла;
Возврат Результат;
КонецФункции // ПолучитьСтрокуПовторомЛкс()
// Обновляет в строковом свойстве объекта часть, которая следует за маркером.
// Если маркер не находится, то он добавляется.
//
// Параметры:
// пОбъект – Объект, Строка - объект, строковое свойство которого будем обновлять, или само свойство по ссылке;
// *пИмяСвойства – Строка, *"" – имя строкового Свойства объекта, указывается в случае, если свойство не передается по ссылке;
// пНовыйТекст - Строка - новая часть, которая следует за разделителем;
// *пМаркер - Строка, *"," - маркер.
//
Процедура ОбновитьТекстПослеМаркераВСтрокеЛкс(пОбъектИлиСвойство, пИмяСвойства = "", пНовыйТекст, пМаркер = ", ") Экспорт
Если пИмяСвойства <> "" Тогда
СтараяСтрока = пОбъектИлиСвойство[пИмяСвойства];
Иначе
СтараяСтрока = пОбъектИлиСвойство;
КонецЕсли;
ПозицияРазделителя = Найти(СтараяСтрока, пМаркер);
Если ПозицияРазделителя = 0 Тогда
ПозицияРазделителя = СтрДлина(СтараяСтрока) + 1;
КонецЕсли;
НоваяСтрока = Лев(СтараяСтрока, ПозицияРазделителя - 1) + пМаркер + пНовыйТекст;
Если пИмяСвойства <> "" Тогда
пОбъектИлиСвойство[пИмяСвойства] = НоваяСтрока;
Иначе
пОбъектИлиСвойство = НоваяСтрока;
КонецЕсли;
КонецПроцедуры // ОбновитьТекстПослеМаркераВСтрокеЛкс()
// Заменяет текущее выделение в поле текстового документа новым текстом.
// После этого устанавливает выделение на вставленный фрагмент.
//
// Параметры:
// ПолеТекстовогоДокумента - ПолеТекстовогоДокумента;
// НовыйТекст – Строка.
//
Процедура ЗаменитьВыделенныйТекстСохраняяГраницыВыделенияЛкс(ПолеТекстовогоДокумента, НовыйТекст) Экспорт
Перем НачальнаяСтрока;
Перем НачальнаяКолонка;
Перем КонечнаяСтрока;
Перем КонечнаяКолонка;
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка);
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, НачальнаяСтрока, НачальнаяКолонка);
НачальнаяГраница = СтрДлина(ПолеТекстовогоДокумента.ВыделенныйТекст) + 1;
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка);
ПолеТекстовогоДокумента.ВыделенныйТекст = НовыйТекст;
КонечнаяГраница = НачальнаяГраница + СтрДлина(НовыйТекст);
Если КонечнаяГраница > СтрДлина(ПолеТекстовогоДокумента.ПолучитьТекст()) Тогда
КонечнаяГраница = КонечнаяГраница - 1;
КонецЕсли;
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяГраница, КонечнаяГраница);
КонецПроцедуры // ЗаменитьВыделенныйТекстСохраняяГраницыВыделенияЛкс()
// Взято отсюда 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.УстановитьСтроку(
"
| cc:AnyRef
|");
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Если ирКэш.Получить().ВерсияПлатформы >= 803001 Тогда
Для Каждого ВнешнийИсточникДанных Из Вычислить("ВнешниеИсточникиДанных") Цикл // Для компиляции на платформе 8.2.13-
Результат = Новый ОписаниеТипов(Результат, ВнешнийИсточникДанных.Таблицы.ТипВсеСсылки().Типы());
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьОписаниеТиповВсеРедактируемыеТипыЛкс() Экспорт
ОписаниеТипов = ПолучитьОписаниеТиповВсеСсылкиЛкс();
ДополнительныеТипы = Новый Массив();
ДополнительныеТипы.Добавить(Тип("Строка"));
ДополнительныеТипы.Добавить(Тип("Число"));
ДополнительныеТипы.Добавить(Тип("Дата"));
ДополнительныеТипы.Добавить(Тип("Булево"));
ДополнительныеТипы.Добавить(Тип("СписокЗначений"));
ДополнительныеТипы.Добавить(Тип("Массив"));
ДополнительныеТипы.Добавить(Тип("ОписаниеТипов"));
ДополнительныеТипы.Добавить(Тип("МоментВремени"));
ДополнительныеТипы.Добавить(Тип("Граница"));
ДополнительныеТипы.Добавить(Тип("СтандартнаяДатаНачала"));
ДополнительныеТипы.Добавить(Тип("СтандартныйПериод"));
ДополнительныеТипы.Добавить(Тип("ТаблицаЗначений"));
ДополнительныеТипы.Добавить(Тип("ДеревоЗначений"));
ДополнительныеТипы.Добавить(Тип("ТабличныйДокумент"));
ДополнительныеТипы.Добавить(Тип("ВидДвиженияНакопления"));
ДополнительныеТипы.Добавить(Тип("ВидДвиженияБухгалтерии"));
ДополнительныеТипы.Добавить(Тип("ВидСчета"));
ДополнительныеТипы.Добавить(Тип("Тип"));
ДополнительныеТипы.Добавить(Тип("Null"));
ДополнительныеТипы.Добавить(Тип("ПолеКомпоновкиДанных"));
//ДополнительныеТипы.Добавить(Тип("ВидТочкиМаршрутаБизнесПроцесса")); // нельзя добавить, т.к. для этого типа не поддерживается сериализация
//ДополнительныеТипы.Добавить(Тип("ВидПериодаРегистраРасчета")); // нельзя добавить, т.к. для этого типа не поддерживается сериализация
ДополнительныеТипы.Добавить(Тип("УникальныйИдентификатор"));
ДополнительныеТипы.Добавить(Тип("ХранилищеЗначения"));
ДополнительныеТипы.Добавить(Тип("ДвоичныеДанные"));
// Из-за бага платформы отключены
//ДополнительныеТипы.Добавить(Тип("ПериодичностьАгрегатаРегистраНакопления"));
//ДополнительныеТипы.Добавить(Тип("ИспользованиеАгрегатаРегистраНакопления"));
КвалификаторыЧисла = Новый КвалификаторыЧисла; //(25, 5); // Важно!
ОписаниеТипов = Новый ОписаниеТипов(ОписаниеТипов, ДополнительныеТипы, , КвалификаторыЧисла);
Возврат ОписаниеТипов;
КонецФункции
Функция РежимСовместимостиМеньше8_3_4Лкс() Экспорт
Возврат Ложь
Или ирКэш.Получить().ВерсияПлатформы < 803004
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_3_3
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_3_2
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_3_1
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_2_16
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_2_13
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_1;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С ДЕРЕВЬЯМИ
Процедура ДобавитьКолонкуЕслиНетЛкс(КолонкиДереваИлиТаблицы, ИмяКолонки, ОписаниеТипов = Неопределено,
Заголовок = Неопределено, Ширина = 0) Экспорт
Если КолонкиДереваИлиТаблицы.Найти(ИмяКолонки) <> Неопределено Тогда
Возврат;
КонецЕсли;
КолонкиДереваИлиТаблицы.Добавить(ИмяКолонки, ОписаниеТипов, Заголовок, Ширина);
КонецПроцедуры // ДобавитьКолонкуЕслиНетЛкс()
// ИгнорироватьПростойПервыйУровень - Булево - если на первом уровне только одна строка, то игнорировать ее
Функция ПолучитьСтрокуПутиВДеревеЛкс(СтрокаДерева, ИмяКолонки = "Имя", ИгнорироватьПростойПервыйУровень = Ложь, Разделитель = ".") Экспорт
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Результат = ПолучитьРодителяСтрокиДереваЛкс(СтрокаДерева).Строки.Индекс(СтрокаДерева);
Иначе
Результат = СтрокаДерева[ИмяКолонки];
КонецЕсли;
Если СтрокаДерева.Родитель = Неопределено Тогда
Если Истина
И ИгнорироватьПростойПервыйУровень
И СтрокаДерева.Владелец().Строки.Количество() = 1
Тогда
Результат = Неопределено;
КонецЕсли;
Иначе
РезультатСверху = ПолучитьСтрокуПутиВДеревеЛкс(СтрокаДерева.Родитель, ИмяКолонки, ИгнорироватьПростойПервыйУровень, Разделитель);
Если РезультатСверху <> Неопределено Тогда
Результат = РезультатСверху + Разделитель + Результат;
КонецЕсли;
КонецЕсли;
Возврат XMLСтрока(Результат);
КонецФункции // ПолучитьСтрокуПутиВДеревеЛкс()
// ИгнорироватьПростойПервыйУровень - Булево - если на первом уровне только одна строка, то игнорировать ее
Функция НайтиПоСтрокеПутиВДеревеЛкс(СтрокаДерева, ИмяКолонки = "Имя", Путь, ИгнорироватьПростойПервыйУровень = Ложь) Экспорт
Если Истина
И ИгнорироватьПростойПервыйУровень
И ТипЗнч(СтрокаДерева) = Тип("ДеревоЗначений")
И СтрокаДерева.Строки.Количество() = 1
Тогда
Возврат НайтиПоСтрокеПутиВДеревеЛкс(СтрокаДерева.Строки[0], ИмяКолонки, Сред(Путь, 2));
КонецЕсли;
ТекущийУровень = ПолучитьПервыйФрагментЛкс(Путь);
Если Не ЗначениеЗаполнено(ТекущийУровень) Тогда
Возврат СтрокаДерева;
КонецЕсли;
ОстальнойПуть = Сред(Путь, СтрДлина(ТекущийУровень) + 2);
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ТекущаяСтрока = СтрокаДерева.Строки[Число(ТекущийУровень)];
Иначе
ТекущаяСтрока = СтрокаДерева.Строки.Найти(ТекущийУровень, ИмяКолонки);
КонецЕсли;
Если ТекущаяСтрока <> Неопределено Тогда
Возврат НайтиПоСтрокеПутиВДеревеЛкс(ТекущаяСтрока, ИмяКолонки, ОстальнойПуть);
Иначе
Возврат СтрокаДерева;
КонецЕсли;
КонецФункции // НайтиПоСтрокеПутиВДеревеЛкс()
Функция _ПолучитьМассивПутиСтрокиДереваЛкс(СтрокаДерева, ИмяКолонки = "Имя") Экспорт
Если СтрокаДерева.Родитель = Неопределено Тогда
Результат = Новый Массив;
Иначе
Результат = _ПолучитьМассивПутиСтрокиДереваЛкс(СтрокаДерева.Родитель, ИмяКолонки);
КонецЕсли;
ТекущийУровень = СтрокаДерева[ИмяКолонки];
//Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Результат.Добавить(ТекущийУровень);
//КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьМассивПутиСтрокиДереваЛкс()
Функция НайтиСтрокуДереваПоМассивуПутиЛкс(СтрокаДерева, ИмяКолонки = "Имя", Путь, Позиция = 0) Экспорт
Индекс = Позиция;
ТекущийУровень = Путь[Индекс];
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ТекущаяСтрока = СтрокаДерева.Строки[ТекущийУровень];
Иначе
ТекущаяСтрока = СтрокаДерева.Строки.Найти(ТекущийУровень, ИмяКолонки);
КонецЕсли;
Если Истина
И ТекущаяСтрока <> Неопределено
И Индекс < Путь.ВГраница()
Тогда
Возврат НайтиСтрокуДереваПоМассивуПутиЛкс(ТекущаяСтрока, ИмяКолонки, Путь, Позиция + 1);
Иначе
Возврат ТекущаяСтрока;
КонецЕсли;
КонецФункции // НайтиСтрокуДереваПоМассивуПутиЛкс()
// Процедура заполняет колонку дерева значением.
//
// Параметры
// ЭлементДЗ - ДеревоЗначений;
// ИмяКолонки - Строка;
// ЗначениеКолонки - Произвольный.
//
Процедура ЗаполнитьКолонкуДереваЛкс(ЭлементДЗ, ИмяКолонки, ЗначениеКолонки) Экспорт
Для Каждого ПодчиненнаяСтрока Из ЭлементДЗ.Строки Цикл
ПодчиненнаяСтрока[ИмяКолонки] = ЗначениеКолонки;
ЗаполнитьКолонкуДереваЛкс(ПодчиненнаяСтрока, ИмяКолонки, ЗначениеКолонки);
КонецЦикла;
КонецПроцедуры // ЗаполнитьКолонкуДереваЛкс
// Процедура удаляет все строки дерева со значением в колонке.
//
// Параметры
// ЭлементДЗ - ДеревоЗначений;
// ИмяКолонки - Строка;
// ЗначениеКолонки - Произвольный.
//
Процедура УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс(ЭлементДЗ, ИмяКолонки, ЗначениеКолонки) Экспорт
НачальноеКоличество = ЭлементДЗ.Строки.Количество();
Для Счетчик = 1 По НачальноеКоличество Цикл
ПодчиненнаяСтрока = ЭлементДЗ.Строки[НачальноеКоличество - Счетчик];
Если ПодчиненнаяСтрока[ИмяКолонки] = ЗначениеКолонки Тогда
ЭлементДЗ.Строки.Удалить(ПодчиненнаяСтрока);
Иначе
УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс(ПодчиненнаяСтрока, ИмяКолонки, ЗначениеКолонки);
КонецЕсли;
КонецЦикла;
КонецПроцедуры // УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс
// <Описание процедуры>
//
// Параметры:
// <Параметр1> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>.
//
Функция ПолучитьТекстИзXMLЛкс(Текст) Экспорт
//{ Заменяем символы, критичные для XML
Текст = СтрЗаменить(Текст,"&","&");
Текст = СтрЗаменить(Текст,"<","<");
Текст = СтрЗаменить(Текст,">",">");
Возврат Текст;
КонецФункции // ПолучитьТекстИзXMLЛкс()
Функция СтрокаВнутрВХМЛТелоЛкс(вхСтрока, выхХМЛТело = Неопределено) Экспорт
//{ Получение одной длинной строки
выхХМЛТело = СтрЗаменить(вхСтрока,СИМВОЛЫ.ПС,"");
выхХМЛТело = СтрЗаменить(выхХМЛТело,СИМВОЛЫ.ВК,"");
//}
//{ Заменяем символы, критичные для XML
// & на &
// < на <
// > на >
выхХМЛТело = СтрЗаменить(выхХМЛТело,"&","&");
выхХМЛТело = СтрЗаменить(выхХМЛТело,"<","<");
выхХМЛТело = СтрЗаменить(выхХМЛТело,">",">");
//{ Замена одинарных символов
выхХМЛТело = СтрЗаменить(выхХМЛТело,",","");
выхХМЛТело = СтрЗаменить(выхХМЛТело,"{","");
выхХМЛТело = СтрЗаменить(выхХМЛТело,"}","");
//}
//{ Удаляем лишние блоки и
выхХМЛТело = СтрЗаменить(выхХМЛТело,"","");
выхХМЛТело = СтрЗаменить(выхХМЛТело,"","");
//}
//{ Добавляем перенос строки к и к для удобства поиска различий
выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""+СИМВОЛЫ.ПС);
выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""+СИМВОЛЫ.ПС);
//}
Возврат выхХМЛТело;
КонецФункции
// Получает структуру для индикации прогресса цикла.
//
// Параметры:
// КоличествоПроходов – Число - максимальное значение счетчика;
// ПредставлениеПроцесса – Строка, *"Выполнено" – отображаемое название процесса;
// КоличествоОбновлений - Число, *100 - всего количество обновлений индикатора;
// ЛиВыводитьВремя - Булево, *Истина - выводить приблизительное время до окончания процесса;
// РазрешитьПрерывание - Булево, *Истина - разрешает пользователю прерывать процесс.
// МинимальныйПериодОбновления - Число, *1 - с, обновлять не чаще чем этот период, 0 - по количеству обновлений,
// эта реализация не поддерживает дробные значения;
// ТаблицаИндикаторов - ТаблицаЗначений,* - передается при необходимости многоуровневой индикации
//
// Возвращаемое значение:
// Структура - которую потом нужно будет передавать в метод ОбработатьИндикаторЛкс.
//
Функция ПолучитьИндикаторПроцессаЛкс(Знач КоличествоПроходов = 0, ПредставлениеПроцесса = "Выполнение",
Знач КоличествоОбновлений = 0, ЛиВыводитьВремя = Истина, РазрешитьПрерывание = Истина, МинимальныйПериодОбновления = 1,
ТаблицаИндикаторов = Неопределено) Экспорт
ирПлатформа = ирКэш.Получить();
Если Не ЗначениеЗаполнено(КоличествоПроходов) Тогда
//#Если Клиент Тогда
// СостояниеЛкс(ПредставлениеПроцесса + "...");
//#КонецЕсли
КоличествоПроходов = 0;
КонецЕсли;
КоличествоПроходов = Цел(КоличествоПроходов);
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
Если ТаблицаИндикаторов.Количество() = 0 Тогда
#Если Клиент Тогда
ПодключитьГлобальныйОбработчикОжиданияЛкс("ОсвободитьВсеИндикаторыПроцессовОтложенноЛкс");
#КонецЕсли
ИначеЕсли ТаблицаИндикаторов.Количество() >= 10 Тогда
ВызватьИсключение "Превышена допустимая глубина вложенности индикаторов";
КонецЕсли;
Индикатор = ТаблицаИндикаторов.Добавить();
Индикатор.КоличествоПроходов = КоличествоПроходов;
Индикатор.ПредставлениеПроцесса = ПредставлениеПроцесса;
Индикатор.ЛиВыводитьВремя = ЛиВыводитьВремя;
Индикатор.РазрешитьПрерывание = РазрешитьПрерывание;
Индикатор.ДатаНачалаПроцесса = ТекущаяДата();
Индикатор.МинимальныйПериодОбновления = МинимальныйПериодОбновления;
Индикатор.ДатаСледующегоОбновления = Индикатор.ДатаНачалаПроцесса + Индикатор.МинимальныйПериодОбновления;
Если КоличествоОбновлений > 0 Тогда
Шаг = КоличествоПроходов / КоличествоОбновлений;
Иначе
Шаг = 0;
КонецЕсли;
Индикатор.Шаг = Шаг;
//Индикатор.СледующийСчетчик = 0;
//Индикатор.Счетчик = 0;
Возврат Индикатор;
КонецФункции // ПолучитьИндикаторПроцессаЛкс()
// Вызов метода при без параметра СтрокаИндикатора освобождает один полученный последним индикатор процесса. В качестве параметра этого метода можно передавать и конкретный индикатор процесса. При освобождении индикатора процесса выполняется либо его удаление из базы данных (без постоянного хранения состояния), либо сохранение его текущего состояния в базу данных (с постоянным хранением состояния)
// Параметры:
// СтрокаИндикатора - Неопределено, СтрокаТаблицыЗначений - Если Неопределено, то освобождается последний индикатор
// ВывестиИтогИндикации - Булево
// ТолькоВосстановитьСостояние - Булево - Устанавливается при обратном COM вызове
//
Процедура ОсвободитьИндикаторПроцессаЛкс(Знач Индикатор = Неопределено, Знач ВывестиИтогИндикации = Ложь) Экспорт
ирПлатформа = ирКэш.Получить();
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
Если Индикатор = Неопределено Тогда
Если ТаблицаИндикаторов.Количество() > 0 Тогда
Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1];
КонецЕсли;
КонецЕсли;
Если Индикатор <> Неопределено Тогда
Если ВывестиИтогИндикации Тогда
СообщитьИтогИндикацииЛкс(Индикатор);
КонецЕсли;
Если ТаблицаИндикаторов <> Неопределено Тогда
Если ТаблицаИндикаторов.Индекс(Индикатор) <> -1 Тогда
ТаблицаИндикаторов.Удалить(Индикатор);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Ложь
Или ТаблицаИндикаторов = Неопределено
Или ТаблицаИндикаторов.Количество() = 0
Тогда
НовоеСостояние = "";
Иначе
НовоеСостояние = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1].ТекстСостояния;
КонецЕсли;
#Если Клиент Тогда
Состояние(НовоеСостояние);
#КонецЕсли
КонецПроцедуры
Процедура ОсвободитьВсеИндикаторыПроцессовЛкс() Экспорт
ирПлатформа = ирКэш.Получить();
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
//Для Каждого СтрокаИндикатора Из ТаблицаИндикаторов Цикл
// ОбработатьИндикаторЛкс(СтрокаИндикатора, , Истина);
//КонецЦикла;
ТаблицаИндикаторов.Очистить();
КонецПроцедуры
// Проверяет и обновляет индикатор. Нужно вызывать на каждом проходе индицируемого цикла.
//
// Параметры:
// Индикатор – Структура – индикатора, полученная методом ПолучитьИндикаторПроцессаЛкс;
// Счетчик – Число, *Неопределено – внешний счетчик цикла.
//
Процедура ОбработатьИндикаторЛкс(Индикатор, Счетчик = Неопределено) Экспорт
Если Счетчик = Неопределено Тогда
Попытка
Счетчик = Индикатор.Счетчик;
Исключение
// Бывает, что строка таблицы индикаторов уже была удалена
Возврат;
КонецПопытки;
Счетчик = Счетчик + 1;
КонецЕсли;
Индикатор.Счетчик = Счетчик;
#Если Клиент Тогда
Если Индикатор.РазрешитьПрерывание Тогда
ОбработкаПрерыванияПользователя();
КонецЕсли;
#КонецЕсли
ОбновитьИндикатор = Истина;
Если Ложь
Или Счетчик < Индикатор.КоличествоПроходов
Или Индикатор.КоличествоПроходов = 0
Тогда
ТекущаяДата = ТекущаяДата();
Если Индикатор.МинимальныйПериодОбновления > 0 Тогда
Если ТекущаяДата >= Индикатор.ДатаСледующегоОбновления Тогда
Индикатор.ДатаСледующегоОбновления = ТекущаяДата + Индикатор.МинимальныйПериодОбновления;
Иначе
ОбновитьИндикатор = Ложь;
КонецЕсли;
КонецЕсли;
Если ОбновитьИндикатор Тогда
Если Индикатор.Шаг > 0 Тогда
Если Счетчик >= Индикатор.СледующийСчетчик Тогда
Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг);
Иначе
ОбновитьИндикатор = Ложь;
КонецЕсли;
//Иначе
// ОбновитьИндикатор = Ложь;
// ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Счетчик + " ";
// Состояние(ТекстСостояния);
КонецЕсли;
КонецЕсли;
Иначе
Если ТипЗнч(Индикатор) <> Тип("СтрокаТаблицыЗначений") Тогда
#Если Клиент Тогда
Состояние("");
#КонецЕсли
ОбновитьИндикатор = Ложь;
КонецЕсли;
КонецЕсли;
Если ОбновитьИндикатор Тогда
Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг);
Если ТипЗнч(Индикатор) = Тип("СтрокаТаблицыЗначений") Тогда
МассивИндикаторов = Индикатор.Владелец();
Иначе
МассивИндикаторов = Новый Массив;
МассивИндикаторов.Добавить(Индикатор);
КонецЕсли;
#Если Клиент Тогда
ТекстСостояния = "";
Для Каждого лИндикатор Из МассивИндикаторов Цикл
Если ТекстСостояния <> "" Тогда
ТекстСостояния = ТекстСостояния + ".>> ";
КонецЕсли;
ТекстСостояния = ТекстСостояния + ПолучитьТекстСостоянияИндикатораЛкс(лИндикатор);
КонецЦикла;
лИндикатор.ТекстСостояния = ТекстСостояния;
Состояние(ТекстСостояния);
#КонецЕсли
КонецЕсли;
КонецПроцедуры // ОбработатьИндикаторЛкс()
Процедура СостояниеЛкс(СтрокаСостояния = "") Экспорт
ирПлатформа = ирКэш.Получить();
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
Если ТаблицаИндикаторов.Количество() > 0 Тогда
Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1];
СтрокаСостояния = Индикатор.ТекстСостояния + ".>> " + СтрокаСостояния;
КонецЕсли;
#Если Клиент Тогда
Состояние(СтрокаСостояния);
#КонецЕсли
КонецПроцедуры
// Функция сравнивает две таблицы значений на идентичность структуры и данных
//
// Параметры
// ТаблицаЗначений1 - ТаблицаЗначений для сравнения
// ТаблицаЗначений2 - ТаблицаЗначений для сравнения
//
// Возвращаемое значение:
// Булево, идентичны или нет две таблицы
//
Функция ТаблицыЗначенийРавныЛкс(ТаблицаЗначений1, ТаблицаЗначений2) Экспорт
Если ТипЗнч(ТаблицаЗначений1) <> Тип("ТаблицаЗначений") ИЛИ ТипЗнч(ТаблицаЗначений2) <> Тип("ТаблицаЗначений") Тогда
Возврат Ложь;
КонецЕсли;
Если ТаблицаЗначений1.Количество() <> ТаблицаЗначений2.Количество() Тогда
Возврат Ложь;
КонецЕсли;
Если ТаблицаЗначений1.Колонки.Количество() <> ТаблицаЗначений2.Колонки.Количество() Тогда
Возврат Ложь;
КонецЕсли;
Для каждого Колонка Из ТаблицаЗначений1.Колонки Цикл
Если ТаблицаЗначений2.Колонки.Найти(Колонка.Имя) = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Для каждого СтрокаТаблицы1 Из ТаблицаЗначений1 Цикл
СтрокаТаблицы2 = ТаблицаЗначений2[ТаблицаЗначений1.Индекс(СтрокаТаблицы1)];
Если СтрокаТаблицы1[Колонка.Имя] <> СтрокаТаблицы2[Колонка.Имя] Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Возврат Истина;
КонецФункции // СравнитьТаблицыЗначений()
#Если Клиент Тогда
Функция ИмяФормыИзСтрокиИнструментаЛкс(Знач СтрокаИнструмента) Экспорт
ИмяВыбраннойФормы = СтрокаИнструмента.ПолноеИмя;
Если Найти(ИмяВыбраннойФормы, "ОбщаяФорма.") <> 1 И Найти(ИмяВыбраннойФормы, ".Форма.") = 0 Тогда
Если Найти(ИмяВыбраннойФормы, "Справочник.") = 1 Тогда
ИмяВыбраннойФормы = ИмяВыбраннойФормы + ".ФормаСписка";
Иначе
ИмяВыбраннойФормы = ИмяВыбраннойФормы + ".Форма";
КонецЕсли;
КонецЕсли;
Возврат ИмяВыбраннойФормы;
КонецФункции
Процедура ПодключитьГлобальныйОбработчикОжиданияЛкс(ИмяМетода, Интервал = 0.1, Однократно = Истина) Экспорт
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ирПортативный.ПолучитьФорму().ПодключитьОбработчикОжидания(ИмяМетода, 0.1, Истина);
Иначе
ПодключитьОбработчикОжидания(ИмяМетода, 0.1, Истина);
КонецЕсли;
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С ФОРМАМИ
// РежимОткрытия - Булево - Истина - Открытие, иначе Сохранение
Функция ВыбратьФайлЛкс(РежимОткрытия = Истина, Расширение = "", ОписаниеФормата = "", Знач ПолноеИмяФайла = "", Знач Каталог = "", Знач КраткоеИмя = "") Экспорт
Если Не ЗначениеЗаполнено(Расширение) Тогда
Расширение = "*";
КонецЕсли;
Если РежимОткрытия = Истина Тогда
РежимДиалога = РежимДиалогаВыбораФайла.Открытие;
Иначе
РежимДиалога = РежимДиалогаВыбораФайла.Сохранение;
КонецЕсли;
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалога);
Если ЗначениеЗаполнено(ПолноеИмяФайла) Тогда
Файл = Новый Файл(ПолноеИмяФайла);
ВыборФайла.Каталог = Файл.Путь;
ВыборФайла.ПолноеИмяФайла = Файл.Имя;
Иначе
ВыборФайла.Каталог = Каталог;
ВыборФайла.ПолноеИмяФайла = КраткоеИмя;
КонецЕсли;
ВыборФайла.Фильтр = ПолучитьСтрокуФильтраДляВыбораФайлаЛкс(Расширение, ОписаниеФормата);
ВыборФайла.Расширение = Расширение;
Если Не ВыборФайла.Выбрать() Тогда
Возврат Неопределено;
КонецЕсли;
Возврат ВыборФайла.ПолноеИмяФайла;
КонецФункции
Функция ВыбратьКаталогВФормеЛкс(Каталог, ФормаДляУстановкиМодифицированности = Неопределено, Заголовок = "") Экспорт
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
ВыборФайла.Каталог = Каталог;
ВыборФайла.Заголовок = Заголовок;
Если Не ВыборФайла.Выбрать() Тогда
Возврат Неопределено;
КонецЕсли;
Каталог = ВыборФайла.Каталог;
Если ФормаДляУстановкиМодифицированности <> Неопределено Тогда
ФормаДляУстановкиМодифицированности.Модифицированность = Истина;
КонецЕсли;
Возврат Каталог;
КонецФункции
Процедура ПолучитьМассивЗначенийПеретаскиванияЛкс(Знач ПараметрыПеретаскивания, выхМассивЗначений, выхТипЗначенияПеретаскивания = Неопределено) Экспорт
ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение;
выхТипЗначенияПеретаскивания = ТипЗнч(ЗначениеПеретаскивания);
Если выхТипЗначенияПеретаскивания = Тип("Массив") Тогда
выхТипЗначенияПеретаскивания = ТипЗнч(ЗначениеПеретаскивания[0]);
выхМассивЗначений = ЗначениеПеретаскивания;
Иначе
выхМассивЗначений = Новый Массив;
выхМассивЗначений.Добавить(ЗначениеПеретаскивания);
КонецЕсли;
КонецПроцедуры
// Параметры:
// КлючеваяКолонка - Строка - используется при отборе
Процедура ИзменитьПометкиВыделенныхСтрокЛкс(Знач ТабличноеПоле, ИмяКолонкиПометки = "Пометка", НовоеЗначениеПометки = Истина, КлючеваяКолонка = "НомерСтроки", СтруктураОтбора = Неопределено) Экспорт
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
Если ВыделенныеСтроки.Количество() <= 1 Тогда
ВыделенныеСтроки = ТабличноеПоле.Значение;
Попытка
ОтборСтрок = ТабличноеПоле.ОтборСтрок;
Исключение
КонецПопытки;
Если ОтборСтрок <> Неопределено Или СтруктураОтбора <> Неопределено Тогда
Построитель = ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ТабличноеПоле, СтруктураОтбора);
#Если Сервер И Не Сервер Тогда
Построитель = Новый ПостроительЗапроса;
#КонецЕсли
Построитель.ВыбранныеПоля.Очистить();
Построитель.ВыбранныеПоля.Добавить(КлючеваяКолонка);
НомераОтобранныхСтрок = Построитель.Результат.Выгрузить();
НомераОтобранныхСтрок.Индексы.Добавить(КлючеваяКолонка);
КонецЕсли;
КонецЕсли;
Для каждого Строка из ВыделенныеСтроки Цикл
ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(Строка);
Если ОформлениеСтроки.Ячейки[ИмяКолонкиПометки].ТолькоПросмотр Тогда
Продолжить;
КонецЕсли;
Если Истина
И НомераОтобранныхСтрок <> Неопределено
И НомераОтобранныхСтрок.Найти(Строка[КлючеваяКолонка], КлючеваяКолонка) = Неопределено
Тогда
Продолжить;
КонецЕсли;
Строка[ИмяКолонкиПометки] = НовоеЗначениеПометки;
КонецЦикла;
КонецПроцедуры
Функция ВыбратьСсылкуЛкс(ИмяТаблицыИлиМДИлиТип, НачальноеЗначениеВыбора = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено) Экспорт
Результат = ОткрытьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип,, ИспользоватьДинамическийСписокИР,, Истина,, НачальноеЗначениеВыбора, Истина);
Возврат Результат;
КонецФункции
Процедура ВыбратьИЗаполнитьТабличнуюЧастьОбъектаБДЛкс(ТаблицаИсточник, НачальноеПолноеИмяОбъекта = "") Экспорт
ФормаВыбораОбъектаБД = ирОбщий.ПолучитьФормуВыбораОбъектаМетаданныхЛкс(,, НачальноеПолноеИмяОбъекта,, Истина,, Истина, Истина,, Истина,,, Истина);
РезультатВыбора = ФормаВыбораОбъектаБД.ОткрытьМодально();
Если РезультатВыбора = Неопределено Тогда
Возврат;
КонецЕсли;
ОбъектМД = ирОбщий.НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(РезультатВыбора.ПолноеИмяОбъекта);
ЭтоНаборЗаписей = ирОбщий.ЛиРегистровыйОбъектМетаданных(ОбъектМД);
Если ЭтоНаборЗаписей Тогда
ПолноеИмяМДСписка = ОбъектМД.ПолноеИмя();
Иначе
ПолноеИмяМДСписка = ОбъектМД.Родитель().ПолноеИмя();
КонецЕсли;
МакетныйОбъект = Неопределено;
ТекущаяГруппаТипаМетаданных = Неопределено;
ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяМДСписка, МакетныйОбъект, ТекущаяГруппаТипаМетаданных);
Если ЭтоНаборЗаписей Тогда
ОбъектБД = МакетныйОбъект;
ТаблицаПриемник = ОбъектБД;
Иначе
ВыбраннаяСтрока = ОткрытьФормуСпискаЛкс(ПолноеИмяМДСписка,,,, Истина,,, Истина);
Если ВыбраннаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
ОбъектБД = ирОбщий.ПолучитьОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(ВыбраннаяСтрока, МакетныйОбъект, ТекущаяГруппаТипаМетаданных, Истина);
ТаблицаПриемник = ОбъектБД[ОбъектМД.Имя];
КонецЕсли;
Если ТаблицаПриемник.Количество() > 0 Тогда
Если ЭтоНаборЗаписей Тогда
ТекстВопроса = "Хотите очистить набор записей в памяти перед заполнением?";
Иначе
ТекстВопроса = "Выбранная табличная часть объекта не пустая. Хотите очистить ее в памяти перед заполнением?";
КонецЕсли;
Ответ = Вопрос(ТекстВопроса, РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Да);
Если Ответ = КодВозвратаДиалога.Да Тогда
ТаблицаПриемник.Очистить();
КонецЕсли;
КонецЕсли;
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИсточник, ТаблицаПриемник);
ОбработкаРедактора = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирРедакторОбъектаБД");
#Если Сервер И Не Сервер Тогда
ОбработкаРедактора = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
ФормаРедактора = ОбработкаРедактора.РедактироватьМодифицированныйОбъект(ОбъектБД);
ФормаРедактора.ПоказатьЯчейкуДанныхОбъекта(РезультатВыбора.ПолноеИмяОбъекта);
КонецПроцедуры
// <Описание процедуры>
//
// Параметры:
// <Параметр1> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>.
//
Функция СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс(Значение1, Значение2, Модально = Ложь,
Название1 = Неопределено, Название2 = Неопределено, СравнениеФайлов = Неопределено, ПолучатьXMLПредставлениеДляНеизвестныхТипов = Истина) Экспорт
Если Истина
И ТипЗнч(Значение1) = Тип("ТаблицаЗначений")
И ТипЗнч(Значение2) = Тип("ТаблицаЗначений")
Тогда
Обработка = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирСравнениеТаблиц");
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирСравнениеТаблиц.Создать();
#КонецЕсли
Обработка.Таблица1 = Значение1;
Обработка.Таблица2 = Значение2;
Обработка.ОбновитьСопоставлениеКолонок();
Обработка.ЗаполнитьСопоставлениеКолонок();
Обработка.ПодобратьКлючевыеИСравниваемыеКолонки();
ФормаСравнителя = Обработка.ПолучитьФорму();
ФормаСравнителя.РежимРедактора = Истина;
ФормаСравнителя.Открыть();
Возврат ФормаСравнителя.СравнитьТаблицы();
КонецЕсли;
Путь1 = ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение1, Название1, ПолучатьXMLПредставлениеДляНеизвестныхТипов);
Путь2 = ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение2, Название2, ПолучатьXMLПредставлениеДляНеизвестныхТипов);
// Думал, так будет использовать существующее окно, но этого не происходит. Пока оставил, может потом появится.
Если СравнениеФайлов = Неопределено Тогда
СравнениеФайлов = Новый СравнениеФайлов;
КонецЕсли;
СравнениеФайлов.ПервыйФайл = Путь1;
СравнениеФайлов.ВторойФайл = Путь2;
СравнениеФайлов.ИгнорироватьПустоеПространство = Ложь;
Если Истина
И ТипЗнч(Значение1) = Тип("ТабличныйДокумент")
И ТипЗнч(Значение2) = Тип("ТабличныйДокумент")
Тогда
СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТабличныйДокумент;
Иначе
СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТекстовыйДокумент;
КонецЕсли;
Если Модально Тогда
СравнениеФайлов.ПоказатьРазличияМодально();
Иначе
СравнениеФайлов.ПоказатьРазличия();
КонецЕсли;
Возврат СравнениеФайлов.Сравнить();
КонецФункции // СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс()
// Сравнивает табличный документ, полученный из элемента управления с предыдущим.
//
// Параметры:
// СравнительТабличныхДокументов – Массив, *Неопределено – переменная для хранения предыдущего табличного документа.
// ЭлементУправления – ТабличноеПоле, ПолеТабличногоДокумента – откуда получаем содержимое.
//
Процедура СравнитьСодержимоеЭлементаУправленияЛкс(ЭлементУправления) Экспорт
Если ТипЗнч(ЭлементУправления) = Тип("ПолеТекстовогоДокумента") Тогда
СравниваемыйДокумент = Новый ТекстовыйДокумент;
СравниваемыйДокумент.УстановитьТекст(ЭлементУправления.ПолучитьТекст());
ИначеЕсли ТипЗнч(ЭлементУправления) = Тип("ПолеВвода") Тогда
СравниваемыйДокумент = Новый ТекстовыйДокумент;
СравниваемыйДокумент.УстановитьТекст(ЭлементУправления.Значение);
ИначеЕсли ТипЗнч(ЭлементУправления) = Тип("ТабличноеПоле") Тогда
Ответ = Вопрос("Использовать только данные (без оформления)?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Нет Тогда
СравниваемыйДокумент = ВывестиТабличноеПолеКоллекцииВТабличныйДокументЛкс(ЭлементУправления, Неопределено);
Иначе
СравниваемыйДокумент = ЭлементУправления.Значение;
КонецЕсли;
ИначеЕсли ТипЗнч(ЭлементУправления) = Тип("ПолеТабличногоДокумента") Тогда
СравниваемыйДокумент = ЭлементУправления.ПолучитьОбласть();
Иначе
Сообщить("Неподдерживаемый тип элемента управления для сравнения");
Возврат;
КонецЕсли;
МассивСравнения = ирКэш.ПолучитьБуферСравненияЛкс("" + ТипЗнч(СравниваемыйДокумент));
Если МассивСравнения.Количество() = 2 Тогда
МассивСравнения.Удалить(0);
КонецЕсли;
МассивСравнения.Добавить(СравниваемыйДокумент);
Если МассивСравнения.Количество() = 2 Тогда
Ответ = Вопрос("Сравнить с предыдущим?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Нет Тогда
Возврат;
КонецЕсли;
СравниваемыйДокумент1 = МассивСравнения[0];
СравниваемыйДокумент2 = МассивСравнения[1];
СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс(СравниваемыйДокумент1, СравниваемыйДокумент2);
КонецЕсли;
КонецПроцедуры
Функция ВывестиТабличноеПолеКоллекцииВТабличныйДокументЛкс(Знач ТабличноеПоле, ВыводБезОформления = Ложь) Экспорт
Если ВыводБезОформления = Неопределено Тогда
Ответ = Вопрос("Быстрый вывод (без оформления)?", РежимДиалогаВопрос.ДаНет);
ВыводБезОформления = Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если ВыводБезОформления Тогда
Результат = ВывестиТаблицуВТабличныйДокументЛкс(ТабличноеПоле.Значение);
Иначе
Результат = Новый ТабличныйДокумент;
НомерКолонки = 1;
НомерСтроки = 1;
ОбластьТаблицы = Результат.Область();
ОбластьТаблицы.ЦветРамки = ЦветаСтиля.ЦветРамки;
ОбластьЗаголовков = Результат.Область(НомерСтроки, 0, НомерСтроки, 0);
ОбластьЗаголовков.ЦветФона = ТабличноеПоле.ЦветФонаШапки;
ОбластьЗаголовков.ЦветТекста = ТабличноеПоле.ЦветТекстаШапки;
Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл
Если Колонка.Имя = ирКэш.ИмяКолонкиНомерСтрокиЛкс() Тогда
Продолжить;
КонецЕсли;
Если Колонка.Видимость Тогда
ОбластьЗаголовка = Результат.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки);
ОбластьЗаголовка.Текст = Колонка.ТекстШапки;
ОбластьЗаголовка.ЦветФона = Колонка.ЦветФонаШапки;
ОбластьЗаголовка.ЦветТекста = Колонка.ЦветТекстаШапки;
//ШиринаКолонки = Колонка.Ширина;
//Если ШиринаКолонки <= 0 Тогда
// Если ЗначениеЗаполнено(Колонка.Данные) Тогда
// ШиринаКолонки = ТабличноеПоле.Значение.Колонки[Колонка.Данные].Ширина;
// Если ШиринаКолонки = 0 Тогда
// ШиринаКолонки = 30;
// КонецЕсли;
// Иначе
// ШиринаКолонки = 30;
// КонецЕсли;
//КонецЕсли;
//ШиринаКолонки = Мин(ШиринаКолонки, 50);
//ШиринаКолонки = Макс(ШиринаКолонки, 10);
//ОбластьЗаголовка.ШиринаКолонки = ШиринаКолонки;
ОбластьЗаголовка.ЦветФона = ЦветаСтиля.ЦветФонаШапкиТаблицы;
ОбластьЗаголовка.ЦветТекста = ЦветаСтиля.ЦветТекстаШапкиТаблицы;
УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(ОбластьЗаголовка, ТабличноеПоле);
НомерКолонки = НомерКолонки + 1;
КонецЕсли;
КонецЦикла;
Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда
КоллекцияСтрок = ТабличноеПоле.Значение.Строки;
Иначе
КоллекцияСтрок = ТабличноеПоле.Значение;
КонецЕсли;
ВывестиСтрокиТабличногоПоляКоллекцииВТабличныйДокументЛкс(КоллекцияСтрок, НомерСтроки, Результат, ТабличноеПоле);
УстановитьАвтоширинуКолонокТабличногоДокументаЛкс(Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ВывестиСтрокиТабличногоПоляКоллекцииВТабличныйДокументЛкс(Знач КоллекцияСтрок, НомерСтроки, Знач Результат, Знач ТабличноеПоле, Смещение = "")
#Если Сервер И Не Сервер Тогда
Результат = Новый ТабличныйДокумент;
#КонецЕсли
Индикатор = ПолучитьИндикаторПроцессаЛкс(КоллекцияСтрок.Количество());
Для Каждого СтрокаИсточника Из КоллекцияСтрок Цикл
ОбработатьИндикаторЛкс(Индикатор);
НомерСтроки = НомерСтроки + 1;
ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(СтрокаИсточника);
ОбластьСтроки = Результат.Область(НомерСтроки, 0, НомерСтроки, 0);
//ЗаполнитьЗначенияСвойств(ОбластьСтроки, ОформлениеСтроки, "Шрифт, ЦветТекста, ЦветФона");
НомерКолонки = 1;
Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл
Если Колонка.Имя = ирКэш.ИмяКолонкиНомерСтрокиЛкс() Тогда
Продолжить;
КонецЕсли;
Если Колонка.Видимость И ОформлениеСтроки <> Неопределено Тогда // Для строк ТЧ почему то ОформлениеСтроки = Неопределено, видимо баг платформы
ОформлениеЯчейки = ОформлениеСтроки.Ячейки[Колонка.Имя];
ОбластьЯчейки = Результат.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки);
ЗаполнитьЗначенияСвойств(ОбластьЯчейки, ОформлениеЯчейки, "Шрифт, ЦветТекста, ЦветФона");
Если ОформлениеЯчейки.ОтображатьТекст Тогда
ОбластьЯчейки.Текст = Смещение + ОформлениеЯчейки.Текст;
ИначеЕсли ОформлениеЯчейки.ОтображатьФлажок Тогда
ОбластьЯчейки.Текст = Смещение + ОформлениеЯчейки.ЗначениеФлажка;
КонецЕсли;
Если ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ОформлениеЯчейки.Значение, Ложь) Тогда
ОбластьЯчейки.Расшифровка = ОформлениеЯчейки.Значение;
КонецЕсли;
УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(ОбластьЯчейки, ТабличноеПоле);
НомерКолонки = НомерКолонки + 1;
КонецЕсли;
КонецЦикла;
Если ТипЗнч(СтрокаИсточника) = Тип("СтрокаДереваЗначений") И ТабличноеПоле.Развернут(СтрокаИсточника) Тогда
Результат.НачатьГруппуСтрок();
ВывестиСтрокиТабличногоПоляКоллекцииВТабличныйДокументЛкс(СтрокаИсточника.Строки, НомерСтроки, Результат, ТабличноеПоле, Смещение + " ");
Результат.ЗакончитьГруппуСтрок();
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
КонецПроцедуры
Процедура ВывестиТабличноеПолеВТабличныйДокументЛкс(Знач ТабличноеПоле, Знач ВыводБезОформления = Неопределено) Экспорт
ТабличныйДокумент = ВывестиТабличноеПолеКоллекцииВТабличныйДокументЛкс(ТабличноеПоле, ВыводБезОформления);
ОткрытьФормуПроизвольногоЗначенияЛкс(ТабличныйДокумент,,,, Ложь);
КонецПроцедуры
Процедура УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(Знач ОбластьЯчейки, Знач ЭлементУправления) Экспорт
ЛинияСплошная = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная);
Если ЭлементУправления.ГоризонтальныеЛинии Тогда
ОбластьЯчейки.ГраницаСверху = ЛинияСплошная;
ОбластьЯчейки.ГраницаСнизу = ЛинияСплошная;
КонецЕсли;
Если ЭлементУправления.ВертикальныеЛинии Тогда
ОбластьЯчейки.ГраницаСлева = ЛинияСплошная;
ОбластьЯчейки.ГраницаСправа = ЛинияСплошная;
КонецЕсли;
КонецПроцедуры // ЛксСравнитьСодержимоеПоля()
Процедура РасширитьКолонкиТабличногоПоляЛкс(ТабличноеПоле, УважатьЗапретИзмененияРазмера = Истина) Экспорт
//ВведенноеЗначениеШирины = 10;
//Если ВвестиЧисло(ВведенноеЗначениеШирины, "Введите новую ширину колонки для всех колонок", 5, 0) Тогда
// УстановитьСвойствоВКоллекцииЛкс(ТабличноеПоле.Колонки, , "-Ширина", ВведенноеЗначениеШирины);
//КонецЕсли;
Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл
Ширина = Колонка.Ширина;
Если Ширина = 0 Тогда
// Антибаг платформы.
Ширина = 10;
КонецЕсли;
Если Ложь
Или Не УважатьЗапретИзмененияРазмера
Или Колонка.ИзменениеРазмера = ИзменениеРазмераКолонки.Изменять
Тогда
НоваяШирина = Ширина + 3;
Колонка.Ширина = НоваяШирина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // РасширитьКолонкиТабличногоПоляЛкс()
// Пропорционально сжимает ширины колонок табличного поля.
//
// Параметры:
// ТабличноеПоле – ТабличноеПоле;
// Сжатие – Число, *2 – коэффициент сжатия;
// УважатьЗапретИзмененияРазмера – Булево, *Истина – не сжимать колонки с запретом изменения размера;
//
Процедура СжатьКолонкиТабличногоПоляЛкс(ТабличноеПоле, Сжатие = 2, УважатьЗапретИзмененияРазмера = Истина) Экспорт
Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл
Ширина = Колонка.Ширина;
Если Ширина = 0 Тогда
// Антибаг платформы.
Ширина = 10;
КонецЕсли;
Если Ложь
Или Не УважатьЗапретИзмененияРазмера
Или Колонка.ИзменениеРазмера = ИзменениеРазмераКолонки.Изменять
Тогда
НоваяШирина = Ширина / Сжатие;
НоваяШирина = Макс(НоваяШирина, 1);
Колонка.Ширина = НоваяШирина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // СжатьКолонкиТабличногоПоляЛкс()
// Интерактивно записывает значение в элемент управления. Интерактивность заключается в срабатывании
// события ПриИзменении у элемента управления.
//
// Параметры:
// ЭлементУправления – ЭлементУправления – которому присваиваем значение;
// Значение – Произвольный – присваиваемое значение;
// *ФормаИнициатор - Форма, *Неопределено - которая будет использована в качестве инициатора события;
// если не указана, то будет создана временная форма-пустышка.
//
// Результат - Булево - успешно ли значение установлено
Функция ИнтерактивноЗаписатьВЭлементУправленияЛкс(ЭлементУправления, Знач Значение, Знач ФормаИнициатор = Неопределено) Экспорт
Если ФормаИнициатор = Неопределено Тогда
ФормаИнициатор = ирКэш.Получить().ПолучитьФорму("Пустышка", ЭлементУправления);
Иначе
СтарыйВладелец = ФормаИнициатор.ВладелецФормы;
СтарыйЗакрыватьПриВыборе = ФормаИнициатор.ЗакрыватьПриВыборе;
ФормаИнициатор.ВладелецФормы = ЭлементУправления;
ФормаИнициатор.ЗакрыватьПриВыборе = Ложь;
КонецЕсли;
НовоеЗначение = ЭлементУправления.ОграничениеТипа.ПривестиЗначение(Значение);
Если Ложь
Или НовоеЗначение <> Значение
Или ЭлементУправления.ТолькоПросмотр
Тогда
Возврат Ложь;
КонецЕсли;
ФормаИнициатор.ОповеститьОВыборе(Значение);
Если СтарыйЗакрыватьПриВыборе <> Неопределено Тогда
ФормаИнициатор.ВладелецФормы = СтарыйВладелец;
ФормаИнициатор.ЗакрыватьПриВыборе = СтарыйЗакрыватьПриВыборе;
КонецЕсли;
Попытка
Результат = ЭлементУправления.Значение = Значение;
Исключение
// Это поле управляемой формы
Результат = Истина;
КонецПопытки;
Возврат Результат;
КонецФункции // ИнтерактивноЗаписатьВЭлементУправленияЛкс()
// Интерактивно записывает значение в элемент управления (только поле ввода) колонки табличного поля.
// Интерактивность заключается в срабатывании события ПриИзменении у элемента управления.
// Строка табличного поля должна находиться в режиме редактирования,
// иначе никаких изменений данных не произойдет.
//
// Параметры:
// ТабличноеПоле - ТабличноеПоле - строка которого редактируется;
// Колонка – КолонкаТабличногоПоля – в элемент управления которой записываем;
// Значение – Произвольный – присваиваемое значение;
// *ФормаИнициатор - Форма, *Неопределено - которая будет использована в качестве инициатора события;
// если не указана, то будет создана временная форма-пустышка;
// *ВосстанавитьТекущуюКолонку – Булево, *Истина;
// *ВключитьРежимРедактирования – Булево, *Истина.
//
Процедура ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Знач Колонка, Знач Значение, Знач ФормаИнициатор = Неопределено,
Знач ВосстанавитьТекущуюКолонку = Истина, Знач ВключитьРежимРедактирования = Истина, Знач КонтролироватьТекущиеДанные = Ложь) Экспорт
ЭлементУправления = Колонка.ЭлементУправления;
Если ТипЗнч(ЭлементУправления) <> Тип("ПолеВвода") Тогда
Возврат;
КонецЕсли;
ХмлТип = XMLТипЗнч(ЭлементУправления.Значение);
Если Истина
И ХмлТип <> Неопределено
И Найти(ХмлТип.ИмяТипа, "CatalogRef.") > 0
Тогда
Если Ложь
Или (Истина
И ЗначениеЗаполнено(ЭлементУправления.ВыборПоВладельцу)
И Значение.Владелец <> ЭлементУправления.ВыборПоВладельцу)
Или (Истина
И ЭлементУправления.ВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Элементы
И Значение.ЭтоГруппа)
Или (Истина
И ЭлементУправления.ВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Группы
И Не Значение.ЭтоГруппа)
Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Если ВосстанавитьТекущуюКолонку Тогда
СтараяТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка;
КонецЕсли;
ПрисвоитьЕслиНеРавноЛкс(ТабличноеПоле.ТекущаяКолонка, Колонка);
Если ВключитьРежимРедактирования Тогда
ТабличноеПоле.ИзменитьСтроку();
КонецЕсли;
ИнтерактивноЗаписатьВЭлементУправленияЛкс(ЭлементУправления, Значение, ФормаИнициатор);
Если Истина
//И КонтролироватьТекущиеДанные // На 8.3.8 значение в свойство строки почему то не попадает
И Колонка.Данные <> ""
Тогда
Попытка
ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные[Колонка.Данные];
ИмяДанныхПравильное = Истина;
Исключение
// В табличных полях компоновки
ИмяДанныхПравильное = Ложь;
КонецПопытки;
Если ИмяДанныхПравильное Тогда
Если Значение <> ЗначениеЯчейки Тогда
// Такое случается в некоторых состояниях формы (пока Открыта() = Ложь)
// Также это срабатывает для неподдерживаемых типов в поле ввода
ТабличноеПоле.ТекущиеДанные[Колонка.Данные] = Значение;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ВосстанавитьТекущуюКолонку Тогда
ПрисвоитьЕслиНеРавноЛкс(ТабличноеПоле.ТекущаяКолонка, СтараяТекущаяКолонка);
КонецЕсли;
КонецПроцедуры // ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс()
// Проверяет колонку табличного поля на интерактивную доступность.
//
// Параметры:
// пКолонка – КолонкаТабличногоПоля.
//
// Возвращаемое значение:
// Истина - колонка интерактивно доступна;
// Ложь - иначе.
//
Функция ЛиИнтерактивноДоступнаяКолонкаЛкс(пКолонка) Экспорт
Если Истина
И пКолонка.Доступность
И пКолонка.Видимость
И Не пКолонка.ТолькоПросмотр
И (Ложь
Или пКолонка.ДанныеФлажка <> ""
Или (Истина
И пКолонка.ЭлементУправления <> Неопределено
И пКолонка.ЭлементУправления.Доступность))
Тогда
Попытка
Если пКолонка.ЭлементУправления.ТолькоПросмотр Тогда
Возврат Ложь;
КонецЕсли;
Исключение
КонецПопытки;
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиИнтерактивноДоступнаяКолонкаЛкс()
// Копирует привязки между элементами форм.
//
// Параметры:
// пФорма – Форма – в которую копируем;
// ЭлементПриемник – ЭлементУправления;
// ЭлементИсточник – ЭлементУправления.
//
Процедура СкопироватьПривязкиЛкс(пФорма, ЭлементПриемник, ЭлементИсточник) Экспорт
Перем ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент, ГраницаВторогоЭлемента;
Границы = Новый Массив;
Границы.Добавить(ГраницаЭлементаУправления.Верх);
Границы.Добавить(ГраницаЭлементаУправления.Низ);
Границы.Добавить(ГраницаЭлементаУправления.Лево);
Границы.Добавить(ГраницаЭлементаУправления.Право);
Для Каждого Граница Из Границы Цикл
ЭлементИсточник.ПолучитьПривязку( Граница, ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент,
ГраницаВторогоЭлемента);
Если ПервыйЭлемент <> Неопределено Тогда
ПервыйЭлемент = пФорма.ЭлементыФормы.Найти(ПервыйЭлемент.Имя);
Если ПервыйЭлемент = Неопределено Тогда
ПервыйЭлемент = пФорма.Панель;
КонецЕсли;
КонецЕсли;
Если ВторойЭлемент <> Неопределено Тогда
ВторойЭлемент = пФорма.ЭлементыФормы.Найти(ВторойЭлемент.Имя);
Если ВторойЭлемент = Неопределено Тогда
ВторойЭлемент = пФорма.Панель;
КонецЕсли;
КонецЕсли;
ЭлементПриемник.УстановитьПривязку(Граница, ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент,
ГраницаВторогоЭлемента);
КонецЦикла;
КонецПроцедуры // СкопироватьПривязкиЛкс()
// Заполняет форму по ее макету. Используется для динамического добавления элементов
// в типовые формы, чтобы облегчить их обновление. Макет формы, если явно не указан,
// ищется среди форм объекта метаданных формы по имени "Лкс"+<ИмяФормы>+"Макет".
// Для измененных элементов в макете к имени следует добавлять через "_" суффиксы
// в соответствии с изменениями: "Привязка", "Размер", "Позиция", "Внутри" (для коллекций).
// Следует вызывать в обработчике ПередОткрытием формы.
// Ограничения.
// 1. Без явного указания макета работает только для основной формы объекта.
// 2. Нельзя добавлять элементы в панели и поля табличного документа, т.к. у элемента нельзя
// определить родителя.
// 3. Нельзя, чтобы форма и макет имели разные размеры. Обрабатываеся.
// 4. Нельзя добавлять и изменять элементы, привязанные косвенно к низу формы.
// 5. Иногда элементы, привязанные косвенно к правой границе формы неверно располагаются.
// 6. Нельзя, чтобы оригинальные имена измененных элементов включали "_". Обрабатывается.
//
// Параметры:
// пФорма – Форма – которую настраиваем;
// *пМакет – Форма - макет, по которому настраиваем.
//
Процедура НастроитьФормуПоМакетуЛкс(пФорма, пМакетФормы) Экспорт
МакетФормы = пМакетФормы;
СоответствиеПривязки = Новый Соответствие;
Если Ложь
Или пФорма.Высота <> МакетФормы.Высота
Или пФорма.Ширина <> МакетФормы.Ширина
Тогда
Сообщить("Не соответствие размеров формы при заполнении по макету",
СтатусСообщения.Важное);
КонецЕсли;
//ЗаполнитьЗначенияСвойств(пФорма, МакетФормы, , "ДокументОбъект, Данные, ЭтотОбъект, Панель, ЭлементыФормы");
//ЗаполнитьЗначенияСвойств(пФорма.Панель, МакетФормы.Панель, , "Данные");
ЭлементыФормы = пФорма.ЭлементыФормы;
Для Каждого ЭлементМакета Из МакетФормы.ЭлементыФормы Цикл
ИмяЭлемента = ЭлементМакета.Имя;
ЭлементФормы = ЭлементыФормы.Добавить(ТипЗнч(ЭлементМакета), ИмяЭлемента, Ложь, пФорма.Панель);
Если ТипЗнч(ЭлементМакета) = Тип("КоманднаяПанель") Тогда
ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные, Кнопки, ИсточникДействий");
Если ЭлементМакета.ИсточникДействий = пМакетФормы Тогда
ЭлементФормы.ИсточникДействий = пФорма;
КонецЕсли;
ИначеЕсли ТипЗнч(ЭлементМакета) = Тип("ТабличноеПоле") Тогда
ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные, ТекущаяСтрока");
Иначе
ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные");
КонецЕсли;
СоответствиеПривязки.Вставить(ЭлементФормы, ЭлементМакета);
КонецЦикла;
// Установи новые привязки
Для Каждого Привязка Из СоответствиеПривязки Цикл
ЭлементФормы = Привязка.Ключ;
ЭлементМакета = Привязка.Значение;
СкопироватьПривязкиЛкс(пФорма, ЭлементФормы, ЭлементМакета);
КонецЦикла;
КонецПроцедуры // НастроитьФормуПоМакетуЛкс()
// Изменяет свернутость всех строк табличного поля дерева значений.
//
// Параметры:
// ДЗ – ТабличноеПоле – связанное с деревом значений и включенным режимом Дерево;
// Свернуть – Булево, *Истина - новое значение свернутости.
//
Процедура ДеревоЗначенийСвернутьЛкс(ДЗ, Свернуть = Ложь, Строки = Неопределено) Экспорт
Если Свернуть Тогда
ПредставлениеПроцесса = "Сворачиваем строки дерева";
Иначе
ПредставлениеПроцесса = "Разворачиваем строки дерева";
КонецЕсли;
Если Строки = Неопределено Тогда
Строки = ДЗ.Значение.Строки;
КонецЕсли;
Индикатор = ПолучитьИндикаторПроцессаЛкс(Строки.Количество(), ПредставлениеПроцесса);
Для Каждого СтрокаДерева Из Строки Цикл
ОбработатьИндикаторЛкс(Индикатор);
Если Истина
И Свернуть
И ДЗ.Развернут(СтрокаДерева)
Тогда
ДЗ.Свернуть(СтрокаДерева);
ИначеЕсли Истина
И Не Свернуть
И Не ДЗ.Развернут(СтрокаДерева)
Тогда
ДЗ.Развернуть(СтрокаДерева, Истина);
КонецЕсли;
//ДеревоЗначенийСвернутьЛкс(ДЗ, Свернуть, СтрокаДерева.Строки, Индикатор);
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс(Индикатор);
КонецПроцедуры
Процедура ДеревоКонсолиПроверкаПеретаскиванияЛкс(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка, ИмяТипаСроки) Экспорт
Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Структура") Тогда
ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение;
Если ЗначениеПеретаскивания.Свойство("Тип") Тогда
Если НРег(ЗначениеПеретаскивания.Тип) = Нрег(ИмяТипаСроки) Тогда
ТекущийРодитель = Строка;
Пока ТекущийРодитель <> Неопределено Цикл
Если ТекущийРодитель = ЗначениеПеретаскивания.Значение Тогда
ПараметрыПеретаскивания.ДопустимыеДействия = ДопустимыеДействияПеретаскивания.НеОбрабатывать;
Возврат;
КонецЕсли;
ТекущийРодитель = ТекущийРодитель.Родитель;
КонецЦикла;
СтандартнаяОбработка = Ложь;
ПараметрыПеретаскивания.ДопустимыеДействия = ДопустимыеДействияПеретаскивания.Копирование;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ДеревоКонсолиПеретаскиваниеЛкс(ЭтаФорма, Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка, ИмяТипаСроки, ИмяПоляНаименования) Экспорт
Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Структура") Тогда
ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение;
Если ЗначениеПеретаскивания.Свойство("Тип") Тогда
Если НРег(ЗначениеПеретаскивания.Тип) = Нрег(ИмяТипаСроки) Тогда
СтандартнаяОбработка = Ложь;
Если Строка <> Неопределено Тогда
РодительскаяСтрока = Строка;
Иначе
РодительскаяСтрока = Элемент.Значение;
КонецЕсли;
НоваяСтрокаЗапросов = РодительскаяСтрока.Строки.Добавить();
СкопироватьСтрокиДереваЛкс(ЗначениеПеретаскивания.Значение, НоваяСтрокаЗапросов);
Если ЗначениеПеретаскивания.Значение.Родитель = НоваяСтрокаЗапросов.Родитель Тогда
НоваяСтрокаЗапросов[ИмяПоляНаименования] = ПолучитьАвтоУникальноеИмяВКоллекцииСтрокЛкс(РодительскаяСтрока.Строки,
ЗначениеПеретаскивания.Значение[ИмяПоляНаименования], ИмяПоляНаименования, Ложь);
КонецЕсли;
Элемент.ТекущаяСтрока = НоваяСтрокаЗапросов;
Если ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Перемещение Тогда
РодительСтроки = ЗначениеПеретаскивания.Значение.Родитель;
Если РодительСтроки = Неопределено Тогда
РодительСтроки = Элемент.Значение;
Если ЗначениеПеретаскивания.Значение.Владелец() <> РодительСтроки Тогда
// Строка другой формы. Не будем ее удалять
РодительСтроки = Неопределено;
КонецЕсли;
КонецЕсли;
Если РодительСтроки <> Неопределено Тогда
РодительСтроки.Строки.Удалить(ЗначениеПеретаскивания.Значение);
КонецЕсли;
КонецЕсли;
Если Элемент.ИзменяетДанные Тогда
ЭтаФорма.Модифицированность = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ДеревоКонсолиНачалоПеретаскиванияЛкс(Элемент, ПараметрыПеретаскивания, Выполнение, ИмяТипаСроки) Экспорт
Элемент.ТекущаяСтрока = Элемент.ТекущаяСтрока; // Для сохранения изменений в строке
ЗначениеПеретаскивания = Новый Структура("Тип, Значение", ИмяТипаСроки, Элемент.ТекущаяСтрока);
ПараметрыПеретаскивания.Значение = ЗначениеПеретаскивания;
КонецПроцедуры
Процедура СкопироватьСтрокиДереваЛкс(СтрокаИсточник, СтрокаПриемник, СтопСтрока = Неопределено) Экспорт
Если СтопСтрока = Неопределено Тогда
Если СтрокаПриемник.Родитель <> Неопределено Тогда
СтопСтрока = СтрокаПриемник.Родитель;
КонецЕсли;
КонецЕсли;
Дерево = СтрокаПриемник.Владелец();
Для Каждого Колонка Из Дерево.Колонки Цикл
СтрокаПриемник[Колонка.Имя] = ПолучитьКопиюОбъектаЛкс(СтрокаИсточник[Колонка.Имя]);
КонецЦикла;
Для Каждого Строка Из СтрокаИсточник.Строки Цикл
Если Строка = СтопСтрока Тогда
Продолжить;
КонецЕсли;
НоваяСтрока = СтрокаПриемник.Строки.Добавить();
СкопироватьСтрокиДереваЛкс(Строка, НоваяСтрока, СтопСтрока);
КонецЦикла;
КонецПроцедуры
Процедура ИзменитьСвернутостьЛкс(Видимость, ГлавныйЭлемент, Разделитель, Панель, Направление, ПодчиненныйЭлемент = Неопределено,
ПропорциональныйРазмер = Истина) Экспорт
Если Разделитель = Неопределено Тогда
Разделитель = ГлавныйЭлемент;
КонецЕсли;
Если ТипЗнч(Разделитель) = Тип("Разделитель") Тогда
Если Разделитель.Ориентация = Ориентация.Авто Тогда
// возможно это касается только свертки вправо
Сообщить("Корректная работа свертки с разделителем """ + Разделитель.Имя + """ с ориентацией Авто невозможна из-за ошибки платформы",
СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
//ПервыйЭлемент = 0;
//ГраницаПервогоЭлемента = 0;
//ВторойЭлемент = 0;
//ГраницаВторогоЭлемента = 0;
Если СтрокиРавныЛкс(Направление, "лево") Тогда
Если Видимость Тогда
// откроем
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право);
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет;
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет;
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право);
Если ПропорциональныйРазмер Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Лево, Панель,
ГраницаЭлементаУправления.Право);
Иначе
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Право);
КонецЕсли;
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, Разделитель, ГраницаЭлементаУправления.Лево);
КонецЕсли;
//Разделитель.Ширина = ШиринаРазделителя;
Иначе
// скроем
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ГлавныйЭлемент, ГраницаЭлементаУправления.Право);
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Лево;
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Лево;
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ГлавныйЭлемент, ГраницаЭлементаУправления.Право);
КонецЕсли;
КонецЕсли;
ИначеЕсли СтрокиРавныЛкс(Направление, "право") Тогда
Если Видимость Тогда
// откроем
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, Разделитель, ГраницаЭлементаУправления.Лево);
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет;
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет;
Если ПропорциональныйРазмер Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Лево, Панель,
ГраницаЭлементаУправления.Право);
Иначе
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Право);
КонецЕсли;
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право);
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право);
//Разделитель.Ширина = ШиринаРазделителя;
КонецЕсли;
Иначе
// Скроем
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, ГлавныйЭлемент, ГраницаЭлементаУправления.Лево);
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Право;
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Право;
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, ГлавныйЭлемент, ГраницаЭлементаУправления.Лево);
КонецЕсли;
КонецЕсли;
ИначеЕсли СтрокиРавныЛкс(Направление, "низ") Тогда
Если Видимость Тогда
// Откроем
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ);
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет;
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет;
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ);
Если ПропорциональныйРазмер Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Верх, Панель,
ГраницаЭлементаУправления.Низ);
Иначе
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Низ);
КонецЕсли;
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ);
КонецЕсли;
//Разделитель.Высота = ШиринаРазделителя;
Иначе // Скроем
Если Разделитель <> ГлавныйЭлемент Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх);
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ГлавныйЭлемент, ГраницаЭлементаУправления.Верх);
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Низ;
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Низ;
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ГлавныйЭлемент, ГраницаЭлементаУправления.Верх);
КонецЕсли;
КонецЕсли;
ИначеЕсли СтрокиРавныЛкс(Направление, "верх") Тогда
Если Видимость Тогда
// Откроем
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Разделитель, ГраницаЭлементаУправления.Верх);
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет;
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет;
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ);
Если ПропорциональныйРазмер Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Верх, Панель,
ГраницаЭлементаУправления.Низ);
Иначе
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Низ);
КонецЕсли;
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Разделитель, ГраницаЭлементаУправления.Верх);
//Разделитель.Высота = ШиринаРазделителя;
КонецЕсли;
Иначе // Скроем
Если Разделитель <> ГлавныйЭлемент Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ);
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ГлавныйЭлемент, ГраницаЭлементаУправления.Низ);
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Верх;
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Верх;
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ГлавныйЭлемент, ГраницаЭлементаУправления.Низ);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры // ИзменитьСвернутостьЛкс()
Процедура УстановитьТекстСОткатомЛкс(ПолеТекста, Текст) Экспорт
СтарыйТекст = ПолеТекста.ПолучитьТекст();
ПолеТекста.УстановитьГраницыВыделения(1, СтрДлина(СтарыйТекст) + 1);
ПолеТекста.ВыделенныйТекст = Текст;
КонецПроцедуры // УстановитьТекстСОткатомЛкс()
// Основным элементом страницы считается одноименный с ней элемент формы.
//
Процедура ОбновитьЗаголовкиСтраницПанелейЛкс(ЭтаФорма) Экспорт
ЭлементыФормы = ЭтаФорма.ЭлементыФормы;
Для Каждого ЭлементФормы Из ЭлементыФормы Цикл
Если ТипЗнч(ЭлементФормы) <> Тип("Панель") Тогда
Продолжить;
КонецЕсли;
ОбновитьЗаголовкиСтраницПанелиЛкс(ЭлементыФормы, ЭлементФормы);
КонецЦикла;
КонецПроцедуры // ОбновитьЗаголовкиСтраницПанелейЛкс()
Функция ОбновитьЗаголовкиСтраницПанелиЛкс(ЭлементыФормы, Панель) Экспорт
ТабличноеПолеСтраниц = ЭлементыФормы.Найти("Страницы" + Панель.Имя);
Если ТипЗнч(ТабличноеПолеСтраниц) = Тип("ТабличноеПоле") Тогда
ТаблицаСтраниц = ТабличноеПолеСтраниц.Значение;
Иначе
ТаблицаСтраниц = Неопределено;
КонецЕсли;
ОбщееКоличество = 0;
Для Каждого Страница Из Панель.Страницы Цикл
Если Страница.Имя = "" Тогда // Служебная страница. Появляется после очистки страниц.
Продолжить;
КонецЕсли;
ЭУ = ЭлементыФормы.Найти(Страница.Имя);
Если ЭУ = Неопределено Тогда
Продолжить;
КонецЕсли;
Если Ложь
Или Страница.Значение = Null
Или (Истина
И ТипЗнч(Страница.Значение) = Тип("Структура")
И Страница.Значение.Свойство("Рассчитано")
И Не Страница.Значение.Рассчитано)
Тогда
Количество = "-";
Иначе
Суффикс = "";
Количество = Неопределено;
Если ТипЗнч(ЭУ) = Тип("ТабличноеПоле") Тогда
ЗначениеЭУ = ЭУ.Значение;
Если Количество = Неопределено Тогда
Попытка
Количество = ЗначениеЭУ.Количество();
Исключение КонецПопытки;
КонецЕсли;
Если Количество = Неопределено Тогда
Попытка
Количество = ЗначениеЭУ.Элементы.Количество();
//Суффикс = "*";
Исключение КонецПопытки;
КонецЕсли;
Если Количество = Неопределено Тогда
Попытка
Количество = ЗначениеЭУ.Строки.Количество();
Суффикс = "*";
Исключение КонецПопытки;
КонецЕсли;
//Если Количество = 0 Тогда
// Попытка
// КоличествоКолонок = ЗначениеЭУ.Колонки.Количество();
// Исключение
// КоличествоКолонок = 1;
// КонецПопытки;
// Если КоличествоКолонок = 0 Тогда
// Количество = "-";
// КонецЕсли;
//КонецЕсли;
ИначеЕсли ТипЗнч(ЭУ) = Тип("ПолеТабличногоДокумента") Тогда
Количество = ?(ЭУ.ВысотаТаблицы > 0, 1, 0);
ИначеЕсли ТипЗнч(ЭУ) = Тип("ПолеТекстовогоДокумента") Тогда
Количество = ?(ЭУ.КоличествоСтрок() > 0, 1, 0);
ИначеЕсли ТипЗнч(ЭУ) = Тип("ПолеГрафическойСхемы") Тогда
Количество = ЭУ.ЭлементыГрафическойСхемы.Количество();
ИначеЕсли ТипЗнч(ЭУ) = Тип("Панель") Тогда
//Количество = ЭУ.Страницы.Количество();
//Если Количество = 1 Тогда
// Если ЭУ.Страницы[0].Имя = "" Тогда
// Количество = 0;
// КонецЕсли;
//КонецЕсли;
Количество = ОбновитьЗаголовкиСтраницПанелиЛкс(ЭлементыФормы, ЭУ);
КонецЕсли;
Если ТипЗнч(Количество) = Тип("Число") Тогда
ОбщееКоличество = ОбщееКоличество + Количество;
КонецЕсли;
КонецЕсли;
Если ТаблицаСтраниц <> Неопределено Тогда
СтрокаСтраницы = ТаблицаСтраниц.Найти(Страница.Имя, "ИмяСтраницы");
СтрокаСтраницы.Количество = Количество;
КонецЕсли;
ОбновитьТекстПослеМаркераВСтрокеЛкс(Страница.Заголовок, , "" + Количество + Суффикс + ")", "(");
КонецЦикла;
Возврат ОбщееКоличество;
КонецФункции // ОбновитьЗаголовкиСтраницПанелейЛкс()
// <Описание процедуры>
//
// Параметры:
// Ссылка – Ссылка, КлючЗаписи, КонстантаМенеджер;
// ПолноеИмя - Строка - полное имя метаданных для константы.
//
Процедура ОткрытьСсылкуИзРезультатаПоискаСсылокЛкс(Ссылка, ПолноеИмя = "") Экспорт
Если ЛиКлючЗаписиРегистраЛкс(Ссылка) Тогда
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(Ссылка));
ПолноеИмя = ОбъектМетаданных.ПолноеИмя();
ФормаСписка = ПолучитьФормуСпискаЛкс(ОбъектМетаданных.ПолноеИмя(),,,,,, Ссылка);
ФормаСписка.Открыть();
ИначеЕсли ЛиКорневойТипКонстантыЛкс(ПолучитьПервыйФрагментЛкс(ПолноеИмя)) Тогда
ОткрытьКонстантуВСпискеЛкс(ПолучитьПоследнийФрагментЛкс(ПолноеИмя));
Иначе
ОткрытьЗначение(Ссылка);
КонецЕсли;
КонецПроцедуры // ОткрытьСсылкуИзРезультатаПоискаСсылокЛкс()
Процедура ОткрытьКонстантуВСпискеЛкс(ИмяКонстанты) Экспорт
ФормаСписка = ПолучитьФормуЛкс("Обработка.ирРедакторКонстант.Форма");
ФормаСписка.НачальноеЗначениеВыбора = ИмяКонстанты;
ФормаСписка.Открыть();
КонецПроцедуры
Функция ПромежуточноеОбновлениеСтроковогоЗначенияПоляВводаЛкс(Знач Элемент, Текст) Экспорт
НачалоКолонки = 0; НачалоСтроки = 0; КонецКолонки = 0; КонецСтроки = 0;
Элемент.ПолучитьГраницыВыделения(НачалоСтроки, НачалоКолонки, КонецСтроки, КонецКолонки);
Элемент.Значение = Текст;
Элемент.УстановитьГраницыВыделения(1, 1, КонецСтроки, КонецКолонки);
Элемент.ВыделенныйТекст = Элемент.ВыделенныйТекст;
Элемент.УстановитьГраницыВыделения(НачалоСтроки, НачалоКолонки, КонецСтроки, КонецКолонки);
КонецФункции
Функция ПрочитатьЗначениеИзФайлаСКонтролемПотерьЛкс(ПолноеИмяФайла) Экспорт
ФайлЗначения = Новый Файл(ПолноеИмяФайла);
ПолученноеЗначение = ?(ФайлЗначения.Существует(), ЗначениеИзФайла(ПолноеИмяФайла), Неопределено);
Если ПолученноеЗначение = Неопределено Тогда
Возврат ПолученноеЗначение;
КонецЕсли;
СравнениеФайлов = Новый СравнениеФайлов;
ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
ЗначениеВФайл(ИмяВременногоФайла, ПолученноеЗначение);
СравнениеФайлов.ПервыйФайл = ПолноеИмяФайла;
СравнениеФайлов.ВторойФайл = ИмяВременногоФайла;
СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.Двоичное;
Если Не СравнениеФайлов.Сравнить() Тогда
Сообщить("При чтении из файла вероятно была потеряна часть информации", СтатусСообщения.Внимание);
КонецЕсли;
УдалитьФайлы(ИмяВременногоФайла);
Возврат ПолученноеЗначение;
КонецФункции
#КонецЕсли
//Для Объект = Неопределено возвращает Ложь, работает только для русского и английского языков платформы
// Параметры:
// КоличествоПараметров - нужно задать заведомо большее значение, чем может быть у метода
Функция МетодРеализованЛкс(Объект, ИмяМетода) Экспорт
Если Объект = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Выражение = "Объект." + ИмяМетода + "(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)";
Попытка
Выполнить(Выражение);
Исключение
Инфо = ИнформацияОбОшибке();
Описание = Инфо.Описание;
//СообщитьИис(Описание);
КонецПопытки;
Результат = Ложь
Или Описание = "Слишком много фактических параметров"
Или Описание = "Too many actual parameters";
Возврат Результат;
КонецФункции
// Параметры:
// КоличествоПроходов - Число(Н8,0)
// КлючЗамера - Строка
// ВыдатьСообщение - Булево
//
Функция НачатьЗамерЛкс(Знач КоличествоПроходов = 1, Знач КлючЗамера = "", Знач ВыдатьСообщение = Ложь) Экспорт
ирПлатформа = ирКэш.Получить();
ТаблицаЗамеров = ирПлатформа.мТаблицаЗамеров;
Если Не ЗначениеЗаполнено(КлючЗамера) Тогда
КлючЗамера = "Замер" + ТаблицаЗамеров.Колонки[0].Имя;
КонецЕсли;
ТаблицаЗамеров.Колонки[0].Имя = "_" + XMLСтрока(Число(Сред(ТаблицаЗамеров.Колонки[0].Имя, 2)) + 1);
СтрокаЗамера = ТаблицаЗамеров.Добавить();
СтрокаЗамера.Ключ = КлючЗамера;
#Если Клиент Тогда
СтрокаЗамера.Отладчик = ирПлатформа.ПолучитьИдентификаторПроцессаОтладчика() <> Неопределено;
#КонецЕсли
СтрокаЗамера.КоличествоПроходов = КоличествоПроходов;
Если Ложь
Или ВыдатьСообщение
//Или СтрокаЗамера.Отладчик
Тогда
Сообщение = "Начало замера """ + СтрокаЗамера.Ключ + """, количество проходов = " + КоличествоПроходов;
Если СтрокаЗамера.Отладчик Тогда
Сообщение = Сообщение + ". Отладчик подключен и неравномерно замедляет выполнение кода!";
КонецЕсли;
Сообщить(Сообщение);
КонецЕсли;
СтрокаЗамера.ДатаНачала = ПолучитьТекущееВремяВМиллисекундахЛкс();
Результат = КоличествоПроходов;
Возврат Результат;
КонецФункции
// Параметры:
// КлючЗамера - Строка - По умолчанию последний замер
//
Функция КончитьЗамерЛкс(Знач КлючЗамера = "") Экспорт
ТекущееВремя = ПолучитьТекущееВремяВМиллисекундахЛкс();
ирПлатформа = ирКэш.Получить();
ТаблицаЗамеров = ирПлатформа.мТаблицаЗамеров;
Если Не ЗначениеЗаполнено(КлючЗамера) Тогда
Если ТаблицаЗамеров.Количество() > 0 Тогда
СтрокаЗамера = ТаблицаЗамеров[ТаблицаЗамеров.Количество() - 1];
КонецЕсли;
Иначе
СтрокаЗамера = ТаблицаЗамеров.Найти(КлючЗамера, "Ключ");
КонецЕсли;
Если СтрокаЗамера = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Длительность = ТекущееВремя - СтрокаЗамера.ДатаНачала;
Длительность = Длительность / 1000;
Сообщение = "Окончание замера """ + СтрокаЗамера.Ключ + """ - Длительность = " + XMLСтрока(Длительность) + "с";
Если СтрокаЗамера.КоличествоПроходов > 1 Тогда
Среднее = Длительность / СтрокаЗамера.КоличествоПроходов;
Сообщение = Сообщение + ", Среднее = " + XMLСтрока(Среднее) + "с";
КонецЕсли;
Если Ложь
Или СтрокаЗамера.Отладчик
Или ирПлатформа.ПолучитьИдентификаторПроцессаОтладчика() <> Неопределено
Тогда
Сообщение = Сообщение + ". Отладчик подключен и неравномерно замедляет выполнение кода!";
КонецЕсли;
Сообщить(Сообщение);
ТаблицаЗамеров.Удалить(СтрокаЗамера);
Результат = Длительность;
Возврат Результат;
КонецФункции
Функция ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ТабличноеПоле, СтруктураОтбора = Неопределено) Экспорт
ВременнныйПостроительЗапроса = Новый ПостроительЗапроса;
ВременнныйПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличноеПоле.Значение);
Попытка
ОтборСтрок = ТабличноеПоле.ОтборСтрок;
Исключение
КонецПопытки;
Если ОтборСтрок <> Неопределено Тогда
СкопироватьОтборЛкс(ВременнныйПостроительЗапроса.Отбор, ОтборСтрок, Истина);
КонецЕсли;
Если СтруктураОтбора <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
ВременнныйПостроительЗапроса.Отбор.Добавить(КлючИЗначение.Ключ).Установить(КлючИЗначение.Значение);
КонецЦикла;
КонецЕсли;
Возврат ВременнныйПостроительЗапроса;
КонецФункции
Функция ПолучитьСтруктуруВыделенияТекстаЛкс() Экспорт
Структура = Новый Структура();
Структура.Вставить("НачальнаяСтрока");
Структура.Вставить("НачальнаяКолонка");
Структура.Вставить("КонечнаяСтрока");
Структура.Вставить("КонечнаяКолонка");
Возврат Структура;
КонецФункции
Функция ПолеТекста_ПолучитьДиапазонВыделенияЛкс(ПолеТекста) Экспорт
СтруктуруВыделения = ПолучитьСтруктуруВыделенияТекстаЛкс();
ПолеТекста.ПолучитьГраницыВыделения(СтруктуруВыделения.НачальнаяСтрока, СтруктуруВыделения.НачальнаяКолонка,
СтруктуруВыделения.КонечнаяСтрока, СтруктуруВыделения.КонечнаяКолонка);
Возврат СтруктуруВыделения;
КонецФункции
Функция ПолеТекста_УстановитьДиапазонВыделенияЛкс(Знач ПолеТекста, Знач СтруктуруВыделения) Экспорт
ПолеТекста.УстановитьГраницыВыделения(СтруктуруВыделения.НачальнаяСтрока, СтруктуруВыделения.НачальнаяКолонка,
СтруктуруВыделения.КонечнаяСтрока, СтруктуруВыделения.КонечнаяКолонка);
Возврат Неопределено;
КонецФункции
// Копирует таблицу значений из исходной таблицы значений с удалением типа Null из описаний типов колонок.
// Параметры:
// ОбработатьТолькоКолонки - Строка - имена колонок разделенные запятыми
// НеОбрабатыватьКолонки - Строка - имена колонок разделенные запятыми
//
// Возвращаемое значение:
// ТаблицаЗначений
//
Функция ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(Знач Таблица, ЗагружатьДанныеВНовуюТаблицу = Истина, ОбрабатыватьТолькоКолонки = "", НеОбрабатыватьКолонки = "") Экспорт
Результат = Новый ТаблицаЗначений;
НовыеКолонки = Результат.Колонки;
ИсходныеКолонки = Таблица.Колонки;
ИменаОбрабатываемыхКолонок = Новый Массив();
Если ОбрабатыватьТолькоКолонки <> "" Тогда
ИменаОбрабатываемыхКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(ОбрабатыватьТолькоКолонки, ",", Истина);
КонецЕсли;
ИменаНеобрабатываемыхКолонок = Новый Массив();
Если НеОбрабатыватьКолонки <> "" Тогда
ИменаНеобрабатываемыхКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(НеОбрабатыватьКолонки, ",", Истина);
КонецЕсли;
Для Каждого Колонка Из ИсходныеКолонки Цикл
Если Ложь
Или (Истина
И ОбрабатыватьТолькоКолонки <> ""
И ИменаОбрабатываемыхКолонок.Найти(Колонка.Имя) = Неопределено)
Или (Истина
И НеОбрабатыватьКолонки <> ""
И ИменаНеобрабатываемыхКолонок.Найти(Колонка.Имя) <> Неопределено)
Тогда
ОписаниеТипов = Колонка.ТипЗначения;
Иначе
ОписаниеТипов = Новый ОписаниеТипов(Колонка.ТипЗначения, , "NULL");
КонецЕсли;
НовыеКолонки.Добавить(Колонка.Имя, ОписаниеТипов, Колонка.Заголовок, Колонка.Ширина);
КонецЦикла;
Если ЗагружатьДанныеВНовуюТаблицу Тогда
ЗагрузитьВТаблицуЗначенийЛкс(Таблица, Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиСсылочныйОбъектМетаданных(ОбъектМД, ДляТабличнойЧастиПроверятьРодителя = Истина) Экспорт
Если ТипЗнч(Метаданные) <> Тип("Строка") Тогда
ПолноеИмя = ОбъектМД.ПолноеИмя();
Иначе
ПолноеИмя = ОбъектМД;
КонецЕсли;
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
Если Истина
И Не ДляТабличнойЧастиПроверятьРодителя
И МассивФрагментов.Количество() > 2
Тогда
Возврат Ложь;
КонецЕсли;
КорневойТип = МассивФрагментов[0];
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
Возврат Истина;
ИначеЕсли Истина
И МассивФрагментов.Количество() = 4
И КорневойТип = "ВнешнийИсточникДанных"
Тогда
Возврат (ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные);
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
Функция ЛиРегистровыйОбъектМетаданных(ОбъектМД) Экспорт
Если ТипЗнч(Метаданные) <> Тип("Строка") Тогда
ПолноеИмя = ОбъектМД.ПолноеИмя();
Иначе
ПолноеИмя = ОбъектМД;
КонецЕсли;
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
КорневойТип = МассивФрагментов[0];
Если ЛиКорневойТипРегистраБДЛкс(КорневойТип) Тогда
Возврат Истина;
ИначеЕсли Истина
И МассивФрагментов.Количество() = 4
И КорневойТип = "ВнешнийИсточникДанных"
Тогда
Возврат (ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.НеобъектныеДанные);
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
Функция ЛиТипВнешнегоИсточникаДанных(Метаданные) Экспорт
Если ТипЗнч(Метаданные) <> Тип("Строка") Тогда
ПолноеИмя = Метаданные.ПолноеИмя();
Иначе
ПолноеИмя = Метаданные;
КонецЕсли;
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмя);
Возврат КорневойТип = "ВнешнийИсточникДанных";
КонецФункции
Функция ПолучитьИмяТаблицыИзМетаданныхЛкс(Знач ОбъектМД, ЛиТаблицаИзменений = Ложь, ЛиДвиженияССубконтоДляРегистраБухгалтерии = Истина,
ТолькоРазрешенные = Ложь) Экспорт
Если ТипЗнч(ОбъектМД) <> Тип("Строка") Тогда
ПолноеИмя = ОбъектМД.ПолноеИмя();
Иначе
ПолноеИмя = ОбъектМД;
КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
Если ТолькоРазрешенные Тогда
Если ТипЗнч(ОбъектМД) = Тип("Строка") Тогда
Если Фрагменты.Количество() > 1 Тогда
ОбъектМД = Метаданные.НайтиПоПолномуИмени(Фрагменты[0] + "." + Фрагменты[1]); // очень долгая операция, поэтому лучше не устанавливать флаг ТолькоРазрешенные
Иначе
//ОбъектМД = Метаданные[Фрагменты[0]];
ОбъектМД = Неопределено;
КонецЕсли;
КонецЕсли;
Если Истина
И ОбъектМД <> Неопределено
И Не ПравоДоступа("Чтение", ОбъектМД)
Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Если Истина
И Фрагменты[0] = "Константа"
И Фрагменты.Количество() = 2
И Не ЛиТаблицаИзменений
Тогда
Если Не ирКэш.ИндивидуальныеТаблицыКонстантДоступныЛкс() Тогда
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс("Константы");
КонецЕсли;
КонецЕсли;
Если Фрагменты.Количество() = 4 Тогда
Если Ложь
Или СтрокиРавныЛкс(Фрагменты[2], "ТабличнаяЧасть")
Или СтрокиРавныЛкс(Фрагменты[2], "Перерасчет")
//Или СтрокиРавныЛкс(Фрагменты[2], "Таблица")
Тогда
Фрагменты.Удалить(2);
КонецЕсли;
КонецЕсли;
ИмяТаблицы = ПолучитьСтрокуСРазделителемИзМассиваЛкс(Фрагменты, ".");
Если Истина
И ЛиПолноеИмяРегистраБухгалтерииЛкс(ПолноеИмя)
И Не ЛиТаблицаИзменений
И ЛиДвиженияССубконтоДляРегистраБухгалтерии
Тогда
ИмяТаблицы = ИмяТаблицы + ".ДвиженияССубконто";
КонецЕсли;
Если ЛиТаблицаИзменений Тогда
ИмяТаблицы = ИмяТаблицы + ".Изменения";
КонецЕсли;
Возврат ИмяТаблицы;
КонецФункции // ПолучитьИмяТаблицыИзМетаданныхЛкс()
Функция ПолучитьОпределениеТаблицыБДДляИЗЛкс(ИмяТаблицы) Экспорт
Результат = ИмяТаблицы;
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ИмяТаблицы);
Если ТипТаблицы = "ДвиженияССубконто" Тогда
Результат = Результат + "(,, {Регистратор.*, НомерСтроки, Активность})";
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяТаблицы, выхМакетныйОбъект, выхТекущаяГруппаТипаМетаданных = Неопределено, выхКлючевыеПоля = Неопределено) Экспорт
выхКлючевыеПоля = Новый Массив;
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицы);
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы) Тогда
выхМакетныйОбъект = Новый (СтрЗаменить(ПолноеИмяТаблицы, ".", "Объект."));
выхТекущаяГруппаТипаМетаданных = "Ссылочный";
выхКлючевыеПоля.Добавить("Ссылка");
ИначеЕсли ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда
выхМакетныйОбъект = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицы);
выхТекущаяГруппаТипаМетаданных = "Регистр";
Для Каждого ЭлементОтбора Из выхМакетныйОбъект.Отбор Цикл
выхКлючевыеПоля.Добавить(ЭлементОтбора.ПутьКДанным);
КонецЦикла;
ИначеЕсли ЛиКорневойТипКонстантыЛкс(ТипТаблицы) Тогда
выхМакетныйОбъект = Новый (СтрЗаменить(ПолноеИмяТаблицы, ".", "МенеджерЗначения."));
выхТекущаяГруппаТипаМетаданных = "Константа";
Иначе
Если ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
выхТекущаяГруппаТипаМетаданных = "ВложеннаяТаблица";
КонецЕсли;
//ВызватьИсключение "Макетный объект данных для таблицы типа " + ТипТаблицы + " не допустим";
КонецЕсли;
КонецПроцедуры
Функция ОписаниеТиповОбъектаИлиСтрокиБДПоИменамТаблицЛкс(Знач МассивИлиИмяТаблицыБД, Знач НуженТипОбъекта, РежимОбходаДанных = "Строки", Знач ТипТаблицы = Неопределено, выхПолноеИмяТаблицы = Неопределено) Экспорт
МассивИменТаблицБД = Новый Массив();
Если ТипЗнч(МассивИлиИмяТаблицыБД) = Тип("Строка") Тогда
ТипТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(МассивИлиИмяТаблицыБД);
МассивИменТаблицБД.Добавить(МассивИлиИмяТаблицыБД);
Иначе
МассивИменТаблицБД = МассивИлиИмяТаблицыБД;
КонецЕсли;
МассивТипов = Новый Массив();
Если Ложь
Или ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы)
Или ТипТаблицы = "Внешняя"
Тогда
Если РежимОбходаДанных = "КлючиОбъектов" Тогда
РасширениеТипа = "Ссылка";
Иначе
РасширениеТипа = "Объект";
КонецЕсли;
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ИмяТипа = ирОбщий.ИмяТипаИзПолногоИмениТаблицыБДЛкс(ИмяТаблицыБД, РасширениеТипа);
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли Ложь
Или ирОбщий.ЛиКорневойТипЖурналаДокументовЛкс(ТипТаблицы)
Тогда
Если РежимОбходаДанных = "КлючиОбъектов" Тогда
РасширениеТипа = "Ссылка";
Иначе
РасширениеТипа = "Объект";
КонецЕсли;
Поля = ирОбщий.ПолучитьПоляТаблицыБДЛкс(МассивИменТаблицБД[0]);
Поле = Поля.Найти("Ссылка", "Имя");
Для Каждого ТипЗначения Из Поле.ТипЗначения.Типы() Цикл
ИмяТипа = ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(Метаданные.НайтиПоТипу(ТипЗначения), РасширениеТипа);
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли ТипТаблицы = "Точки" Тогда
РасширениеТипа = "ТочкаМаршрутаБизнесПроцессаСсылка";
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ИмяТипа = СтрЗаменить(ИмяТаблицыБД, "БизнесПроцесс.", РасширениеТипа + ".");
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли ирОбщий.ЛиКорневойТипПеречисленияЛкс(ТипТаблицы) Тогда
РасширениеТипа = "Ссылка";
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ИмяТипа = СтрЗаменить(ИмяТаблицыБД, ".", РасширениеТипа + ".");
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли ирОбщий.ЛиКорневойТипКонстантыЛкс(ТипТаблицы) Тогда
РасширениеТипа = "МенеджерЗначения";
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ИмяТипа = СтрЗаменить(ИмяТаблицыБД, ".", РасширениеТипа + ".");
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
МассивФрагментов = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ИмяТаблицыБД);
выхПолноеИмяТаблицы = МассивФрагментов[0] + "." + МассивФрагментов[1];
Если Не НуженТипОбъекта И РежимОбходаДанных = "Строки" Тогда
ИмяТипа = МассивФрагментов[0] + ТипТаблицы + "Строка." + МассивФрагментов[1];
Если ТипТаблицы = "ТабличнаяЧасть" Тогда
ИмяТипа = ИмяТипа + "." + МассивФрагментов[2];
выхПолноеИмяТаблицы = выхПолноеИмяТаблицы + "." + МассивФрагментов[2];
Иначе
выхПолноеИмяТаблицы = выхПолноеИмяТаблицы + "." + ТипТаблицы;
КонецЕсли;
МассивТипов.Добавить(Тип(ИмяТипа));
ИначеЕсли РежимОбходаДанных = "КлючиОбъектов" Тогда
МассивТипов.Добавить(Тип(МассивФрагментов[0] + "Ссылка." + МассивФрагментов[1]));
Иначе
МассивТипов.Добавить(Тип(МассивФрагментов[0] + "Объект." + МассивФрагментов[1]));
КонецЕсли;
КонецЦикла;
ИначеЕсли Ложь
Или ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы)
Или ирОбщий.ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы)
Тогда
Если Не НуженТипОбъекта И РежимОбходаДанных = "Строки" Тогда
РасширениеТипа = "Запись";
Иначе
РасширениеТипа = "НаборЗаписей";
КонецЕсли;
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ТипЭлементаДанных = Тип(ирОбщий.ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ИмяТаблицыБД, РасширениеТипа));
МассивТипов.Добавить(ТипЭлементаДанных);
КонецЦикла;
Иначе
ВызватьИсключение "Неподдерживаемый тип таблицы """ + ТипТаблицы + """";
КонецЕсли;
Результат = Новый ОписаниеТипов(МассивТипов);
Возврат Результат;
КонецФункции
Функция ЛиПолноеИмяРегистраБухгалтерииЛкс(ПолноеИмяМД) Экспорт
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД);
Результат = Истина
И Фрагменты.Количество() = 2
И (Ложь
Или Фрагменты[0] = "AccountingRegister"
Или Фрагменты[0] = "РегистрБухгалтерии");
Возврат Результат;
КонецФункции
// Создает тип из метаданных.
//
// Параметры:
// Метаданные – ОбъектМетаданных;
// *Расширение - Строка, "Ссылка" - расширение типа.
//
// Возвращаемое значение:
// Тип.
//
Функция ПолучитьТипИзМетаданныхЛкс(ОбъектМД, Расширение = "Ссылка") Экспорт
Возврат Тип(ИмяТипаИзПолногоИмениМДЛкс(ОбъектМД, Расширение));
КонецФункции // ПолучитьТипИзМетаданных()
Функция ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Экспорт
ЭлементСостава = ОбщийРеквизит.Состав.Найти(ОбъектМетаданных);
Результат = Истина
И ЭлементСостава <> Неопределено
И (Ложь
Или ЭлементСостава.Использование = Метаданные.СвойстваОбъектов.ИспользованиеОбщегоРеквизита.Использовать
Или (Истина
И ЭлементСостава.Использование = Метаданные.СвойстваОбъектов.ИспользованиеОбщегоРеквизита.Авто
И ОбщийРеквизит.АвтоИспользование = Метаданные.СвойстваОбъектов.АвтоИспользованиеОбщегоРеквизита.Использовать));
Возврат Результат;
КонецФункции
Функция ПолучитьАлгоритмОбъектПоИдентификаторуЛкс(Знач Алгоритм) Экспорт
Если ТипЗнч(Алгоритм) <> Тип("СправочникСсылка.ирАлгоритмы") Тогда
Алгоритм = "" + Алгоритм;
Если Найти(Алгоритм, "-") > 0 Тогда
// Передан GUID
Алгоритм = Справочники.ирАлгоритмы.ПолучитьСсылку(Новый УникальныйИдентификатор(Алгоритм));
Иначе
// Передано имя алгоритма
Попытка
Алгоритм = ПредопределенноеЗначение("Справочник.ирАлгоритмы." + Алгоритм);
Исключение
КонецПопытки;
Если ТипЗнч(Алгоритм) <> Тип("СправочникСсылка.ирАлгоритмы") Тогда
Алгоритм = Справочники.ирАлгоритмы.НайтиПоНаименованию(Алгоритм, Истина);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(Алгоритм) Тогда
ВызватьИсключение "Алгоритм по идентификатору """ + Алгоритм + """ не найден";
КонецЕсли;
Возврат Алгоритм.ПолучитьОбъект();
КонецФункции
//Если объекту не назначена ссылка, назначает эту ссылку
Функция ПолучитьТочнуюСсылкуОбъектаЛкс(ОбъектБД) Экспорт
Ссылка = ОбъектБД.Ссылка;
Если Ссылка.Пустая() Тогда
Ссылка = ОбъектБД.ПолучитьСсылкуНового();
Если Ссылка.Пустая() Тогда
Ссылка = XMLЗначение(ТипЗнч(Ссылка), "" + Новый УникальныйИдентификатор);
ОбъектБД.УстановитьСсылкуНового(Ссылка);
КонецЕсли;
КонецЕсли;
Возврат Ссылка;
КонецФункции
Функция ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(Знач Текст) Экспорт
Текст = Символы.ПС + Текст;
Текст = СтрЗаменить(Текст, Символы.ПС, Символы.ПС + "|");
Текст = СтрЗаменить(Текст, """", """""");
Текст = """" + Текст + """";
Возврат Текст;
КонецФункции // ПолучитьСтроковыйЛитералИзМногострочногоТекста()
Функция ПолучитьВсеСтрокиДереваЗначенийЛкс(СтрокаИлиДеревоЗначений) Экспорт
Если ТипЗнч(СтрокаИлиДеревоЗначений) = Тип("СтрокаДереваЗначений") Тогда
ДеревоЗначений = СтрокаИлиДеревоЗначений.Владелец();
Иначе
ДеревоЗначений = СтрокаИлиДеревоЗначений;
КонецЕсли;
Идентификатор = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", "");
ДеревоЗначений.Колонки.Добавить(Идентификатор);
ВсеСтроки = СтрокаИлиДеревоЗначений.Строки.НайтиСтроки(Новый Структура(Идентификатор,), Истина);
ДеревоЗначений.Колонки.Удалить(Идентификатор);
Если ТипЗнч(СтрокаИлиДеревоЗначений) = Тип("СтрокаДереваЗначений") Тогда
ВсеСтроки.Добавить(СтрокаИлиДеревоЗначений);
КонецЕсли;
Возврат ВсеСтроки;
КонецФункции // ПолучитьВсеСтрокиДереваЗначений()
Функция СериализацииРавныЛкс(Таблица1, Таблица2) Экспорт
Хмл1 = СохранитьОбъектВВидеСтрокиXMLЛкс(Таблица1);
Хмл2 = СохранитьОбъектВВидеСтрокиXMLЛкс(Таблица2);
Возврат (Хмл1 = Хмл2);
КонецФункции
// ВариантОбрезания - 1
// ВариантОбрезания - 2
Функция ПолучитьИнформациюОбОшибкеБезВерхнегоМодуляЛкс(ИнформацияОбОшибке = Неопределено, ВариантОбрезания = 2) Экспорт
Если ИнформацияОбОшибке = Неопределено Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецЕсли;
Если ВариантОбрезания = 1 Тогда
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
КонецЕсли;
ИначеЕсли Истина
И ВариантОбрезания = 2
И ИнформацияОбОшибке.Причина <> Неопределено
Тогда
ОписаниеОшибки = ИнформацияОбОшибке.Описание + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
Иначе
ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
КонецЕсли;
Возврат ОписаниеОшибки;
КонецФункции
// МаксимальнаяГлубинаПричины - на сколько уровней вниз надо опуститься, пока есть вложенная причина
Функция ПредставлениеИнформацииОбОшибкеЛкс(Знач ИнформацияОбОшибке, Знач МаксимальнаяГлубинаПричины = 0, УбратьСтрокуКодаСПервогоУровня = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
ОписаниеОшибки = "";
Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда
Для Счетчик = 1 По МаксимальнаяГлубинаПричины Цикл
Если ТипЗнч(ИнформацияОбОшибке.Причина) = Тип("ИнформацияОбОшибке") Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
Если УбратьСтрокуКодаСПервогоУровня Тогда
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если ТипЗнч(ИнформацияОбОшибке.Причина) = Тип("ИнформацияОбОшибке") Тогда
ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(ОписаниеОшибки) Тогда
Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда
ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
Иначе
// Такое может случаться в свойстве ИнформацияОбОшибке объекта ФоновоеЗадание из-за ошибки платформы
ОписаниеОшибки = "Описание ошибки отсутствует";
КонецЕсли;
КонецЕсли;
Возврат ОписаниеОшибки;
КонецФункции
// Первая строка табличного документа содержит заголовки
Функция ПолучитьТаблицуИзТабличногоДокументаЛкс(Знач ТабличныйДокумент, ЛиПерваяСтрокаСодержитИменаКолонок = Истина, ДлинаСтрокиТипаКолонки = 150,
ВычислятьНетипизированныеЗначения = Ложь, ЛиВтораяСтрокаСодержитТипыЗначений = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент
#КонецЕсли
ТаблицаПриемник = Новый ТаблицаЗначений;
НачальнаяСтрока = 1;
Если ЛиПерваяСтрокаСодержитИменаКолонок Тогда
НачальнаяСтрока = НачальнаяСтрока + 1;
КонецЕсли;
Если ЛиВтораяСтрокаСодержитТипыЗначений Тогда
НачальнаяСтрока = НачальнаяСтрока + 1;
КонецЕсли;
ТипизированныеКолонки = Новый Соответствие;
Для Счетчик = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Если ЛиПерваяСтрокаСодержитИменаКолонок Тогда
ИмяКолонки = ТабличныйДокумент.Область(1, Счетчик).Текст;
Иначе
ИмяКолонки = "Колонка" + Счетчик;
КонецЕсли;
Если ЛиВтораяСтрокаСодержитТипыЗначений Тогда
ИменаТипов = ТабличныйДокумент.Область(2, Счетчик).Текст;
ТипизированныеКолонки[Счетчик] = 1;
Иначе
ИменаТипов = "";
КонецЕсли;
ТаблицаПриемник.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов(ИменаТипов));
КонецЦикла;
// Цикл перебора строк табличного документа
ВысотаТаблицы = ТабличныйДокумент.ВысотаТаблицы;
//Индикатор = ПолучитьИндикаторПроцессаЛкс(ТабличныйДокумент.ВысотаТаблицы);
Для НомерСтроки = НачальнаяСтрока По ВысотаТаблицы Цикл
// Добавление строки результирующей таблицы
НоваяСтрокаТЗ = ТаблицаПриемник.Добавить();
Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Область = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
ТекстЯчейки = Область.Текст;
Если Не ЗначениеЗаполнено(ТекстЯчейки) Тогда
Поддокумент = ТабличныйДокумент.ПолучитьОбласть(НомерСтроки, НомерКолонки);
Если Поддокумент.Рисунки.Количество() > 0 Тогда
ТекстЯчейки = Поддокумент.Рисунки[0].Картинка;
КонецЕсли;
КонецЕсли;
ЗначениеЯчейки = Неопределено;
Если ТипизированныеКолонки[НомерКолонки] <> Неопределено Тогда
ОписаниеТиповКолонки = ТаблицаПриемник.Колонки[НомерКолонки - 1].ТипЗначения;
Если ОписаниеТиповКолонки.СодержитТип(Тип("ОписаниеТипов")) Тогда
Попытка
ЗначениеЯчейки = Новый ОписаниеТипов(ТекстЯчейки);
Исключение
КонецПопытки;
ИначеЕсли ОписаниеТиповКолонки.СодержитТип(Тип("Тип")) Тогда
Попытка
ЗначениеЯчейки = Тип(ТекстЯчейки);
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если Ложь
Или ВычислятьНетипизированныеЗначения
Или (Истина
И ТипизированныеКолонки[НомерКолонки] <> Неопределено
И ЗначениеЯчейки = Неопределено)
Тогда
Попытка
ЗначениеЯчейки = Вычислить(ТекстЯчейки);
Исключение
КонецПопытки;
КонецЕсли;
Если ЗначениеЯчейки = Неопределено Тогда
ЗначениеЯчейки = ТекстЯчейки;
КонецЕсли;
НоваяСтрокаТЗ[НомерКолонки - 1] = ЗначениеЯчейки;
КонецЦикла;
КонецЦикла;
Возврат ТаблицаПриемник;
КонецФункции
Процедура УпроститьРасшифровкиТабличногоДокументаКомпоновкиЛкс(ТабличныйДокумент, ДанныеРасшифровки, СхемаКомпоновки) Экспорт
ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки));
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
ВысотаТаблицы = ТабличныйДокумент.ВысотаТаблицы;
Для НомерСтроки = 1 По ВысотаТаблицы Цикл
Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Область = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
Если ТипЗнч(Область.Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
Для каждого ЗначениеПоля Из ДанныеРасшифровки.Элементы[Область.Расшифровка].ПолучитьПоля() Цикл
Если Не ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение, Ложь) Тогда
Продолжить;
КонецЕсли;
Область.Расшифровка = ЗначениеПоля.Значение;
Прервать;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьИдентификаторТипаЛкс(Тип) Экспорт
Результат = ПолучитьСтрокуМеждуМаркерамиЛкс("" + ЗначениеВСтрокуВнутр(Тип), ",", "}", Ложь);
Возврат Результат;
КонецФункции
Функция ПолучитьПеременныеТекстаВстроенногоЯзыкаЛкс(Знач ТекстПрограммы = "") Экспорт
Если ПустаяСтрока(ТекстПрограммы) Тогда
#Если Клиент Тогда
ТекстПрограммы = ПолучитьТекстИзБуфераОбменаОСЛкс();
#Иначе
ВызватьИсключение "Получение текста из буфера обмена возможно только на клиенте";
#КонецЕсли
КонецЕсли;
Параметры = Новый Структура();
ПолеВстроенногоЯзыка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой");
#Если Сервер И Не Сервер Тогда
ПолеВстроенногоЯзыка = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать();
#КонецЕсли
ПолеВстроенногоЯзыка.ИнициализироватьНеинтерактивно();
ПолеВстроенногоЯзыка.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(,,,, Истина, ТекстПрограммы);
СтрокиЛокальныхПеременных = ПолеВстроенногоЯзыка.ТаблицаСлов.НайтиСтроки(Новый Структура("ТипСлова, Определение", "Свойство", "Статистический"));
//СтрокиЛокальныхПеременных = ПолеВстроенногоЯзыка.ТаблицаСлов.НайтиСтроки(Новый Структура("ТипСлова", "Свойство"));
Для Каждого СтрокаПеременной Из СтрокиЛокальныхПеременных Цикл
Параметры.Вставить(СтрокаПеременной.Слово);
КонецЦикла;
Возврат Параметры;
КонецФункции
// КолонкиНабора - КоллекцияКолонокДереваЗначений, КоллекцияКолонокТаблицыЗначений, КоллекцияКолонокРезультатаЗапроса
Функция СоздатьИлиОбновитьНаборДанныхОбъектПоМетаданнымЛкс(Знач СхемаКомпоновкиДанных, Знач КолонкиНабора, Знач ИмяНабора = "Основной",
Знач СоздаватьПапкиПолей = Ложь, СоздаватьРесурсыЧисловыхПолей = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
Результат = СхемаКомпоновкиДанных.НаборыДанных.Найти(ИмяНабора);
Если Результат = Неопределено Тогда
Результат = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
КонецЕсли;
Результат.Имя = ИмяНабора;
Результат.ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных[0].Имя;
Результат.ИмяОбъекта = ИмяНабора;
Для Каждого ЭлементМетаданных Из КолонкиНабора Цикл
Если Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаДереваЗначений")
Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаТаблицыЗначений")
Тогда
ИмяПоля = ЭлементМетаданных.Имя;
ЗаголовокПоля = ЭлементМетаданных.Заголовок;
ИначеЕсли Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаРезультатаЗапроса")
Тогда
ИмяПоля = ЭлементМетаданных.Имя;
ЗаголовокПоля = ИмяПоля;
ИначеЕсли Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("ПолеНастройки")
Тогда
ИмяПоля = ЭлементМетаданных.Имя;
ЗаголовокПоля = ЭлементМетаданных.Представление;
ИначеЕсли Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("ДоступноеПолеОтбораКомпоновкиДанных")
Тогда
ИмяПоля = "" + ЭлементМетаданных.Поле;
ЗаголовокПоля = ЭлементМетаданных.Заголовок;
Иначе
Продолжить;
КонецЕсли;
Поле = Результат.Поля.Найти(ИмяПоля);
Если Поле = Неопределено Тогда
Поле = Результат.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
КонецЕсли;
ПутьКДанным = ИмяПоля;
Если СоздаватьПапкиПолей Тогда
ПутьКДанным = Результат.Имя + "." + ПутьКДанным;
КонецЕсли;
Поле.ПутьКДанным = ПутьКДанным;
Поле.Поле = ИмяПоля;
Поле.Заголовок = ЗаголовокПоля;
Поле.ТипЗначения = ЭлементМетаданных.ТипЗначения;
Если Истина
И СоздаватьРесурсыЧисловыхПолей
И Поле.ТипЗначения.СодержитТип(Тип("Число"))
Тогда
Ресурс = СхемаКомпоновкиДанных.ПоляИтога.Добавить();
Ресурс.Выражение = "Сумма(" + ИмяПоля + ")";
Ресурс.ПутьКДанным = ИмяПоля;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура ЗаполнитьПараметрыСхемыПоЗапросуЛкс(Знач СхемаКомпоновкиДанных, Знач Запрос) Экспорт
#Если Сервер И Не Сервер Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
ОписанияПараметров = Запрос.НайтиПараметры(); // Здесь могут быть ложные ошибки синтаксического контроля
Для Каждого ОписаниеПараметра Из ОписанияПараметров Цикл
Если Не Запрос.Параметры.Свойство(ОписаниеПараметра.Имя) Тогда
Запрос.Параметры.Вставить(ОписаниеПараметра.Имя);
КонецЕсли;
КонецЦикла;
Для Каждого КлючИЗначение Из Запрос.Параметры Цикл
ЗначениеПараметра = КлючИЗначение.Значение;
Если ТипЗнч(ЗначениеПараметра) = Тип("Массив") Тогда
Список = Новый СписокЗначений;
Список.ЗагрузитьЗначения(ЗначениеПараметра);
ЗначениеПараметра = Список;
КонецЕсли;
ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти(КлючИЗначение.Ключ);
Если ПараметрСхемы = Неопределено Тогда
ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Добавить();
КонецЕсли;
ПараметрСхемы.Имя = КлючИЗначение.Ключ;
ПараметрСхемы.ДоступенСписокЗначений = ТипЗнч(ЗначениеПараметра) = Тип("СписокЗначений");
//Тип надо задавать, чтобы значение корректно записалось. Иначе ссылки будут преобразованы к строке.
МассивТипов = Новый Массив;
МассивТипов.Добавить(ТипЗнч(КлючИЗначение.Значение));
Если Не ПараметрСхемы.ДоступенСписокЗначений Тогда
ПараметрСхемы.ТипЗначения = Новый ОписаниеТипов(МассивТипов);
КонецЕсли;
ПараметрСхемы.Значение = ЗначениеПараметра;
КонецЦикла;
КонецПроцедуры
Функция СоздатьИлиОбновитьНаборДанныхЗапросПоЗапросуЛкс(Знач СхемаКомпоновкиДанных, Знач Запрос, Знач ИмяНабора = "Основной", Представления = Неопределено) Экспорт
НаборДанных = ДобавитьНаборДанныхЗапросЛкс(СхемаКомпоновкиДанных.НаборыДанных, СхемаКомпоновкиДанных.ИсточникиДанных[0]);
НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина;
НаборДанных.Запрос = Запрос.Текст;
Если Представления <> Неопределено Тогда
Для Каждого КлючИЗначение Из Представления Цикл
ПолеНабора = НаборДанных.Поля.Найти(КлючИЗначение.Ключ);
Если ПолеНабора = Неопределено Тогда
ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
КонецЕсли;
ПолеНабора.Поле = КлючИЗначение.Ключ;
ПолеНабора.ПутьКДанным = КлючИЗначение.Ключ;
ПолеНабора.Заголовок = КлючИЗначение.Значение;
КонецЦикла;
КонецЕсли;
ЗаполнитьПараметрыСхемыПоЗапросуЛкс(СхемаКомпоновкиДанных, Запрос);
Возврат НаборДанных;
КонецФункции
// Представления - Структура
Функция ПолучитьСхемуКомпоновкиПоЗапросуЛкс(Знач ЗапросИлиТекст, ИмяНабораДанных = "НаборДанных1", Представления = Неопределено) Экспорт
Схема = Новый СхемаКомпоновкиДанных;
ДобавитьЛокальныйИсточникДанныхЛкс(Схема);
Если ТипЗнч(ЗапросИлиТекст) = Тип("Строка") Тогда
Запрос = Новый Запрос;
Запрос.Текст = ЗапросИлиТекст;
Иначе
Запрос = ЗапросИлиТекст;
КонецЕсли;
СоздатьИлиОбновитьНаборДанныхЗапросПоЗапросуЛкс(Схема, Запрос, ИмяНабораДанных, Представления);
Возврат Схема;
КонецФункции
Функция ПолучитьСхемуКомпоновкиПоОбъектуМетаданныхЛкс(Знач ПолноеИмяИлиОбъектМД, ИмяНабораДанных = "НаборДанных1", ДобавитьАвтополеКоличествоСтрок = Истина,
ПсевдонимТаблицы = "Т", ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "", ИменаВместоПредставлений = Ложь) Экспорт
Если ТипЗнч(ПолноеИмяИлиОбъектМД) = Тип("Строка") Тогда
ПолноеИмяМД = ПолноеИмяИлиОбъектМД;
Иначе
ПолноеИмяМД = ПолноеИмяИлиОбъектМД.ПолноеИмя();
КонецЕсли;
ПолноеИмяТаблицыБД = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
Схема = ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВыражениеПараметраПериодичность, ДобавитьАвтополеКоличествоСтрок, ИндексПараметраПериодичность, ПсевдонимТаблицы,
ИменаВместоПредставлений);
Возврат Схема;
КонецФункции
Функция ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВызыватьИсключениеПриОтсутствииПрав = Истина, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "") Экспорт
Запрос = Новый Запрос;
Запрос.Текст = ПолучитьТекстЗапросаПолейТаблицыБДЛкс(ПолноеИмяТаблицыБД, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность) + " ГДЕ ЛОЖЬ";
Попытка
ТаблицаРезультата = Запрос.Выполнить().Выгрузить();
Исключение
ПостроительЗапроса = Новый ПостроительЗапроса;
ПостроительЗапроса.Текст = Запрос.Текст;
Попытка
ПостроительЗапроса.ЗаполнитьНастройки(); // Долгий способ пробуем только если быстрый не удался
Исключение
Если ВызыватьИсключениеПриОтсутствииПрав Тогда
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
ТаблицаРезультата = Новый ТаблицаЗначений;
Для Каждого ДоступноеПоле Из ПостроительЗапроса.ДоступныеПоля Цикл
ТаблицаРезультата.Колонки.Добавить(ДоступноеПоле.ПутьКДанным, ДоступноеПоле.ТипЗначения);
КонецЦикла;
КонецПопытки;
Если ТаблицаРезультата <> Неопределено Тогда
ПоляТаблицы = ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(ТаблицаРезультата).Колонки;
КонецЕсли;
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Имя");
Результат.Колонки.Добавить("ТипЗначения");
Результат.Колонки.Добавить("Метаданные");
Результат.Колонки.Добавить("Заголовок");
Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл
СтрокаПоля = Результат.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаПоля, ПолеТаблицы);
КонецЦикла;
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Если Истина
И ТипТаблицы <> "ДвиженияССубконто"
И ТипТаблицы <> "ВиртуальнаяТаблица"
Тогда
ОбъектМД = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, Истина);
Если ОбъектМД <> Неопределено Тогда
РодительМД = ОбъектМД.Родитель();
Если Истина
И ТипТаблицы <> "Перерасчет"
И ТипТаблицы <> "Внешняя"
И ТипЗнч(РодительМД) <> Тип("ОбъектМетаданныхКонфигурация")
Тогда
ОбъектМД = РодительМД;
КонецЕсли;
Если ТипТаблицы = "Внешняя" Тогда
Для Каждого ПолеТаблицы Из ОбъектМД.Поля Цикл
СтрокаПоля = Результат.Найти(ПолеТаблицы.Имя, "Имя");
Если СтрокаПоля <> Неопределено Тогда
СтрокаПоля.Метаданные = ПолеТаблицы;
Заголовок = ПолеТаблицы.Представление();
Если ЗначениеЗаполнено(Заголовок) Тогда
СтрокаПоля.Заголовок = Заголовок;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе
ФильтрМетаданных = Новый Массив;
ФильтрМетаданных.Добавить(ОбъектМД);
СтрокиСтруктурыТаблицы = ПолучитьСтруктуруХраненияБазыДанных(ФильтрМетаданных).НайтиСтроки(Новый Структура("ИмяТаблицы", ПолноеИмяТаблицыБД));
Если СтрокиСтруктурыТаблицы.Количество() = 0 Тогда
Если Истина
И ТипТаблицы <> "Изменения"
И ТипТаблицы <> "Границы"
И ТипТаблицы <> "Константа"
И ТипТаблицы <> "ЗадачиПоИсполнителю"
Тогда
Сообщить("Не удалось найти в структуре хранения БД описание таблицы " + ПолноеИмяТаблицыБД);
Иначе
// Для отладки
// Сюда попадаем для констант, у которых у таблицы изменений имя ошибочно указано то же, что и у основной таблицы.
// Сюда попадаем для границ последовательностей, у которых ошибочно пустое имя таблицы.
Пустышка = 1;
КонецЕсли;
Иначе
Если СтрокиСтруктурыТаблицы.Количество() > 1 Тогда
Пустышка = 1; // Для отладки. Сюда попадаем для констант, у которых у таблицы изменений имя ошибочно указано то же, что и у основной таблицы
КонецЕсли;
Для Каждого ПолеТаблицы Из СтрокиСтруктурыТаблицы[0].Поля Цикл
Если Истина
И ЗначениеЗаполнено(ПолеТаблицы.Метаданные)
И (Ложь
Или ПолеТаблицы.ИмяПоля <> "НомерСтроки"
Или Найти(ПолеТаблицы.Метаданные, ".ТабличнаяЧасть.") = 0)
Тогда
СтрокаПоля = Результат.Найти(ПолеТаблицы.ИмяПоля, "Имя");
Если СтрокаПоля <> Неопределено Тогда
СтрокаПоля.Метаданные = Метаданные.НайтиПоПолномуИмени(ПолеТаблицы.Метаданные);
Заголовок = СтрокаПоля.Метаданные.Представление();
Если ЗначениеЗаполнено(Заголовок) Тогда
СтрокаПоля.Заголовок = Заголовок;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьПоляТаблицыМДЛкс(ПолноеИмяМД, ВызыватьИсключениеПриОтсутствииПрав = Истина, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "") Экспорт
ПолноеИмяТаблицыБД = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
ПоляТаблицы = ирКэш.ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВызыватьИсключениеПриОтсутствииПрав, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность);
Возврат ПоляТаблицы;
КонецФункции
// Добавляет в набор данных поле набора данных
Функция ДобавитьПолеНабораДанныхЛкс(НаборДанных, Поле, Заголовок, ПутьКДанным = Неопределено) Экспорт
Если ПутьКДанным = Неопределено Тогда
ПутьКДанным = Поле;
КонецЕсли;
ПолеНабораДанных = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНабораДанных.Поле = Поле;
ПолеНабораДанных.Заголовок = Заголовок;
ПолеНабораДанных.ПутьКДанным = ПутьКДанным;
Возврат ПолеНабораДанных;
КонецФункции
Функция ДобавитьПоляПериодаВНаборДанныхЛкс(НаборДанных)
СписокПериодов = Новый СписокЗначений;
СписокПериодов.Добавить("ПериодСекунда", "Период секунда");
СписокПериодов.Добавить("ПериодМинута", "Период минута");
СписокПериодов.Добавить("ПериодЧас", "Период час");
СписокПериодов.Добавить("ПериодДень", "Период день");
СписокПериодов.Добавить("ПериодНеделя", "Период неделя");
СписокПериодов.Добавить("ПериодДекада", "Период декада");
СписокПериодов.Добавить("ПериодМесяц", "Период месяц");
СписокПериодов.Добавить("ПериодКвартал", "Период квартал");
СписокПериодов.Добавить("ПериодПолугодие", "Период полугодие");
СписокПериодов.Добавить("ПериодГод", "Период год");
ИмяПапки = "Периоды";
СписокПолейНабораДанных = Новый СписокЗначений;
ПапкаПолейНабораДанных = НаборДанных.Поля.Добавить(Тип("ПапкаПолейНабораДанныхСхемыКомпоновкиДанных"));
ПапкаПолейНабораДанных.Заголовок = ИмяПапки;
ПапкаПолейНабораДанных.ПутьКДанным = ИмяПапки;
Для каждого Период Из СписокПериодов Цикл
ПолеНабораДанных = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНабораДанных.Поле = Период.Значение;
ПолеНабораДанных.Заголовок = Период.Представление;
ПолеНабораДанных.ПутьКДанным = ИмяПапки + "." + Период.Значение;
СписокПолейНабораДанных.Добавить(ПолеНабораДанных);
КонецЦикла;
Возврат СписокПолейНабораДанных;
КонецФункции
// Функция добавляет поле итога в схему компоновки данных. Если параметр Выражение не указан, используется Сумма(ПутьКДанным)
Функция ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, ПутьКДанным, Выражение = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
Если Выражение = Неопределено Тогда
Выражение = "Сумма(" + ПутьКДанным + ")";
КонецЕсли;
ПолеИтога = СхемаКомпоновкиДанных.ПоляИтога.Добавить();
ПолеИтога.ПутьКДанным = ПутьКДанным;
ПолеИтога.Выражение = Выражение;
Возврат ПолеИтога;
КонецФункции
Процедура ДобавитьПоляНабораДанныхЛкс(ПолноеИмяТаблицыБД, СхемаКомпоновкиДанных) Экспорт
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмяТаблицыБД);
Если СтрокиРавныЛкс(ТипТаблицы, "ВиртуальнаяТаблица") Тогда
ИмяВиртуальнойТаблицы = ПолучитьПоследнийФрагментЛкс(ПолноеИмяТаблицыБД);
ПолноеИмяМД = ПолноеИмяТаблицыБД;
Иначе
ИмяВиртуальнойТаблицы = "";
ПолноеИмяМД = ПолноеИмяТаблицыБД;
КонецЕсли;
ОбъектМД = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Если ЛиКорневойТипРегистраБДЛкс(КорневойТип) И Не СтрокиРавныЛкс(ТипТаблицы, "Изменения") Тогда
// Добавляем измерения
Для каждого Измерение Из ОбъектМД.Измерения Цикл
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Измерение.Имя, Измерение.Синоним);
КонецЦикла;
// Добавляем реквизиты
Если Истина
И Не ЛиКорневойТипПоследовательностиЛкс(КорневойТип)
И Не СтрокиРавныЛкс(ТипТаблицы, "Перерасчет")
Тогда
//Если ПустаяСтрока(ИмяВиртуальнойТаблицы) Тогда
Для каждого Реквизит Из ОбъектМД.Реквизиты Цикл
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Реквизит.Имя, Реквизит.Синоним);
КонецЦикла;
//КонецЕсли;
// Добавляем поля периода
Если Ложь
Или ИмяВиртуальнойТаблицы = "ОстаткиИОбороты"
Или ИмяВиртуальнойТаблицы = "Обороты"
Или (Истина
И КорневойТип = "РегистрБухгалтерии"
И ИмяВиртуальнойТаблицы = "")
Тогда
ДобавитьПоляПериодаВНаборДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0]);
КонецЕсли;
// Добавляем ресурсы
Для каждого Ресурс Из ОбъектМД.Ресурсы Цикл
Если ИмяВиртуальнойТаблицы = "Обороты" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Оборот", Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Оборот");
Если КорневойТип = "РегистрНакопления" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Приход", Ресурс.Синоним + " приход", Ресурс.Имя + "Приход");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Приход");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Расход", Ресурс.Синоним + " расход", Ресурс.Имя + "Расход");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Расход");
ИначеЕсли КорневойТип = "РегистрБухгалтерии" ТОгда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотДт", Ресурс.Синоним + " оборот Дт", Ресурс.Имя + "ОборотДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотКт", Ресурс.Синоним + " оборот Кт", Ресурс.Имя + "ОборотКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотКт");
Если НЕ Ресурс.Балансовый Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КорОборот", Ресурс.Синоним + " кор. оборот", Ресурс.Имя + "КорОборот");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КорОборот");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КорОборотДт", Ресурс.Синоним + " кор. оборот Дт", Ресурс.Имя + "КорОборотДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КорОборотДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КорОборотКт", Ресурс.Синоним + " кор. оборот Кт", Ресурс.Имя + "КорОборотКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КорОборотКт");
КонецЕсли;
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "ОборотыДтКт" Тогда
Если Ресурс.Балансовый Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Оборот", Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Оборот");
Иначе
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотДт", Ресурс.Синоним + " оборот Дт", Ресурс.Имя + "ОборотДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотКт", Ресурс.Синоним + " оборот Кт", Ресурс.Имя + "ОборотКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотКт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "ДвиженияССубконто" Тогда
Если Ресурс.Балансовый Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя, Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя);
Иначе
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Дт", Ресурс.Синоним + " Дт", Ресурс.Имя + "Дт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Дт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Кт", Ресурс.Синоним + " Кт", Ресурс.Имя + "Кт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Кт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "ОстаткиИОбороты" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйОстаток", Ресурс.Синоним + " нач. остаток", Ресурс.Имя + "НачальныйОстаток");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйОстаток");
Если КорневойТип = "РегистрБухгалтерии" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйОстатокДт", Ресурс.Синоним + " нач. остаток Дт", Ресурс.Имя + "НачальныйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйОстатокКт", Ресурс.Синоним + " нач. остаток Кт", Ресурс.Имя + "НачальныйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйОстатокКт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйРазвернутыйОстатокДт", Ресурс.Синоним + " нач. развернутый остаток Дт", Ресурс.Имя + "НачальныйРазвернутыйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйРазвернутыйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйРазвернутыйОстатокКт", Ресурс.Синоним + " нач. развернутый остаток Кт", Ресурс.Имя + "НачальныйРазвернутыйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйРазвернутыйОстатокКт");
КонецЕсли;
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Оборот", Ресурс.Синоним + " оборот", Ресурс.Имя + "Оборот");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Оборот");
Если КорневойТип = "РегистрНакопления" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Приход", Ресурс.Синоним + " приход", Ресурс.Имя + "Приход");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Приход");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Расход", Ресурс.Синоним + " расход", Ресурс.Имя + "Расход");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Расход");
ИначеЕсли КорневойТип = "РегистрБухгалтерии" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотДт", Ресурс.Синоним + " оборот Дт", Ресурс.Имя + "ОборотДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотКт", Ресурс.Синоним + " оборот Кт", Ресурс.Имя + "ОборотКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотКт");
КонецЕсли;
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйОстаток", Ресурс.Синоним + " кон. остаток", Ресурс.Имя + "КонечныйОстаток");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйОстаток");
Если КорневойТип = "РегистрБухгалтерии" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйОстатокДт", Ресурс.Синоним + " кон. остаток Дт", Ресурс.Имя + "КонечныйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйОстатокКт", Ресурс.Синоним + " кон. остаток Кт", Ресурс.Имя + "КонечныйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйОстатокКт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйРазвернутыйОстатокДт", Ресурс.Синоним + " кон. развернутый остаток Дт", Ресурс.Имя + "КонечныйРазвернутыйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйРазвернутыйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйРазвернутыйОстатокКт", Ресурс.Синоним + " кон. развернутый остаток Кт", Ресурс.Имя + "КонечныйРазвернутыйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйРазвернутыйОстатокКт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "Остатки" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Остаток", Ресурс.Синоним + " остаток", Ресурс.Имя + "Остаток");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Остаток");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОстатокДт", Ресурс.Синоним + " остаток Дт", Ресурс.Имя + "ОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОстатокКт", Ресурс.Синоним + " остаток Кт", Ресурс.Имя + "ОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОстатокКт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "РазвернутыйОстатокДт", Ресурс.Синоним + " развернутый остаток Дт", Ресурс.Имя + "РазвернутыйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "РазвернутыйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "РазвернутыйОстатокКт", Ресурс.Синоним + " развернутый остаток Кт", Ресурс.Имя + "РазвернутыйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "РазвернутыйОстатокКт");
ИначеЕсли КорневойТип = "РегистрСведений" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя, Ресурс.Синоним);
Если Ресурс.Тип.СодержитТип(Тип("Число")) Тогда
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя, Ресурс.Имя);
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "" Тогда
Если КорневойТип = "РегистрБухгалтерии" Тогда
Если Ресурс.Балансовый Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя, Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя);
Иначе
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Дт", Ресурс.Синоним + " Дт", Ресурс.Имя + "Дт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Дт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Кт", Ресурс.Синоним + " Кт", Ресурс.Имя + "Кт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Кт");
КонецЕсли;
Иначе
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя, Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ИначеЕсли ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы) Тогда
Если ИмяВиртуальнойТаблицы = "" Тогда
ОбъектМетаданных = ОбъектМД;
Иначе
ОбъектМетаданных = ОбъектМД.ТабличныеЧасти.Найти(ИмяВиртуальнойТаблицы);
Если ОбъектМетаданных = Неопределено Тогда
ОбъектМетаданных = ОбъектМД;
КонецЕсли;
КонецЕсли;
Для каждого Реквизит Из ОбъектМетаданных.Реквизиты Цикл
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Реквизит.Имя, Реквизит.Синоним);
Если Реквизит.Тип.СодержитТип(Тип("Число")) Тогда
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Реквизит.Имя);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьВыбранныеПоляКомпоновкиПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, НастройкаКомпоновки) Экспорт
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмяТаблицыБД);
Если СтрокиРавныЛкс(ТипТаблицы, "ВиртуальнаяТаблица") Тогда
ИмяВиртуальнойТаблицы = ПолучитьПоследнийФрагментЛкс(ПолноеИмяТаблицыБД);
Иначе
ИмяВиртуальнойТаблицы = "";
КонецЕсли;
ОбъектМД = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
ВыбранныеПоля = НастройкаКомпоновки.Выбор;
Если ИмяВиртуальнойТаблицы = "ОстаткиИОбороты" Тогда
ВыбранныеПоляНачальныйОстаток = ВыбранныеПоля.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляНачальныйОстаток.Заголовок = "Нач. остаток";
ВыбранныеПоляНачальныйОстаток.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
Если КорневойТип = "РегистрНакопления" Тогда
ВыбранныеПоляПриход = ВыбранныеПоля.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляПриход.Заголовок = "Приход";
ВыбранныеПоляПриход.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
ВыбранныеПоляРасход = ВыбранныеПоля.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляРасход.Заголовок = "Расход";
ВыбранныеПоляРасход.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
ИначеЕсли КорневойТип = "РегистрБухгалтерии" Тогда
ВыбранныеПоляОбороты = ВыбранныеПоля.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляОбороты.Заголовок = "Обороты";
ВыбранныеПоляОбороты.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
КонецЕсли;
ВыбранныеПоляКонечныйОстаток = ВыбранныеПоля.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляКонечныйОстаток.Заголовок = "Кон. остаток";
ВыбранныеПоляКонечныйОстаток.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
КонецЕсли;
Если КорневойТип = "РегистрНакопления" Тогда
Для каждого Ресурс Из ОбъектМД.Ресурсы Цикл
Если ИмяВиртуальнойТаблицы = "Обороты" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Оборот");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Приход",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Расход",, Ложь);
ИначеЕсли ИмяВиртуальнойТаблицы = "ОстаткиИОбороты" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйОстаток");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Оборот",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляПриход, Ресурс.Имя + "Приход");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляРасход, Ресурс.Имя + "Расход");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйОстаток");
ИначеЕсли ИмяВиртуальнойТаблицы = "" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя);
КонецЕсли;
КонецЦикла;
ИначеЕсли КорневойТип = "РегистрСведений" Тогда
Для каждого Ресурс Из ОбъектМД.Ресурсы Цикл
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя);
КонецЦикла;
ИначеЕсли КорневойТип = "РегистрБухгалтерии" Тогда
Для каждого Ресурс Из ОбъектМД.Ресурсы Цикл
Если ИмяВиртуальнойТаблицы = "Обороты" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Оборот",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОборотДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОборотКт");
Если Не Ресурс.Балансовый Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "КорОборот",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "КорОборотДт",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "КорОборотКт",, Ложь);
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "ОборотыДтКт" Тогда
Если Ресурс.Балансовый Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Оборот");
Иначе
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОборотДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОборотКт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "Остатки" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОстатокДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОстатокКт");
ИначеЕсли ИмяВиртуальнойТаблицы = "ОстаткиИОбороты" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйОстаток",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйОстатокДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйОстатокКт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйРазвернутыйОстатокДт",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйРазвернутыйОстатокКт",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляОбороты, Ресурс.Имя + "Оборот",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляОбороты, Ресурс.Имя + "ОборотДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляОбороты, Ресурс.Имя + "ОборотКт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйОстаток",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйОстатокДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйОстатокКт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйРазвернутыйОстатокДт",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйРазвернутыйОстатокКт",, Ложь);
ИначеЕсли ИмяВиртуальнойТаблицы = "ДвиженияССубконто" Тогда
Если Ресурс.Балансовый Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя);
Иначе
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Дт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Кт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "" Тогда
Если Ресурс.Балансовый Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя);
Иначе
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Дт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Кт");
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
//Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
ПоляТаблицыБД = ирКэш.ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД);
#Если Сервер И Не Сервер Тогда
ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки;
#КонецЕсли
Для каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл
Если ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
Продолжить;
КонецЕсли;
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, ПолеТаблицыБД.Имя);
КонецЦикла;
//КонецЕсли;
КонецПроцедуры
Процедура ДобавитьПолеГруппировкиЛкс(Группировка, Наименование, Синоним)
Если Группировка.Найти(Наименование, "Поле") = Неопределено Тогда
ГруппировкаСтр = Группировка.Добавить();
ГруппировкаСтр.Поле = Наименование;
ГруппировкаСтр.Использование = Истина;
ГруппировкаСтр.Представление = Синоним;
КонецЕсли;
КонецПроцедуры
Процедура ЗаполнитьСтруктуруКомпоновкиПоУмолчаниюПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, НастройкаКомпоновки) Экспорт
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмяТаблицыБД);
Если СтрокиРавныЛкс(ТипТаблицы, "ВиртуальнаяТаблица") Тогда
ИмяВиртуальнойТаблицы = ПолучитьПоследнийФрагментЛкс(ПолноеИмяТаблицыБД);
Иначе
ИмяВиртуальнойТаблицы = "";
КонецЕсли;
ОбъектМД = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
ЭлементСтруктуры = НастройкаКомпоновки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
////ПолеГруппировки = ЭлементСтруктуры.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
//Если ТипТаблицы = "Справочники" Тогда
// Если ИмяВиртуальнойТаблицы = "" Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Наименование", "Наименование");
// Иначе
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Ссылка.Наименование", "Наименование");
// КонецЕсли;
//ИначеЕсли ТипТаблицы = "Документы" Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Ссылка", "Ссылка");
//ИначеЕсли Истина
// И ЭлементСтруктуры.ПоляГруппировки.ДоступныеПоляПолейГруппировок.Элементы.Количество() > 0
// И ОбъектМД.Измерения.Количество() > 0
//Тогда
// Если ТипТаблицы = "РегистрБухгалтерии" Тогда
// Если ИмяВиртуальнойТаблицы = "" Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Регистратор", "Регистратор");
// ИначеЕсли ИмяВиртуальнойТаблицы = "ДвиженияССубконто" Тогда
// ЭлементСтруктуры.ПоляГруппировки.Элементы.Удалить(ПолеГруппировки);
// // Группировки по забалансовым
// Для каждого Измерение Из ОбъектМД.Измерения Цикл
// Если Измерение.Балансовый Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, Измерение.Имя, Измерение.Синоним);
// КонецЕсли
// КонецЦикла;
// // ИзмеренияДт
// Для каждого Измерение Из ОбъектМД.Измерения Цикл
// Если НЕ Измерение.Балансовый Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, Измерение.Имя + "Дт", Измерение.Синоним + " Дт");
// КонецЕсли
// КонецЦикла;
// Для К = 1 По 3 Цикл
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СубконтоДт" + К, "СубконтоДт" + К);
// КонецЦикла;
// // ИзмеренияКт
// Для каждого Измерение Из ОбъектМД.Измерения Цикл
// Если НЕ Измерение.Балансовый Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, Измерение.Имя + "Кт", Измерение.Синоним + " Кт");
// КонецЕсли
// КонецЦикла;
// Для К = 1 По 3 Цикл
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СубконтоКт" + К, "СубконтоКт" + К);
// КонецЦикла;
// Иначе
// Если ЭлементСтруктуры.ПоляГруппировки.ДоступныеПоляПолейГруппировок.Элементы.Найти("Счет")<> Неопределено Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Счет", "Счет");
// Иначе
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СчетДт", "СчетДт");
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СчетКт", "СчетКт");
// КонецЕсли;
// КонецЕсли;
// Иначе
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка,
// ОбъектМД.Измерения[0].Имя,
// ОбъектМД.Измерения[0].Синоним);
// КонецЕсли
//КонецЕсли;
ЭлементПорядка = ЭлементСтруктуры.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
КонецПроцедуры
Функция ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВыражениеПараметраПериодичность = Неопределено, ДобавитьАвтополеКоличествоСтрок = Истина,
Знач ИндексПараметраПериодичность = Неопределено, Знач ПсевдонимТаблицы = "Т", ИменаВместоПредставлений = Ложь, РасширенноеЗаполнение = Ложь) Экспорт
Схема = Новый СхемаКомпоновкиДанных;
ИсточникДанных = ДобавитьЛокальныйИсточникДанныхЛкс(Схема);
НаборДанных = ДобавитьНаборДанныхЗапросЛкс(Схема.НаборыДанных, ИсточникДанных);
#Если Сервер И Не Сервер Тогда
НаборДанных = Схема.НаборыДанных.Добавить();
#КонецЕсли
НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина;
НаборДанных.Запрос = ПолучитьТекстЗапросаПолейТаблицыБДЛкс(ПолноеИмяТаблицыБД, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность, ПсевдонимТаблицы, Ложь);
Если ДобавитьАвтополеКоличествоСтрок Тогда
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(Схема);
КонецЕсли;
Если Ложь
Или ИменаВместоПредставлений
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_1 // Антибаг платформы в режиме совместимости. Предопределенные реквизиты имеют англ. имена полей
Тогда
Построитель = Новый ПостроительЗапроса(НаборДанных.Запрос);
Построитель.ЗаполнитьНастройки();
Для Каждого ДоступноеПоле Из Построитель.ДоступныеПоля Цикл
ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНабора.Поле = ДоступноеПоле.ПутьКДанным;
//ПолеНабора.ПутьКДанным = ДоступноеПоле.ПутьКДанным;
Если ИменаВместоПредставлений Тогда
ПолеНабора.Заголовок = ДоступноеПоле.Имя;
Иначе
ПолеНабора.Заголовок = ДоступноеПоле.Представление;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если РасширенноеЗаполнение Тогда
ДобавитьПоляНабораДанныхЛкс(ПолноеИмяТаблицыБД, Схема);
ЗаполнитьСтруктуруКомпоновкиПоУмолчаниюПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, Схема.НастройкиПоУмолчанию);
ДобавитьВыбранныеПоляКомпоновкиПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, Схема.НастройкиПоУмолчанию);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "Title", Метаданные[Отчет.ТипДанных][Отчет.ИмяОбъекта].Синоним);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "TitleOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "FilterOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "DataParametersOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить);
КонецЕсли;
Возврат Схема;
КонецФункции
Функция ПолучитьТекстЗапросаПолейТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = Неопределено, ПсевдонимТаблицы = "Т",
БлокироватьПолучениеДанных = Истина) Экспорт
ОписаниеТаблицы = ПолучитьОписаниеТаблицыБДИис(ПолноеИмяТаблицыБД);
ПараметрыВиртуальнойТаблицы = "";
Если БлокироватьПолучениеДанных Тогда
ИндексПараметраОтбора = ОписаниеТаблицы.ИндексПараметраОтбора;
Иначе
ИндексПараметраОтбора = Неопределено;
КонецЕсли;
МаксимальныйИндекс = ИндексПараметраОтбора;
Если ИндексПараметраПериодичность <> Неопределено Тогда
Если МаксимальныйИндекс <> Неопределено Тогда
МаксимальныйИндекс = Макс(МаксимальныйИндекс, ИндексПараметраПериодичность);
Иначе
МаксимальныйИндекс = ИндексПараметраПериодичность;
КонецЕсли;
КонецЕсли;
Если МаксимальныйИндекс <> Неопределено Тогда
МассивВыраженийПараметров = Новый Массив;
Для Счетчик = 0 По МаксимальныйИндекс Цикл
МассивВыраженийПараметров.Добавить("");
КонецЦикла;
Если ИндексПараметраОтбора <> Неопределено Тогда
МассивВыраженийПараметров[ИндексПараметраОтбора] = "ЛОЖЬ";
КонецЕсли;
Если ИндексПараметраПериодичность <> Неопределено Тогда
МассивВыраженийПараметров[ИндексПараметраПериодичность] = ВыражениеПараметраПериодичность;
КонецЕсли;
ПараметрыВиртуальнойТаблицы = ирОбщий.ПолучитьСтрокуСРазделителемИзМассиваЛкс(МассивВыраженийПараметров);
КонецЕсли;
Если ЗначениеЗаполнено(ПараметрыВиртуальнойТаблицы) Тогда
ПолноеИмяТаблицыБД = ПолноеИмяТаблицыБД + "(" + ПараметрыВиртуальнойТаблицы + ")";
КонецЕсли;
Если Не ЗначениеЗаполнено(ПсевдонимТаблицы) Тогда
ПсевдонимТаблицы = "Т";
КонецЕсли;
ТекстЗапроса = "ВЫБРАТЬ " + ПсевдонимТаблицы + ".* ИЗ " + ПолноеИмяТаблицыБД + " КАК " + ПсевдонимТаблицы;
Возврат ТекстЗапроса;
КонецФункции
Функция _ПолучитьСхемуКомпоновкиПоВсемТаблицамБДЛкс(ТаблицаВсехТаблицБД, ИмяНабораДанных = "НаборДанных1",
ДобавитьАвтополеКоличествоСтрок = Истина, ПсевдонимТаблицы = "Т", ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "") Экспорт
КорневаяСхема = Новый СхемаКомпоновкиДанных;
НастройкиПоУмолчанию = КорневаяСхема.НастройкиПоУмолчанию;
Для Каждого ОписаниеТаблицы Из ТаблицаВсехТаблицБД Цикл
ПолноеИмяТаблицыБД = ОписаниеТаблицы.ПолноеИмя;
Схема = Новый СхемаКомпоновкиДанных;
ИсточникДанных = ДобавитьЛокальныйИсточникДанныхЛкс(Схема);
НаборДанных = ДобавитьНаборДанныхЗапросЛкс(Схема.НаборыДанных, ИсточникДанных);
#Если Сервер И Не Сервер Тогда
НаборДанных = Схема.НаборыДанных.Добавить();
#КонецЕсли
НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина;
//ПолноеИмяТаблицыБД = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
НаборДанных.Запрос = "ВЫБРАТЬ " + ПсевдонимТаблицы + ".* ИЗ " + ПолноеИмяТаблицыБД + " КАК " + ПсевдонимТаблицы;
Если ДобавитьАвтополеКоличествоСтрок Тогда
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(Схема);
КонецЕсли;
// Антибаг платформы в режиме совместимости. Предопределенные реквизиты имеют англ. имена полей
Если Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_1 Тогда
Построитель = Новый ПостроительЗапроса(НаборДанных.Запрос);
Построитель.ЗаполнитьНастройки();
Для Каждого ДоступноеПоле Из Построитель.ДоступныеПоля Цикл
ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНабора.Поле = ДоступноеПоле.ПутьКДанным;
//ПолеНабора.ПутьКДанным = ДоступноеПоле.ПутьКДанным;
ПолеНабора.Заголовок = ДоступноеПоле.Представление;
КонецЦикла;
КонецЕсли;
ВложеннаяСхема = КорневаяСхема.ВложенныеСхемыКомпоновкиДанных.Добавить();
//ВложеннаяСхема.Заголовок = ОписаниеТаблицы.Представление;
ВложеннаяСхема.Схема = Схема;
ВложеннаяСхема.Имя = СтрЗаменить(ПолноеИмяТаблицыБД, ".", "_1_");
ЭлементСтруктуры = НастройкиПоУмолчанию.Структура.Добавить(Тип("НастройкиВложенногоОбъектаКомпоновкиДанных"));
ЭлементСтруктуры.УстановитьИдентификатор(ВложеннаяСхема.Имя);
КонецЦикла;
Возврат КорневаяСхема;
КонецФункции
Функция ДобавитьДоступнуюТаблицуБДЛкс(ДоступныеТаблицыБД, ПолноеИмя, ПолноеИмяМД = "", ТипТаблицы = "", Имя = "", Представление = "", СхемаТаблицы = "", ПроверятьУникальность = Ложь,
ОбъектМД = Неопределено, ИндексПараметраОтбора = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(ПолноеИмя) Тогда
ПолноеИмя = ПолноеИмяМД;
КонецЕсли;
Фрагменты = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
Если Фрагменты.Количество() > 1 Тогда
//Если Не ЗначениеЗаполнено(СхемаТаблицы) Тогда
// СхемаТаблицы = Фрагменты[0];
//КонецЕсли;
Фрагменты.Удалить(0);
КонецЕсли;
Если ПроверятьУникальность Тогда
СтрокаТаблицы = ДоступныеТаблицыБД.Найти(НРег(ПолноеИмя), "НПолноеИмя");
Иначе
СтрокаТаблицы = Неопределено;
КонецЕсли;
Если СтрокаТаблицы = Неопределено Тогда
СтрокаТаблицы = ДоступныеТаблицыБД.Добавить();
СтрокаТаблицы.Схема = СхемаТаблицы;
СтрокаТаблицы.ПолноеИмяМД = ПолноеИмяМД;
СтрокаТаблицы.ПолноеИмя = ПолноеИмя;
СтрокаТаблицы.НПолноеИмя = НРег(СтрокаТаблицы.ПолноеИмя);
СтрокаТаблицы.ИндексПараметраОтбора = ИндексПараметраОтбора;
Если Не ЗначениеЗаполнено(Имя) Тогда
СтрокаТаблицы.Имя = ирОбщий.ПолучитьСтрокуСРазделителемИзМассиваЛкс(Фрагменты, ".");
Иначе
СтрокаТаблицы.Имя = Имя;
КонецЕсли;
СтрокаТаблицы.Представление = Представление;
Если Не ЗначениеЗаполнено(ТипТаблицы) Тогда
ТипТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(ПолноеИмя);
КонецЕсли;
СтрокаТаблицы.Тип = ТипТаблицы;
Если ТипТаблицы = "Перерасчет" Тогда
МетаРегистрРасчета = ОбъектМД.Родитель();
СтрокаТаблицы.Имя = МетаРегистрРасчета.Имя + "." + СтрокаТаблицы.Имя;
СтрокаТаблицы.Представление = МетаРегистрРасчета.Представление() + "." + СтрокаТаблицы.Представление;
КонецЕсли;
//СтрокаТаблицы.Описание = МетаИсточник.Представление();
КонецЕсли;
Возврат СтрокаТаблицы;
КонецФункции
Функция ПолучитьИндексКартинкиТипаТаблицыБДЛкс(ТипТаблицы) Экспорт
ИндексКартинки = 14;
Если ТипТаблицы = "Константы" Тогда
ИндексКартинки = 2;
ИначеЕсли ТипТаблицы = "Константа" Тогда
ИндексКартинки = 2;
//ИначеЕсли ТипТаблицы = "ТабличнаяЧасть" Тогда
ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
ИндексКартинки = 20;
ИначеЕсли ТипТаблицы = "Изменения" Тогда
ИндексКартинки = 27;
ИначеЕсли ТипТаблицы = "ВиртуальнаяТаблица" Тогда
ИндексКартинки = 28;
ИначеЕсли ТипТаблицы = "ВнешнийИсточникДанных" Тогда
ИндексКартинки = 29;
ИначеЕсли ТипТаблицы = "Справочник" Тогда
ИндексКартинки = 3;
ИначеЕсли ТипТаблицы = "Перечисление" Тогда
ИндексКартинки = 4;
ИначеЕсли ТипТаблицы = "Документ" Тогда
ИндексКартинки = 5;
ИначеЕсли ТипТаблицы = "ЖурналДокументов" Тогда
ИндексКартинки = 6;
ИначеЕсли ТипТаблицы = "Последовательность" Тогда
ИндексКартинки = 7;
ИначеЕсли ТипТаблицы = "РегистрНакопления" Тогда
ИндексКартинки = 8;
ИначеЕсли ТипТаблицы = "РегистрСведений" Тогда
ИндексКартинки = 9;
ИначеЕсли ТипТаблицы = "РегистрБухгалтерии" Тогда
ИндексКартинки = 10;
ИначеЕсли ТипТаблицы = "РегистрРасчета" Тогда
ИндексКартинки = 11;
ИначеЕсли ТипТаблицы = "ПланОбмена" Тогда
ИндексКартинки = 19;
ИначеЕсли ТипТаблицы = "Задача" Тогда
ИндексКартинки = 17;
ИначеЕсли ТипТаблицы = "БизнесПроцесс" Тогда
ИндексКартинки = 18;
ИначеЕсли ТипТаблицы = "РегистрРасчета" Тогда
ИндексКартинки = 26;
ИначеЕсли ТипТаблицы = "ПланВидовРасчета" Тогда
ИндексКартинки = 25;
ИначеЕсли ТипТаблицы = "ПланВидовХарактеристик" Тогда
ИндексКартинки = 22;
ИначеЕсли ТипТаблицы = "Перечисление" Тогда
ИндексКартинки = 23;
ИначеЕсли ТипТаблицы = "ПланСчетов" Тогда
ИндексКартинки = 24;
ИначеЕсли ТипТаблицы = "Перерасчет" Тогда
ИндексКартинки = 30;
ИначеЕсли СтрокиРавныЛкс(ТипТаблицы, "Table") Тогда
ИндексКартинки = 3;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции
Функция НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(Знач Коллекция, Знач Свойство, Знач Значение, Знач ТипЭлемента = Неопределено) Экспорт
Структура = Новый Структура(Свойство);
Для каждого Элемент Из Коллекция Цикл
Если Истина
И ТипЭлемента <> Неопределено
И ТипЗнч(Элемент) <> ТипЭлемента
Тогда
Продолжить;
КонецЕсли;
ЗаполнитьЗначенияСвойств(Структура, Элемент, Свойство);
Если Структура[Свойство] = Значение Тогда
Результат = Элемент;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция НайтиДобавитьЭлементНастроекКомпоновкиПоПредставлениюЛкс(Знач ЭлементыНастройки, Знач Представление = "", Знач ПроверятьУникальность = Истина,
Знач ИспользованиеДляНового = Истина) Экспорт
Попытка
ЭлементыНастройки = ЭлементыНастройки.Элементы;
Исключение
КонецПопытки;
Если ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовОтбораКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ЭлементОтбораКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда
ТипЭлемента = Неопределено;
КонецЕсли;
Если ПроверятьУникальность Тогда
ЭлементНастроек = НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(ЭлементыНастройки, "Представление", Представление, ТипЭлемента);
КонецЕсли;
Если ЭлементНастроек = Неопределено Тогда
Если ТипЭлемента <> Неопределено Тогда
ЭлементНастроек = ЭлементыНастройки.Добавить(ТипЭлемента);
Иначе
ЭлементНастроек = ЭлементыНастройки.Добавить();
КонецЕсли;
ЭлементНастроек.Представление = Представление;
ЭлементНастроек.Использование = ИспользованиеДляНового;
КонецЕсли;
Возврат ЭлементНастроек;
КонецФункции
Функция НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(Знач ЭлементыНастройки, Знач Поле = "", Знач ПроверятьУникальность = Истина,
Знач ИспользованиеДляНового = Истина) Экспорт
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
Попытка
ЭлементыНастройки = ЭлементыНастройки.Элементы;
Исключение
КонецПопытки;
ТипЭлемента = ТипЭлементаИзТипаКоллекцииКомпоновкиЛкс(ЭлементыНастройки);
Если ПроверятьУникальность Тогда
ЭлементНастроек = НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементыНастройки, Поле, ТипЭлемента);
КонецЕсли;
Если ЭлементНастроек = Неопределено Тогда
Если ТипЭлемента <> Неопределено Тогда
ЭлементНастроек = ЭлементыНастройки.Добавить(ТипЭлемента);
Иначе
ЭлементНастроек = ЭлементыНастройки.Добавить();
КонецЕсли;
ЭлементНастроек.Поле = Поле;
ЭлементНастроек.Использование = ИспользованиеДляНового;
КонецЕсли;
Возврат ЭлементНастроек;
КонецФункции
Функция ТипЭлементаИзТипаКоллекцииКомпоновкиЛкс(ЭлементыНастройки) Экспорт
Если ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовПорядкаКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ЭлементПорядкаКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияВыбранныхПолейКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ВыбранноеПолеКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияПолейГруппировкиКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ПолеГруппировкиКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда
ТипЭлемента = Неопределено;
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовОтбораКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ЭлементОтбораКомпоновкиДанных");
КонецЕсли;
Возврат ТипЭлемента;
КонецФункции
Функция НайтиЭлементНастроекКомпоновкиПоПолюЛкс(Знач ЭлементыНастройки, Знач Поле, Знач ТипЭлемента = Неопределено) Экспорт
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
Если ТипЭлемента = Неопределено Тогда
ТипЭлемента = ТипЭлементаИзТипаКоллекцииКомпоновкиЛкс(ЭлементыНастройки);
КонецЕсли;
Для Каждого ЭлементНастроек Из ЭлементыНастройки Цикл
Если Истина
И ТипЭлемента <> Неопределено
И ТипЗнч(ЭлементНастроек) <> ТипЭлемента
Тогда
Попытка
ДочерниеЭлементыНастройки = ЭлементНастроек.Элементы;
Исключение
ДочерниеЭлементыНастройки = Неопределено;
КонецПопытки;
Если ДочерниеЭлементыНастройки <> Неопределено Тогда
НайденныйЭлемент = НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ДочерниеЭлементыНастройки, Поле, ТипЭлемента);
Если НайденныйЭлемент <> Неопределено Тогда
Прервать;
КонецЕсли;
КонецЕсли;
Иначе
Если ТипЭлемента = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
ПолеЭлемента = ЭлементНастроек.ЛевоеЗначение;
Иначе
ПолеЭлемента = ЭлементНастроек.Поле;
КонецЕсли;
Если ПолеЭлемента = Поле Тогда
НайденныйЭлемент = ЭлементНастроек;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат НайденныйЭлемент;
КонецФункции
Функция НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(Знач Группировки, Знач Поле = "") Экспорт
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
ЭлементСуществует = Ложь;
Для Каждого Группировка Из Группировки Цикл
Поля = Группировка.ПоляГруппировки.Элементы;
Если Ложь
Или (Истина
И Поля.Количество() = 0
И "" + Поле = "")
Или (Истина
И Поля.Количество() = 1
И Поля[0].Поле = Поле)
Тогда
ЭлементСуществует = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ЭлементСуществует Тогда
Если ТипЗнч(Группировки) = Тип("КоллекцияЭлементовСтруктурыНастроекКомпоновкиДанных") Тогда
Группировка = Группировки.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Иначе
Группировка = Группировки.Добавить();
КонецЕсли;
Группировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
Группировка.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
Если "" + Поле <> "" Тогда
ПолеГруппировки = Группировка.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
ПолеГруппировки.Поле = Поле;
КонецЕсли;
КонецЕсли;
Группировка.Использование = Истина;
Возврат Группировка;
КонецФункции
Функция НайтиЭлементОтбораКомпоновкиЛкс(Знач Отбор, Знач ИменаПолей, Знач НайденныеЭлементы = Неопределено, Знач ТолькоВключенныеНаРавенствоЗначению = Ложь,
Знач ВключатьПодчиненные = Ложь) Экспорт
Если ТипЗнч(Отбор) = Тип("ОтборКомпоновкиДанных") Тогда
ЭлементыОтбора = Отбор.Элементы;
Иначе
ЭлементыОтбора = Отбор;
КонецЕсли;
Если ТипЗнч(ИменаПолей) = Тип("Строка") Тогда
МассивИменПолей = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаПолей, ",", Истина);
Иначе
МассивИменПолей = ИменаПолей;
КонецЕсли;
МассивПолей = Новый Массив;
Для Каждого ИмяПоля Из МассивИменПолей Цикл
МассивПолей.Добавить(Новый ПолеКомпоновкиДанных(ИмяПоля));
КонецЦикла;
МассивПолейПуст = МассивПолей.Количество() = 0;
Если НайденныеЭлементы = Неопределено Тогда
НайденныеЭлементы = Новый Соответствие;
КонецЕсли;
Для Каждого ЭлементОтбора ИЗ ЭлементыОтбора Цикл
Если Истина
И ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных")
И (Ложь
Или Не ТолькоВключенныеНаРавенствоЗначению
Или (Истина
И ЭлементОтбора.Использование
И ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно
И ТипЗнч(ЭлементОтбора.ЛевоеЗначение) = Тип("ПолеКомпоновкиДанных")
И ТипЗнч(ЭлементОтбора.ПравоеЗначение) <> Тип("ПолеКомпоновкиДанных")))
Тогда
Если Ложь
Или МассивПолейПуст
Или МассивПолей.Найти(ЭлементОтбора.ЛевоеЗначение) <> Неопределено
Тогда
НайденныеЭлементы.Вставить("" + ЭлементОтбора.ЛевоеЗначение, ЭлементОтбора);
КонецЕсли;
ИначеЕсли Истина
И ВключатьПодчиненные
И ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
Тогда
НайтиЭлементОтбораКомпоновкиЛкс(ЭлементОтбора.Элементы, МассивИменПолей, НайденныеЭлементы, ТолькоВключенныеНаРавенствоЗначению);
КонецЕсли;
КонецЦикла;
Если МассивИменПолей.Количество() = 1 Тогда
Результат = НайденныеЭлементы[МассивИменПолей[0]];
Иначе
Результат = НайденныеЭлементы;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НайтиДобавитьЭлементОтбораКомпоновкиЛкс(Знач ЭлементыОтбора, Знач Поле = "", Знач Значение = Неопределено, Знач Сравнение = "", Знач ДоступныеПоляОтбора = Неопределено,
Знач ПроверятьУникальность = Истина) Экспорт
Если ТипЗнч(ЭлементыОтбора) = Тип("НастройкиКомпоновкиДанных") Тогда
ЭлементыОтбора = ЭлементыОтбора.Отбор;
КонецЕсли;
Если ТипЗнч(ЭлементыОтбора) = Тип("ОтборКомпоновкиДанных") Тогда
ДоступныеПоляОтбора = ЭлементыОтбора.ДоступныеПоляОтбора;
ЭлементыОтбора = ЭлементыОтбора.Элементы;
ИначеЕсли ТипЗнч(ЭлементыОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
ЭлементыОтбора = ЭлементыОтбора.Элементы;
Иначе
ЭлементыОтбора = ЭлементыОтбора;
КонецЕсли;
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
Если ПроверятьУникальность Тогда
ЭлементОтбора = НайтиЭлементОтбораКомпоновкиЛкс(ЭлементыОтбора, "" + Поле);
КонецЕсли;
Если ЭлементОтбора = Неопределено Тогда
ЭлементОтбора = ЭлементыОтбора.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Поле;
КонецЕсли;
Если ТипЗнч(Значение) = Тип("Массив") Тогда
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(Значение);
Значение = СписокЗначений;
КонецЕсли;
// Вид сравнения
Если ТипЗнч(Сравнение) = Тип("ВидСравненияКомпоновкиДанных") Тогда
Иначе
Если ТипЗнч(Значение) = Тип("СписокЗначений") Тогда
Сравнение = ВидСравненияКомпоновкиДанных.ВСписке;
Иначе
Сравнение = ВидСравненияКомпоновкиДанных.Равно;
КонецЕсли;
КонецЕсли;
Если Истина
И Сравнение = ВидСравненияКомпоновкиДанных.Равно
И Значение = Неопределено
И ДоступныеПоляОтбора <> Неопределено
Тогда
ДоступноеПолеОтбора = ДоступныеПоляОтбора.НайтиПоле(Поле);
Если ДоступноеПолеОтбора <> Неопределено Тогда
Значение = ДоступноеПолеОтбора.Тип.ПривестиЗначение(Значение);
Если Истина
И Значение = ""
И ДоступноеПолеОтбора.Тип.КвалификаторыСтроки.Длина = 0
Тогда
Сравнение = ВидСравненияКомпоновкиДанных.Содержит;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ЭлементОтбора.ВидСравнения = Сравнение;
ЭлементОтбора.ПравоеЗначение = Значение;
ЭлементОтбора.Использование = Истина;
Возврат ЭлементОтбора;
КонецФункции
// Таблица - ТаблицаЗначений, ТабличнаяЧасть, НаборЗаписей
Функция ПолучитьНеуникальныеЗначенияКолонкиТаблицыЛкс(Таблица, ИмяКолонки, ИгнорироватьРегистрДляПростогоСтрокогоТипа = Истина, ОтборСтрок = Неопределено) Экспорт
Если ТипЗнч(Таблица) = Тип("ТаблицаЗначений") Тогда
КопияТаблицы = Таблица.Скопировать(ОтборСтрок, ИмяКолонки);
Иначе
КопияТаблицы = Таблица.Выгрузить(ОтборСтрок, ИмяКолонки);
КонецЕсли;
Типы = КопияТаблицы.Колонки[ИмяКолонки].ТипЗначения.Типы();
Если Истина
И Типы.Количество() = 1
И Типы[0] = Тип("Строка")
И ИгнорироватьРегистрДляПростогоСтрокогоТипа
Тогда
ИмяКолонкиНрег = ИмяКолонки + "_Нрег777233464645";
КопияТаблицы.Колонки.Добавить(ИмяКолонкиНрег);
Для Каждого СтрокаКопииТаблицы Из КопияТаблицы Цикл
СтрокаКопииТаблицы[ИмяКолонкиНрег] = НРег(СтрокаКопииТаблицы[ИмяКолонки]);
КонецЦикла;
Иначе
ИмяКолонкиНрег = ИмяКолонки;
КонецЕсли;
КолонкаКоличества = ИмяКолонки + "7773534765"; //гарантировано уникальное имя колонки
КопияТаблицы.Колонки.Добавить(КолонкаКоличества);
КопияТаблицы.ЗаполнитьЗначения(1, КолонкаКоличества);
КопияТаблицы.Свернуть(ИмяКолонкиНрег, КолонкаКоличества);
КопияТаблицы.Сортировать(КолонкаКоличества + " Убыв");
МассивНеуникальных = Новый Массив;
Для Индекс = 0 По КопияТаблицы.Количество() - 1 Цикл
СтрокаКопии = КопияТаблицы[Индекс];
Если СтрокаКопии[КолонкаКоличества] > 1 Тогда
МассивНеуникальных.Добавить(СтрокаКопии[ИмяКолонкиНрег]);
КонецЕсли;
КонецЦикла;
Возврат МассивНеуникальных;
КонецФункции // ПолучитьНеуникальныеЗначенияКолонки()
// Таблица - ТаблицаЗначений, ТабличнаяЧасть, НаборЗаписей
// ИменаКолонок - Строка - имена колонок через запятую
Функция ПолучитьНеуникальныеКлючиКолонкиТаблицыЛкс(Таблица, ИменаКолонок) Экспорт
Если ТипЗнч(Таблица) = Тип("ТаблицаЗначений") Тогда
КопияТаблицы = Таблица.Скопировать(, ИменаКолонок);
Иначе
КопияТаблицы = Таблица.Выгрузить(, ИменаКолонок);
КонецЕсли;
КолонкаКоличества = "Количество7773534765"; //гарантировано уникальное имя колонки
КопияТаблицы.Колонки.Добавить(КолонкаКоличества);
КопияТаблицы.ЗаполнитьЗначения(1, КолонкаКоличества);
КопияТаблицы.Свернуть(ИменаКолонок, КолонкаКоличества);
КопияТаблицы.Сортировать(КолонкаКоличества + " Убыв");
МассивНеуникальных = Новый Массив;
Для Индекс = 0 По КопияТаблицы.Количество() - 1 Цикл
СтрокаКопии = КопияТаблицы[Индекс];
Если СтрокаКопии[КолонкаКоличества] > 1 Тогда
НеуникальныйКлюч = Новый Структура(ИменаКолонок);
ЗаполнитьЗначенияСвойств(НеуникальныйКлюч, СтрокаКопии);
МассивНеуникальных.Добавить(НеуникальныйКлюч);
КонецЕсли;
КонецЦикла;
Возврат МассивНеуникальных;
КонецФункции // ПолучитьНеуникальныеЗначенияКолонки()
Функция СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД) Экспорт
НаборЗаписей = Новый (ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД));
Возврат НаборЗаписей;
КонецФункции
Функция ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, РасширениеТипа = "НаборЗаписей") Экспорт
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяТаблицыБД);
Если Фрагменты.Количество() > 2 Тогда
Если Фрагменты[0] = "РегистрРасчета" Тогда
ИмяТипа = "Перерасчет" + РасширениеТипа + "." + Фрагменты[1] + "." + Фрагменты[2];
ИначеЕсли Фрагменты[0] = "РегистрБухгалтерии" Тогда
ИмяТипа = "РегистрБухгалтерии" + РасширениеТипа + "." + Фрагменты[1];
ИначеЕсли Фрагменты[0] = "ВнешнийИсточникДанных" Тогда
ИмяТипа = "ВнешнийИсточникДанныхТаблица" + РасширениеТипа + "." + Фрагменты[1] + "." + Фрагменты[3];
КонецЕсли;
Иначе
ИмяТипа = СтрЗаменить(ПолноеИмяТаблицыБД, ".", РасширениеТипа + ".");
КонецЕсли;
Возврат ИмяТипа;
КонецФункции
Функция ПолучитьТипКлючаЗаписиТаблицыЛкс(ПолноеИмяТаблицы) Экспорт
ТипТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицы);
Если ирОбщий.ЛиКорневойТипСсылкиЛкс(ТипТаблицы) Тогда
Результат = Тип(ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяТаблицы));
ИначеЕсли Истина
И ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы)
И ТипТаблицы <> "Перерасчет"
И ТипТаблицы <> "Последовательность"
Тогда
Результат = Тип(СтрЗаменить(ПолноеИмяТаблицы, ".", "КлючЗаписи."));
Иначе
Результат = Тип("Неопределено");
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ВернутьСтруктуру - Булево - возвращать структуру иначе список значений
// КлючаНабораЗаписейРегистраСведений - Булево - для регистров сведений подчиненных регистратору вернуть ключ записываемого объекта
//
Функция ПолучитьСтруктуруКлючаТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, ВключатьНомерСтроки = Истина, ВернутьСтруктуру = Истина, КлючаНабораЗаписейРегистраСведений = Истина) Экспорт
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяТаблицыБД);
СписокПолей = Новый СписокЗначений;
Если Ложь
Или ЛиТипТаблицыМетассылкиЛкс(ТипТаблицы)
Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы)
Тогда
СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), "Ссылка");
ИначеЕсли ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда
ОбъектМД = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
НаборЗаписей = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
#Если Сервер И Не Сервер Тогда
НаборЗаписей = РегистрыСведений.ВерсииОбъектов.СоздатьНаборЗаписей();
#КонецЕсли
Если Истина
И ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору
И Не КлючаНабораЗаписейРегистраСведений
Тогда
Если ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
СписокПолей.Добавить(Новый ОписаниеТипов("Дата"), "Период");
КонецЕсли;
Если ОбъектМД.ПериодичностьРегистраСведений = Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.ПозицияРегистратора Тогда
СписокПолей.Добавить(НаборЗаписей.Отбор.Регистратор.ТипЗначения, "Регистратор");
КонецЕсли;
Для Каждого Измерение Из ОбъектМД.Измерения Цикл
СписокПолей.Добавить(Измерение.Тип, Измерение.Имя);
КонецЦикла;
КонецЕсли;
Если СписокПолей.Количество() = 0 Тогда
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
Если Ложь
Или ЭлементОтбора.Использование
Или ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
Тогда
СписокПолей.Добавить(ЭлементОтбора.ТипЗначения, ЭлементОтбора.Имя);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ВключатьНомерСтроки Тогда
Если ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы) Тогда
СписокПолей.Добавить(Новый ОписаниеТипов("Дата"), "Период");
ИначеЕсли Истина
И ТипТаблицы <> "Перерасчет"
И (Ложь
Или Не ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
Или (КлючаНабораЗаписейРегистраСведений И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору))
Тогда
СписокПолей.Добавить(Новый ОписаниеТипов("Число"), "НомерСтроки");
КонецЕсли;
КонецЕсли;
ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), "Ссылка");
Если ВключатьНомерСтроки Тогда
СписокПолей.Добавить(Новый ОписаниеТипов("Число"), "НомерСтроки");
КонецЕсли;
ИначеЕсли ТипТаблицы = "Изменения" Тогда
// Такой способ может быть долгим при частых вызовах
ПостроительЗапроса = Новый ПостроительЗапроса;
ПостроительЗапроса.Текст = "ВЫБРАТЬ * ИЗ " + ПолноеИмяТаблицыБД + " КАК _Таблица_";
ПостроительЗапроса.ЗаполнитьНастройки();
Для Каждого ДоступноеПоле Из ПостроительЗапроса.ДоступныеПоля Цикл
Если Ложь
Или СтрокиРавныЛкс(ДоступноеПоле.ПутьКДанным, "НомерСообщения")
Тогда
Продолжить;
КонецЕсли;
СписокПолей.Добавить(ДоступноеПоле.ТипЗначения, ДоступноеПоле.ПутьКДанным);
КонецЦикла;
ИначеЕсли ТипТаблицы = "Внешняя" Тогда
ТаблицаМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмяТаблицыБД);
Если ТаблицаМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные Тогда
СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), "Ссылка");
Иначе
НаборЗаписей = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
СписокПолей.Добавить(ЭлементОтбора.ТипЗначения, ЭлементОтбора.Имя);
КонецЦикла;
КонецЕсли;
ИначеЕсли ТипТаблицы = "ЖурналДокументов" Тогда
Поля = ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Поле = Поля.Найти("Ссылка", "Имя");
СписокПолей.Добавить(Поле.ТипЗначения, "Ссылка");
Иначе
ВызватьИсключение "Полученияе структуры ключа таблицы БД типа " + ТипТаблицы + " не поддерживается";
КонецЕсли;
Если ВернутьСтруктуру Тогда
Результат = Новый Структура();
Для Каждого ЭлементСписка Из СписокПолей Цикл
Результат.Вставить(ЭлементСписка.Представление, ЭлементСписка.Значение);
КонецЦикла;
Иначе
Результат = СписокПолей;
КонецЕсли;
Возврат Результат;
КонецФункции
// Для подчиненного регистра сведений выполняет чтение из БД
// Результат - Структура
Функция ПолучитьКлючНабораЗаписейИзКлючаЗаписиЛкс(КлючЗаписи, ПолноеИмяМДЭлемента = "") Экспорт
Если Не ЗначениеЗаполнено(ПолноеИмяМДЭлемента) Тогда
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(КлючЗаписи));
ПолноеИмяМДЭлемента = ОбъектМД.ПолноеИмя();
Иначе
ОбъектМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмяМДЭлемента);
КонецЕсли;
СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолноеИмяМДЭлемента,,, Ложь);
ЗаполнитьЗначенияСвойств(СтруктураКлюча, КлючЗаписи);
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяМДЭлемента);
Если Истина
И ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору
Тогда
ДанныеСтроки = ПолучитьСтрокуТаблицыБДПоКлючуЛкс(ПолноеИмяМДЭлемента, СтруктураКлюча);
СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолноеИмяМДЭлемента);
ЗаполнитьЗначенияСвойств(СтруктураКлюча, ДанныеСтроки);
КонецЕсли;
Возврат СтруктураКлюча;
КонецФункции
Функция ПолучитьXMLКлючОбъектаБДЛкс(Знач ОбъектДанных, Знач ИспользоватьСсылкуДляСсылочных = Ложь) Экспорт
Если ОбъектДанных = Неопределено Тогда
Результат = "Неопределено";
Возврат Результат;
КонецЕсли;
ПредставлениеОбъекта = "";
Если ТипЗнч(ОбъектДанных) = Тип("УдалениеОбъекта") Тогда
Класс = "Удаление";
Иначе
Попытка
ЭтоНовый = ОбъектДанных.ЭтоНовый();
Класс = "Ссылочный";
ПредставлениеОбъекта = "" + ОбъектДанных + ",";
Исключение
Попытка
УникальныйИдентификатор = ОбъектДанных.УникальныйИдентификатор();
Класс = "Ссылочный";
Исключение
Попытка
Пустышка = ОбъектДанных.Модифицированность();
Класс = "НаборЗаписей";
Исключение
Попытка
Пустышка = ОбъектДанных.Значение;
Класс = "Константы";
Исключение
Класс = "Примитив";
КонецПопытки;
КонецПопытки;
КонецПопытки;
КонецПопытки;
Если Истина
И Класс = "Ссылочный"
И ИспользоватьСсылкуДляСсылочных
Тогда
Результат = ОбъектДанных;
Возврат Результат;
КонецЕсли;
КонецЕсли;
XMLКлюч = "" + XMLТипЗнч(ОбъектДанных).ИмяТипа + "(";
Если Класс = "Ссылочный" Тогда
Если ЭтоНовый = Истина Тогда
УникальныйИдентификатор = "!" + ОбъектДанных.ПолучитьСсылкуНового().УникальныйИдентификатор();
КонецЕсли;
Если УникальныйИдентификатор = Неопределено Тогда
УникальныйИдентификатор = ОбъектДанных.Ссылка.УникальныйИдентификатор();
КонецЕсли;
XMLКлюч = XMLКлюч + ПредставлениеОбъекта + УникальныйИдентификатор;
ИначеЕсли Класс = "Удаление" Тогда
XMLКлюч = XMLКлюч + ПолучитьXMLКлючОбъектаБДЛкс(ОбъектДанных.Ссылка);
ИначеЕсли Класс = "НаборЗаписей" Тогда
ПредставлениеОтбора = "";
Разделитель = ", ";
Для Каждого ЭлементОтбора Из ОбъектДанных.Отбор Цикл
Если ЭлементОтбора.Использование Тогда
ПредставлениеОтбора = ПредставлениеОтбора + Разделитель + ЭлементОтбора.Имя
+ ":" + ПолучитьXMLКлючОбъектаБДЛкс(ЭлементОтбора.Значение);
КонецЕсли;
КонецЦикла;
XMLКлюч = XMLКлюч + Сред(ПредставлениеОтбора, СтрДлина(Разделитель) + 1);
ИначеЕсли Класс = "Константы" Тогда
//
Иначе
// Примитивный тип
XMLКлюч = XMLКлюч + ОбъектДанных;
КонецЕсли;
XMLКлюч = XMLКлюч + ")";
Результат = XMLКлюч;
Возврат Результат;
КонецФункции
// Параметры:
// Объект - ОбъектБД, ОбъектМД
Функция ПолучитьТабличныеЧастиОбъектаЛкс(Объект) Экспорт
Если ТипЗнч(Объект) = Тип("ОбъектМетаданных") Тогда
мдОбъекта = Объект;
ОбъектБД = Неопределено;
Иначе
мдОбъекта = Объект.Метаданные();
ОбъектБД = Объект;
КонецЕсли;
СтруктураТЧ = Новый Структура();
ЭтоСправочник = Метаданные.Справочники.Индекс(мдОбъекта) >= 0;
Если Не ЛиСсылочныйОбъектМетаданных(мдОбъекта, Ложь) Тогда
Возврат СтруктураТЧ;
КонецЕсли;
Для Каждого МетаТЧ из мдОбъекта.ТабличныеЧасти Цикл
// Для реквизитов справочников, принадлежащих только группе или только элементу нужно игнорировать те объекты, для которых эти реквизиты не используются
Если Истина
И ЭтоСправочник
И ОбъектБД <> Неопределено
Тогда
Если Ложь
Или (Истина
И ОбъектБД.ЭтоГруппа
И МетаТЧ.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента)
Или (Истина
И Не ОбъектБД.ЭтоГруппа
И МетаТЧ.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы)
Тогда
Продолжить
КонецЕсли;
КонецЕсли;
СтруктураТЧ.Вставить(МетаТЧ.Имя, МетаТЧ.Представление());
КонецЦикла;
Если Метаданные.ПланыСчетов.Индекс(мдОбъекта) >= 0 Тогда
Если мдОбъекта.ВидыСубконто <> Неопределено Тогда
СтруктураТЧ.Вставить("ВидыСубконто", "Виды субконто");
КонецЕсли;
КонецЕсли;
Если Метаданные.ПланыВидовРасчета.Индекс(мдОбъекта) >= 0 Тогда
Если мдОбъекта.ЗависимостьОтВидовРасчета <> Метаданные.СвойстваОбъектов.ИспользованиеБазыПланаВидовРасчета.НеИспользовать Тогда
СтруктураТЧ.Вставить("БазовыеВидыРасчета", "Базовые виды расчета");
КонецЕсли;
СтруктураТЧ.Вставить("ВедущиеВидыРасчета", "Ведущие виды расчета");
Если мдОбъекта.ИспользованиеПериодаДействия Тогда
СтруктураТЧ.Вставить("ВытесняющиеВидыРасчета", "Вытесняющие виды расчета");
КонецЕсли;
КонецЕсли;
Возврат СтруктураТЧ;
КонецФункции
Функция ЛиСтрокаСодержитВсеПодстрокиЛкс(Знач Строка, Знач Подстроки) Экспорт
Если ТипЗнч(Подстроки) = Тип("Строка") Тогда
Подстроки = ПолучитьМассивИзСтрокиСРазделителемЛкс(НРег(Подстроки), " ", Истина);
КонецЕсли;
НСтрока = НРег(Строка);
Для Каждого Фрагмент Из Подстроки Цикл
Если Найти(НСтрока, Фрагмент) = 0 Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Функция ПолучитьСтрокуТаблицыБДПоКлючуЛкс(ПолноеИмяТаблицы, СтруктураКлюча) Экспорт
Запрос = Новый Запрос;
ТекстЗапроса = "ВЫБРАТЬ Т.* ИЗ " + ПолноеИмяТаблицы + " КАК Т ГДЕ ИСТИНА ";
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
ТекстЗапроса = ТекстЗапроса + " И Т." + КлючИЗначение.Ключ + " = &" + КлючИЗначение.Ключ;
КонецЦикла;
СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураКлюча, Запрос.Параметры);
Запрос.Текст = ТекстЗапроса;
Таблица = Запрос.Выполнить().Выгрузить();
Если Таблица.Количество() > 1 Тогда
ВызватьИсключение "По переданному ключу (" + ПолучитьПредставлениеСтруктурыЛкс(СтруктураКлюча) + ") найдено несколько строк таблицы";
ИначеЕсли Таблица.Количество() > 0 Тогда
СтрокаРезультата = Таблица[0];
Иначе
СтрокаРезультата = Неопределено;
КонецЕсли;
Возврат СтрокаРезультата;
КонецФункции
// Присваивает ячейке по указателю значение. Если после этого ячейка получает другое значение, то ячейке присваивается ее старое значение.
Функция БезопасноПрисвоитьПроизвольнуюСсылкуЛкс(П1, П2) Экспорт
СтароеП1 = П1;
П1 = П2;
Если П1 <> П2 Тогда
П1 = СтароеП1;
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции // БезопасноПрисвоитьПроизвольнуюСсылку()
// ЛиНаходитьОбразующий - Булево - находить ближайший объект метаданных, если точный найти не удается
Функция НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, ЛиНаходитьОбразующий = Ложь) Экспорт
Результат = Неопределено;
Если Истина
И Не ПустаяСтрока(ПолноеИмяТаблицыБД)
И ПолноеИмяТаблицыБД <> "Константы"
Тогда
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяТаблицыБД);
ОбразующийМД = Метаданные.НайтиПоПолномуИмени(Фрагменты[0] + "." + Фрагменты[1]);
Если Ложь
Или ОбразующийМД = Неопределено
Или Фрагменты.Количество() = 2
Тогда
Результат = ОбразующийМД;
Иначе
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(Фрагменты[0]) Тогда
ДочерняяКоллекция = ОбразующийМД.ТабличныеЧасти;
ИначеЕсли Фрагменты[0] = "РегистрРасчета" Тогда
ДочерняяКоллекция = ОбразующийМД.Перерасчеты;
ИначеЕсли Фрагменты[0] = "ВнешнийИсточникДанных" Тогда
ДочерняяКоллекция = ОбразующийМД.Таблицы;
Если Фрагменты.Количество() = 4 Тогда
Результат = ДочерняяКоллекция.Найти(Фрагменты[3]);
КонецЕсли;
//ИначеЕсли Фрагменты[0] = "РегистрБухгалтерии" Тогда
ИначеЕсли Ложь
Или ЛиКорневойТипРегистраБДЛкс(Фрагменты[0])
Или Фрагменты[0] = "Константа"
Тогда
Результат = ОбразующийМД;
Иначе
ВызватьИсключение "Неизвестный корневой тип метаданных(" + Фрагменты[0] + ") с дочерней таблицей";
КонецЕсли;
Если Результат = Неопределено И Фрагменты.Количество() = 3 Тогда
ДочернийОбъектМД = ДочерняяКоллекция.Найти(Фрагменты[2]);
Если ДочернийОбъектМД <> Неопределено Тогда
Результат = ДочернийОбъектМД;
ИначеЕсли ЛиНаходитьОбразующий Тогда
// ВидыСубконто, Изменения, Точки
Результат = ОбразующийМД;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьМетаданныеЛкс()
Функция ОписаниеТипов1ВходитВОписаниеТипов2Лкс(ОписаниеТипов1, ОписаниеТипов2) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов1 = Новый ОписаниеТипов;
ОписаниеТипов2 = Новый ОписаниеТипов;
#КонецЕсли
Результат = Не (ОписаниеТипов2.Типы().Количество() > 0 И ОписаниеТипов1.Типы().Количество() = 0);
Если Результат Тогда
Для Каждого Тип Из ОписаниеТипов1.Типы() Цикл
Если Не ОписаниеТипов2.СодержитТип(Тип) Тогда
Результат = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьОписаниеТаблицыБДИис(ИмяТаблицыБД) Экспорт
Возврат ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс().Найти(НРег(ИмяТаблицыБД), "НПолноеИмя");
КонецФункции
Функция ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД) Экспорт
//ОписаниеТаблицы = ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс().Найти(НРег(ПолноеИмяТаблицыБД), "НПолноеИмя");
//Если ОписаниеТаблицы <> Неопределено Тогда
// Возврат ОписаниеТаблицы.Тип;
//КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяТаблицыБД);
ТипТаблицы = Фрагменты[0];
Если Фрагменты.Количество() > 2 Тогда
ПоследнийФрагмент = Фрагменты[Фрагменты.ВГраница()];
Если Ложь
Или ПоследнийФрагмент = "Изменения"
Или ПоследнийФрагмент = "ДвиженияССубконто"
Или ПоследнийФрагмент = "Границы"
Тогда
ТипТаблицы = ПоследнийФрагмент;
//// Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(МассивФрагментов[0]) Тогда
//// //ТипТаблицы = "ТабличнаяЧасть";
//// ТипТаблицы = МассивФрагментов[2];
//// КонецЕсли;
Иначе
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(Фрагменты[0]) Тогда
ОбъектМД = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Если ОбъектМД = Неопределено Тогда
ТипТаблицы = Фрагменты[2];
Иначе
ТипТаблицы = "ТабличнаяЧасть";
КонецЕсли;
//ИначеЕсли СтрокиРавныЛкс(Фрагменты[2], "ДвиженияССубконто") Тогда
// ТипТаблицы = Фрагменты[0];
ИначеЕсли Фрагменты[0] = "РегистрРасчета" Тогда
ТипТаблицы = "Перерасчет";
ИначеЕсли Фрагменты[0] = "ВнешнийИсточникДанных" Тогда
ТипТаблицы = "Внешняя";
Иначе
ТипТаблицы = "ВиртуальнаяТаблица";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ТипТаблицы;
КонецФункции
// ВариантИсточников - Число, *0
// 0 - Основные таблицы
// 1 - Таблицы изменений
// 2 - Внутреннее соединение основных таблиц с их таблицами изменений с отбором по узлу
Функция ПолучитьТекстЗапросаПоВыбраннымТаблицамЛкс(МассивИменОбъектовМД, ВариантИсточников = 0, ПервыеNКаждойТаблицы = 0, ПодключатьПоляКоличестваДвижений = Ложь) Экспорт
ЛитералЗаменыОтсутствующихПолей = "НЕОПРЕДЕЛЕНО"; // NULL нельзя использовать из-за ошибок платформы 8.2.14
// Сначала определим общие реквизиты
ПроверяемыеПоля = Новый Массив;
ТипыОбъектовМД = Новый Структура;
Для Каждого ИмяОбъектаМД Из МассивИменОбъектовМД Цикл
ТипОбъектаМД = ПолучитьТипТаблицыБДЛкс(ИмяОбъектаМД);
ТипыОбъектовМД.Вставить(ТипОбъектаМД);
КонецЦикла;
Если ТипыОбъектовМД.Количество() > 1 Тогда
ТипОбъектаМД = Неопределено;
КонецЕсли;
Если ЗначениеЗаполнено(ТипОбъектаМД) Тогда
ирКэш.Получить().ИнициализацияОписанияМетодовИСвойств();
СтрокаКорневогоТипа = ирКэш.Получить().ПолучитьСтрокуТипаМетаОбъектов(ТипОбъектаМД);
Если СтрокаКорневогоТипа <> Неопределено Тогда
СтрокаВида = ирКэш.Получить().ТаблицаИменЭлементовКоллекций.Найти(СтрокаКорневогоТипа.Множественное, "ИмяКоллекции");
Если СтрокаВида <> Неопределено Тогда
Если ирОбщий.СтрокиРавныЛкс(ТипОбъектаМД, "ТабличнаяЧасть") Тогда
ТипОбъектаМД = "Справочник.<Имя справочника>";
КонецЕсли;
ИмяОбщегоТипа = ТипОбъектаМД + "." + СтрокаВида.ИмяЭлементаКоллекции;
Если ВариантИсточников = 1 Тогда
ИмяОбщегоТипа = ИмяОбщегоТипа + ".Изменения";
КонецЕсли;
СтрокиИменПолей = ирКэш.Получить().ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста, ЯзыкПрограммы", ИмяОбщегоТипа, 1));
Для Каждого СтрокаСлова Из СтрокиИменПолей Цикл
Если Ложь
Или СтрокаСлова.ТипСлова = "Таблица"
Или ПроверяемыеПоля.Найти(СтрокаСлова.Слово) <> Неопределено // Для таблиц бухгалтерии могут быть дубли из-за вариантов с корреспонденцией и без
Тогда
Продолжить;
КонецЕсли;
ПроверяемыеПоля.Добавить(СтрокаСлова.Слово);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Находим максимум общих реквизитов
ОбщиеМетаПоля = Новый Массив;
ЭтоПервыйПроход = Истина;
Для Каждого ИмяОбъектаМД Из МассивИменОбъектовМД Цикл
ИмяТаблицы = ИмяОбъектаМД;
ОбъектМетаданных = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ИмяОбъектаМД);
Если ВариантИсточников > 0 Тогда
ЕстьТаблицаИзменений = ЕстьТаблицаИзмененийОбъектаМетаданных(ОбъектМетаданных);
Если ЕстьТаблицаИзменений Тогда
Если ВариантИсточников = 1 Тогда
ИмяТаблицы = ИмяОбъектаМД + ".Изменения";
КонецЕсли;
КонецЕсли;
КонецЕсли;
КоллекцияПолей = Новый Массив();
ПоляТаблицыБД = ирКэш.ПолучитьПоляТаблицыБДЛкс(ИмяТаблицы);
#Если Сервер И Не Сервер Тогда
ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки;
#КонецЕсли
Для Каждого ПолеТаблицы Из ПоляТаблицыБД Цикл
Если ПолеТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
Продолжить;
КонецЕсли;
ИмяПоля = ПолеТаблицы.Имя;
Если Ложь
Или ПроверяемыеПоля.Найти(ИмяПоля) <> Неопределено
Тогда
Продолжить;
КонецЕсли;
КоллекцияПолей.Добавить(ИмяПоля);
КонецЦикла;
Если ЭтоПервыйПроход Тогда
Для Каждого ИмяПоля Из КоллекцияПолей Цикл
ОбщиеМетаПоля.Добавить(ИмяПоля);
КонецЦикла;
Иначе
НачальноеКоличество = ОбщиеМетаПоля.Количество();
Для СчетчикОбщиеМетаПоля = 1 По НачальноеКоличество Цикл
ИмяПоля = ОбщиеМетаПоля[НачальноеКоличество - СчетчикОбщиеМетаПоля];
Если КоллекцияПолей.Найти(ИмяПоля) = Неопределено Тогда
ОбщиеМетаПоля.Удалить(НачальноеКоличество - СчетчикОбщиеМетаПоля);
КонецЕсли;
КонецЦикла;
Если ОбщиеМетаПоля.Количество() = 0 Тогда
Прервать;
КонецЕсли;
КонецЕсли;
ЭтоПервыйПроход = Ложь;
КонецЦикла;
ТекстОбщихМетаПолей = "";
Для Каждого ИмяПоля Из ОбщиеМетаПоля Цикл
Если Истина
И ЛиКорневойТипСсылкиЛкс(МассивИменОбъектовМД[0])
И ВариантИсточников > 0
Тогда
ИмяПоля = "Ссылка." + ИмяПоля;
КонецЕсли;
ТекстОбщихМетаПолей = ТекстОбщихМетаПолей + ", Т." + ИмяПоля;
КонецЦикла;
#Если Клиент Тогда
Индикатор = ПолучитьИндикаторПроцессаЛкс(МассивИменОбъектовМД.Количество(), "Генерация текста запроса");
#КонецЕсли
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("");
ЗаписьXMLПустая = Истина;
Для Каждого ИмяОбъектаМД Из МассивИменОбъектовМД Цикл
#Если Клиент Тогда
ОбработатьИндикаторЛкс(Индикатор);
#КонецЕсли
ИмяТаблицы = ИмяОбъектаМД;
ОбъектМетаданных = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ИмяТаблицы);
КорневойТипТаблицы = ирОбщий.ПолучитьПервыйФрагментЛкс(ИмяТаблицы);
ТекстУсловияСоединения = "";
Если ВариантИсточников > 0 Тогда
ЕстьТаблицаИзменений = ЕстьТаблицаИзмененийОбъектаМетаданных(ОбъектМетаданных);
Если ЕстьТаблицаИзменений Тогда
Если ВариантИсточников = 1 Тогда
ИмяТаблицы = ИмяОбъектаМД + ".Изменения";
Иначе
ТекстУсловияСоединения = "_Изменения_.Узел = &Узел";
СтруктураКлючаИзменений = ирОбщий.ПолучитьСтруктуруКлючаТаблицыБДЛкс(ИмяТаблицы + ".Изменения");
Для Каждого КлючИЗначение Из СтруктураКлючаИзменений Цикл
Если ирОбщий.СтрокиРавныЛкс(КлючИЗначение.Ключ, "Узел") Тогда
Продолжить;
КонецЕсли;
Если ТекстУсловияСоединения <> "" Тогда
ТекстУсловияСоединения = ТекстУсловияСоединения + Символы.ПС + " И";
КонецЕсли;
ТекстУсловияСоединения = ТекстУсловияСоединения + " _Изменения_." + КлючИЗначение.Ключ + " = Т." + КлючИЗначение.Ключ;
КонецЦикла;
ТекстУсловияСоединения = Символы.ПС + " ВНУТРЕННЕЕ СОЕДИНЕНИЕ " + ИмяТаблицы + ".Изменения КАК _Изменения_
| ПО " + ТекстУсловияСоединения;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ПодключатьПоляКоличестваДвижений Тогда
Если ирОбщий.ЛиКорневойТипДокументаЛкс(КорневойТипТаблицы) Тогда
ТекстОбщееКоличествоДвижений = "";
Для Каждого МетаРегистр Из ОбъектМетаданных.Движения Цикл
ПолноеИмяРегистра = МетаРегистр.ПолноеИмя();
КраткоеИмяРегистра = МетаРегистр.Имя;
ТекстУсловияСоединения = ТекстУсловияСоединения + Символы.ПС + " { ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ _Регистр_.Регистратор, КОЛИЧЕСТВО(*) КАК КоличествоСтрок
| ИЗ " + ПолноеИмяРегистра + " КАК _Регистр_ СГРУППИРОВАТЬ ПО _Регистр_.Регистратор) КАК " + КраткоеИмяРегистра + "
| ПО " + КраткоеИмяРегистра + ".Регистратор = Т.Ссылка}";
ВыражениеКоличества = "ЕСТЬNULL(" + КраткоеИмяРегистра + ".КоличествоСтрок, 0)";
Если ТекстОбщееКоличествоДвижений <> "" Тогда
ТекстОбщееКоличествоДвижений = ТекстОбщееКоличествоДвижений + " + ";
КонецЕсли;
ТекстОбщееКоличествоДвижений = ТекстОбщееКоличествоДвижений + ВыражениеКоличества;
ТекстОбщееКоличествоДвижений = ВыражениеКоличества + " КАК КоличествоСтрок" + КраткоеИмяРегистра + ", " + ТекстОбщееКоличествоДвижений;
КонецЦикла;
Если ЗначениеЗаполнено(ТекстОбщееКоличествоДвижений) Тогда
ТекстУсловияСоединения = ТекстУсловияСоединения + "
|{ГДЕ " + ТекстОбщееКоличествоДвижений + " КАК КоличествоСтрокВсеРегистры}";
КонецЕсли;
КонецЕсли;
КонецЕсли;
//Если ВариантИсточников <> 1 Тогда
ТекстНеобязательныхПолей = "";
ПоляТаблицыБД = ирКэш.ПолучитьПоляТаблицыБДЛкс(ИмяТаблицы);
#Если Сервер И Не Сервер Тогда
ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки;
#КонецЕсли
Для Каждого ПроверяемоеПоле Из ПроверяемыеПоля Цикл
Если ПоляТаблицыБД.Найти(ПроверяемоеПоле, "Имя") = Неопределено Тогда
ТекстНеобязательныхПолей = ТекстНеобязательныхПолей + ", " + ЛитералЗаменыОтсутствующихПолей + " КАК " + ПроверяемоеПоле;
Иначе
ТекстНеобязательныхПолей = ТекстНеобязательныхПолей + ", Т." + ПроверяемоеПоле;
КонецЕсли;
КонецЦикла;
//КонецЕсли;
Если Не ЗаписьXMLПустая Тогда
ЗаписьXML.ЗаписатьБезОбработки("
|ОБЪЕДИНИТЬ ВСЕ
|");
КонецЕсли;
ЗаписьXMLПустая = Ложь;
ЗаписьXML.ЗаписатьБезОбработки("ВЫБРАТЬ ");
Если ЗначениеЗаполнено(ПервыеNКаждойТаблицы) Тогда
ЗаписьXML.ЗаписатьБезОбработки("ПЕРВЫЕ " + XMLСтрока(ПервыеNКаждойТаблицы) + " ");
КонецЕсли;
Если ЗначениеЗаполнено(ТекстНеобязательныхПолей) Тогда
ЗаписьXML.ЗаписатьБезОбработки(Сред(ТекстНеобязательныхПолей, 2) + ", ");
КонецЕсли;
Если ЗначениеЗаполнено(ТекстОбщихМетаПолей) Тогда
ЗаписьXML.ЗаписатьБезОбработки(Сред(ТекстОбщихМетаПолей, 2) + ", ");
КонецЕсли;
ЗаписьXML.ЗаписатьБезОбработки("""" + ИмяТаблицы + """ КАК _ПолноеИмяТаблицы ИЗ " + ИмяТаблицы + " КАК Т" + ТекстУсловияСоединения);
КонецЦикла;
//Если ЗначениеЗаполнено(ПервыеNОбщие) Тогда
// ТекстЗапроса = "ВЫБРАТЬ ПЕРВЫЕ " + XMLСтрока(ПервыеNОбщие) + " * ИЗ (" + ТекстЗапроса + ") КАК Т";
//КонецЕсли;
ТекстЗапроса = ЗаписьXML.Закрыть();
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Возврат ТекстЗапроса;
КонецФункции
Функция ЕстьТаблицаИзмененийОбъектаМетаданных(ПолноеИмяИлиОбъектМетаданных) Экспорт
ЕстьТаблицаИзменений = Ложь;
Если ТипЗнч(ПолноеИмяИлиОбъектМетаданных) = Тип("Строка") Тогда
ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(ПолноеИмяИлиОбъектМетаданных);
Если ОбъектМетаданных = Неопределено Тогда
ВызватьИсключение "Объект метаданных не найден """ + ПолноеИмяИлиОбъектМетаданных + """";
КонецЕсли;
Иначе
ОбъектМетаданных = ПолноеИмяИлиОбъектМетаданных;
КонецЕсли;
//// Способ 1
//Для Каждого МетаПланОбмена Из Метаданные.ПланыОбмена Цикл
// Если МетаПланОбмена.Состав.Содержит(ОбъектМетаданных) Тогда // Долго на больших конфигурациях
// ЕстьТаблицаИзменений = Истина;
// Прервать;
// КонецЕсли;
//КонецЦикла;
//// Способ 2
//Запрос = Новый Запрос("ВЫБРАТЬ 1 ИЗ " + ПолучитьИмяТаблицыИзМетаданныхЛкс(ОбъектМетаданных, Истина) + " КАК Т");
//Попытка
// Запрос.НайтиПараметры(); // Долго, но стабильно. Длительность не зависит от количества планов обмена
// ЕстьТаблицаИзменений = Истина;
//Исключение
// //Описание = ОписаниеОшибки();
// Пустышка = 1;
//КонецПопытки;
//// Способ 3
//Массив = Новый Массив;
//Массив.Добавить(ОбъектМетаданных);
//СтруктураХранения = ПолучитьСтруктуруХраненияБазыДанных(Массив); // очень долго
//ЕстьТаблицаИзменений = СтруктураХранения.Найти("РегистрацияИзменений", "Назначение") <> Неопределено;
// Способ 4 Быстрый при небольшом количестве планов обмена, а при большом?
ОбъектыМетаданныхСРегистрациейИзменений = ирКэш.ОбъектыМетаданныхСРегистрациейИзменений();
ЕстьТаблицаИзменений = ОбъектыМетаданныхСРегистрациейИзменений[ОбъектМетаданных.ПолноеИмя()] <> Неопределено;
Возврат ЕстьТаблицаИзменений;
КонецФункции
Функция СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект) Экспорт
Перем ОбменДанными, Получатели;
Структура = Новый Структура;
Попытка
ОбменДанными = Объект.ОбменДанными;
Исключение
// Элемент плана обмена в 8.3.4-
ОбменДанными = Неопределено;
КонецПопытки;
Если ОбменДанными <> Неопределено Тогда
Попытка
Получатели = ОбменДанными.Получатели;
Исключение
// Элемент плана обмена в 8.3.5+
Получатели = Неопределено;
КонецПопытки;
КонецЕсли;
Если ОбменДанными <> Неопределено Тогда
СтруктураОбменаДанными = Новый Структура;
СтруктураОбменаДанными.Вставить("Загрузка", ОбменДанными.Загрузка);
Если Получатели <> Неопределено Тогда
Узлы = Новый Массив;
Для Каждого Получатель Из ОбменДанными.Получатели Цикл
Узлы.Добавить(Получатель);
КонецЦикла;
Получатели = Новый Структура;
Получатели.Вставить("Автозаполнение", ОбменДанными.Получатели.Автозаполнение);
Получатели.Вставить("Узлы", Узлы);
СтруктураОбменаДанными.Вставить("Отправитель", ОбменДанными.Отправитель);
СтруктураОбменаДанными.Вставить("Получатели", Получатели);
КонецЕсли;
Структура.Вставить("ОбменДанными", СтруктураОбменаДанными);
КонецЕсли;
Если ТипЗнч(Объект) <> Тип("УдалениеОбъекта") Тогда
ДополнительныеСвойстваXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект.ДополнительныеСвойства);
Структура.Вставить("ДополнительныеСвойстваXML", ДополнительныеСвойстваXML);
КонецЕсли;
Возврат Структура;
КонецФункции // СериализоватьПараметрыОбменаДанными()
Процедура ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, СтруктураДополнительныхСвойств) Экспорт
Перем ОбменДанными, Получатели;
Если СтруктураДополнительныхСвойств.Свойство("ОбменДанными") Тогда
ОбменДанными = Объект.ОбменДанными;
СтруктураОбменаДанными = СтруктураДополнительныхСвойств.ОбменДанными;
ЗаполнитьЗначенияСвойств(ОбменДанными, СтруктураОбменаДанными);
Если СтруктураОбменаДанными.Свойство("Получатели") Тогда
ЗаполнитьЗначенияСвойств(ОбменДанными.Получатели, СтруктураОбменаДанными.Получатели);
ОбменДанными.Получатели.Очистить();
Для Каждого Получатель Из СтруктураОбменаДанными.Получатели.Узлы Цикл
ОбменДанными.Получатели.Добавить(Получатель);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(Объект) <> Тип("УдалениеОбъекта") Тогда
ДополнительныеСвойства = ВосстановитьОбъектИзСтрокиXMLЛкс(СтруктураДополнительныхСвойств.ДополнительныеСвойстваXML);
СкопироватьУниверсальнуюКоллекциюЛкс(ДополнительныеСвойства, Объект.ДополнительныеСвойства);
КонецЕсли;
КонецПроцедуры // ВосстановитьПараметрыОбменаДаннымиЛкс()
// Записывает объект с параметризованным контекстом (клиент/сервер).
// Обеспечивает запись объекта с попытками. Позволяет обойти неинтенсивные дедлоки и превышения ожиданий блокировки.
// Также обеспечивает обход оптимистичных объектных блокировок в случае, если в БД пишутся точно те же данные объекта, что и актуальные.
// Эффективно для многопоточной записи объектов.
Процедура ЗаписатьОбъектЛкс(Объект, НаСервере = Ложь, РежимЗаписи = Неопределено, РежимПроведения = Неопределено, ОтключатьКонтрольЗаписи = Неопределено,
БезАвторегистрацииИзменений = Неопределено) Экспорт
Если НаСервере Тогда
ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект);
ОбъектXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
ирСервер.ЗаписатьОбъектXMLЛкс(ОбъектXML, ДополнительныеСвойства, РежимЗаписи, РежимПроведения, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений);
Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(ОбъектXML);
ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, ДополнительныеСвойства);
//#Если Клиент Тогда
// Попытка
// СсылкаОбъекта = Объект.Ссылка;
// Исключение
// КонецПопытки;
// Если СсылкаОбъекта <> Неопределено Тогда
// // При групповых обработках видимо будут большие потери
// ОповеститьОбИзменении(СсылкаОбъекта);
// КонецЕсли;
//#КонецЕсли
Иначе
НачалоПопыток = ТекущаяДата();
// Для обхода дедлоков и оптимистичной объектной блокировки при высокой параллельности
Если РежимЗаписи = Неопределено Тогда
ПопытокЗаписиОбъекта = 5;
Иначе
ПопытокЗаписиОбъекта = 3;
КонецЕсли;
ПредельнаяДлительность = 20;
Для СчетчикПопыток = 1 По ПопытокЗаписиОбъекта Цикл
УстановитьПараметрыЗаписиОбъектаЛкс(Объект, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений);
Попытка
Если РежимЗаписи = Неопределено Тогда
Объект.Записать();
ИначеЕсли РежимЗаписи = "ПометкаУдаления" Тогда
Объект.Записать();
Объект.ОбменДанными.Загрузка = Ложь;
Объект.УстановитьПометкуУдаления(Не Объект.ПометкаУдаления);
ИначеЕсли Истина
И ТипЗнч(РежимЗаписи) = Тип("РежимЗаписиДокумента")
И РежимЗаписи <> РежимЗаписиДокумента.Запись
Тогда
Объект.ОбменДанными.Загрузка = Ложь;
Объект.Записать(РежимЗаписи, РежимПроведения);
Иначе
Объект.Записать(РежимЗаписи);
КонецЕсли;
Прервать;
Исключение
НужноВызватьИсключение = Истина;
ОписаниеОшибки = ОписаниеОшибки();
НовоеОписаниеОшибки = "";
Если ТранзакцияАктивна() Тогда
//НовоеОписаниеОшибки = "Транзакция активна" + Символы.ПС + ОписаниеОшибки;
Иначе
НОписаниеОшибки = НРег(ОписаниеОшибки);
Если Истина
И РежимЗаписи = Неопределено
И (Ложь
Или Найти(НОписаниеОшибки, "несоответствия версии или отсутствия записи базы данных") > 0
Или Найти(НОписаниеОшибки, "version mismatch or lack of database record") > 0)
Тогда
НужноВызватьИсключение = Ложь;
ТекущийXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект, Ложь);
//Объект.Прочитать(); // Чтение с блокировкой нам не нужно
ОбъектДляСравнения = ПеречитатьОбъектЗапросомЛкс(Объект);
Если Объект <> Неопределено Тогда
НовыйXML = СохранитьОбъектВВидеСтрокиXMLЛкс(ОбъектДляСравнения, Ложь);
Если ТекущийXML = НовыйXML Тогда
Прервать;
Иначе
Попытка
лРежимЗагрузка = Объект.ОбменДанными.Загрузка;
Исключение
лРежимЗагрузка = Неопределено;
КонецПопытки;
ПолноеИмяМД = Объект.Метаданные().ПолноеИмя();
Если лРежимЗагрузка = Истина И СчетчикПопыток = 2 Тогда
Сообщить("Возможно в обработчиках ПередЗаписью объекта " + ПолноеИмяМД + " в режиме Загрузка выполняется его нестабильная модификация");
КонецЕсли;
НужноВызватьИсключение = СчетчикПопыток = ПопытокЗаписиОбъекта;
Если НужноВызватьИсключение Тогда
НовоеОписаниеОшибки = "Обход оптимистичной блокировки объекта " + ПолноеИмяМД + " отменен из-за его нестабильной модификации в обработчиках ПередЗаписью (Загрузка="
+ XMLСтрока(лРежимЗагрузка) + ")" + Символы.ПС + ОписаниеОшибки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или Найти(ОписаниеОшибки, "взаимоблокировк") > 0
Или Найти(ОписаниеОшибки, "deadlock") > 0
Тогда
НужноВызватьИсключение = Ложь;
КонецЕсли;
КонецЕсли;
Если Не НужноВызватьИсключение Тогда
Если СчетчикПопыток = ПопытокЗаписиОбъекта Тогда
//НовоеОписаниеОшибки = "Кончились попытки записи" + Символы.ПС + ОписаниеОшибки;
НужноВызватьИсключение = Истина;
ИначеЕсли ТекущаяДата() - НачалоПопыток >= ПредельнаяДлительность Тогда
//НовоеОписаниеОшибки = "Кончилось время записи" + Символы.ПС + ОписаниеОшибки;
НужноВызватьИсключение = Истина;
ИначеЕсли СчетчикПопыток = ПопытокЗаписиОбъекта Тогда
//НовоеОписаниеОшибки = "Кончились попытки записи" + Символы.ПС + ОписаниеОшибки;
НужноВызватьИсключение = Истина;
КонецЕсли;
КонецЕсли;
#Если Клиент Тогда
Если ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(НОписаниеОшибки, Ложь) Тогда
ВызватьИсключение;
КонецЕсли;
#КонецЕсли
Если НужноВызватьИсключение Тогда
СостояниеОбъекта = ПолучитьПредставлениеДопСвойствОбъектаЛкс(Объект);
Если ЗначениеЗаполнено(СостояниеОбъекта) Тогда
Если ЗначениеЗаполнено(НовоеОписаниеОшибки) Тогда
НовоеОписаниеОшибки = НовоеОписаниеОшибки + СостояниеОбъекта;
Иначе
НовоеОписаниеОшибки = ОписаниеОшибки + СостояниеОбъекта;
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(НовоеОписаниеОшибки) Тогда
ВызватьИсключение НовоеОписаниеОшибки;
Иначе
ВызватьИсключение;
КонецЕсли;
КонецЕсли;
КонецПопытки;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьПредставлениеДопСвойствОбъектаЛкс(Объект)
Попытка
ДополнительныеСвойства = Объект.ДополнительныеСвойства;
Исключение
ДополнительныеСвойства = Новый Структура;
КонецПопытки;
СостояниеОбъекта = "";
Для Каждого КлючИЗначение Из ДополнительныеСвойства Цикл
СостояниеОбъекта = СостояниеОбъекта + Символы.ПС + КлючИЗначение.Ключ + ": " + КлючИЗначение.Значение;
КонецЦикла;
Возврат СостояниеОбъекта;
КонецФункции
// Позволяет перечитать объект грязным чтением, т.е. без учета блокировок. Не перечитывает свойство ВерсияДанных!
// На выходе объект имеет модифицированноть. Для удаленного объекта возвращает Неопределено.
Функция ПеречитатьОбъектЗапросомЛкс(Знач Объект) Экспорт
ОбъектМД = Объект.Метаданные();
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ * ИЗ " + ОбъектМД.ПолноеИмя() + " КАК Т ГДЕ Т.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка);
ТаблицаОбъекта = Запрос.Выполнить().Выгрузить();
Если ТаблицаОбъекта.Количество() > 0 Тогда
СтрокаДанных = ТаблицаОбъекта[0];
Для Каждого КолонкаТаблицы Из ТаблицаОбъекта.Колонки Цикл
ЗначениеРеквизита = СтрокаДанных[КолонкаТаблицы.Имя];
Если ЗначениеРеквизита = Null Тогда
// Реквизит (но не табличная часть) недоступен по признаку ЭтоГруппа. Если к нему обратиться у объекта, то будет ошибка "Ошибка установки значения свойства '...': Реквизит недоступен для группы"
Продолжить;
КонецЕсли;
Пустышка = Объект[КолонкаТаблицы.Имя]; // Проверяем корректность вычисления выражения перед его использованием в попытке
Если КолонкаТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
Попытка
Объект[КолонкаТаблицы.Имя].Загрузить(ЗначениеРеквизита);
Исключение
// Табличная часть недоступна по признаку ЭтоГруппа. Выдается ошибка "Ошибка при вызове метода контекста (Загрузить): Объект недоступен для изменения"
КонецПопытки;
Иначе
Попытка
Объект[КолонкаТаблицы.Имя] = ЗначениеРеквизита;
Исключение
// Реквизит предназначен только для чтения
КонецПопытки;
КонецЕсли;
КонецЦикла;
Иначе
Объект = Неопределено;
КонецЕсли;
Возврат Объект;
КонецФункции
// Антибаг платформы https://partners.v8.1c.ru/forum/topic/1168440
Процедура НаборЗаписейПослеЗагрузкиИзТаблицыЗначенийЛкс(НаборЗаписей) Экспорт
#Если Сервер И Не Сервер Тогда
НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
#КонецЕсли
ОбъектМД = НаборЗаписей.Метаданные();
КорневойТип = ПолучитьПервыйФрагментЛкс(ОбъектМД.ПолноеИмя());
Если КорневойТип = "РегистрБухгалтерии" Тогда
Для Каждого Проводка Из НаборЗаписей Цикл
ОчиститьПоляРегистраБухгалтерииПоПризнакамУчетаЛкс(Проводка, ОбъектМД.Ресурсы, ОбъектМД);
ОчиститьПоляРегистраБухгалтерииПоПризнакамУчетаЛкс(Проводка, ОбъектМД.Измерения, ОбъектМД);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ОчиститьПоляРегистраБухгалтерииПоПризнакамУчетаЛкс(Проводка, КоллекцияПолей, ОбъектМД) Экспорт
Для Каждого Поле Из КоллекцияПолей Цикл
Если Истина
И Не Поле.Балансовый
И Поле.ПризнакУчета <> Неопределено
Тогда
ИмяПризнакаУчета = Поле.ПризнакУчета.Имя;
Если ОбъектМД.Корреспонденция Тогда
Если Не Проводка.СчетДт[ИмяПризнакаУчета] Тогда
ПрисвоитьЕслиНеРавноЛкс(Проводка[Поле.Имя + "Дт"], Неопределено);
КонецЕсли;
Если Не Проводка.СчетКт[ИмяПризнакаУчета] Тогда
ПрисвоитьЕслиНеРавноЛкс(Проводка[Поле.Имя + "Кт"], Неопределено);
КонецЕсли;
Иначе
Если Не Проводка.Счет[ИмяПризнакаУчета] Тогда
ПрисвоитьЕслиНеРавноЛкс(Проводка[Поле.Имя], Неопределено);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура УстановитьПараметрыЗаписиОбъектаЛкс(Знач Объект, ОтключатьКонтрольЗаписи = Неопределено, БезАвторегистрацииИзменений = Неопределено) Экспорт
Перем ОбменДанными, Получатели;
Попытка
ОбменДанными = Объект.ОбменДанными;
Исключение
// Элемент плана обмена в 8.3.4-
ОбменДанными = Неопределено;
КонецПопытки;
Если ОбменДанными <> Неопределено Тогда
Если ОтключатьКонтрольЗаписи <> Неопределено Тогда
ОбменДанными.Загрузка = ОтключатьКонтрольЗаписи;
КонецЕсли;
Если БезАвторегистрацииИзменений <> Неопределено Тогда
Попытка
Получатели = ОбменДанными.Получатели;
Исключение
// Элемент плана обмена в 8.3.5+
Получатели = Неопределено;
КонецПопытки;
Если Получатели <> Неопределено Тогда
Получатели.Автозаполнение = Не БезАвторегистрацииИзменений;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура УдалитьОбъектЛкс(Объект, НаСервере = Ложь, ОтключатьКонтрольЗаписи = Неопределено, БезАвторегистрацииИзменений = Неопределено) Экспорт
УстановитьПараметрыЗаписиОбъектаЛкс(Объект, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений);
Если НаСервере Тогда
ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект);
ХМЛ = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
ирСервер.УдалитьОбъектЛкс(ХМЛ, ДополнительныеСвойства);
#Если Клиент Тогда
ОповеститьОбИзменении(Объект.Ссылка);
#КонецЕсли
Иначе
Объект.Удалить();
КонецЕсли;
КонецПроцедуры
Процедура УстановитьПометкуУдаленияОбъектаЛкс(Объект, НаСервере = Ложь, ЗначениеПометки = Истина, БезАвторегистрацииИзменений = Неопределено) Экспорт
Если НаСервере Тогда
ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект);
ОбъектXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
ирСервер.УстановитьПометкуУдаленияОбъектаЛкс(ОбъектXML, ДополнительныеСвойства, ЗначениеПометки);
Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(ОбъектXML);
ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, ДополнительныеСвойства);
Иначе
УстановитьПараметрыЗаписиОбъектаЛкс(Объект, , БезАвторегистрацииИзменений);
//Если РежимЗаписи = Неопределено Тогда
// Объект.УстановитьПометкуУдаления(ЗначениеПометки);
//Иначе
Объект.УстановитьПометкуУдаления(ЗначениеПометки);
//КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Источник - http://infostart.ru/public/125988/
Функция ВыбратьПоГруппировкамЛкс(Выборка, Группировки, СИерархией = Ложь) Экспорт
МетаВыборка = Новый Соответствие;
врОбходРезультата = ОбходРезультатаЗапроса.ПоГруппировкам;
Если СИерархией Тогда
врОбходРезультата = ОбходРезультатаЗапроса.ПоГруппировкамСИерархией;
КонецЕсли;
МетаВыборка.Вставить("ОбходРезультата", врОбходРезультата);
МассивГруппировок = Новый Массив;
врСтрГруппировки = Группировки;
Пока Истина Цикл
Поз = Найти( врСтрГруппировки, "," );
Если Поз = 0 Тогда
МассивГруппировок.Добавить(СокрЛП(врСтрГруппировки));
Прервать;
КонецЕсли;
МассивГруппировок.Добавить( СокрЛП( Лев(врСтрГруппировки,Поз-1) ) );
врСтрГруппировки = Сред( врСтрГруппировки, Поз+1 );
КонецЦикла;
МетаВыборка.Вставить("Группировки", МассивГруппировок);
врВыборка = Выборка;
Для пц=0 По МассивГруппировок.Количество()-2 Цикл
врВыборкаУровня = врВыборка.Выбрать(врОбходРезультата, МассивГруппировок[пц]);
МетаВыборка.Вставить("_Выборка"+Строка(пц), врВыборкаУровня);
Если не врВыборкаУровня.Следующий() Тогда
Прервать;
КонецЕсли;
врВыборка = врВыборкаУровня;
КонецЦикла;
врВыборкаУровня = врВыборка.Выбрать(врОбходРезультата, МассивГруппировок[пц]);
МетаВыборка.Вставить("Выборка", врВыборкаУровня);
МетаВыборка.Вставить("_Выборка"+Строка(пц), врВыборкаУровня);
Возврат МетаВыборка;
КонецФункции // ВыбратьПоГруппировкамЛкс
// Источник - http://infostart.ru/public/125988/
Функция СледующийПоГруппировкамЛкс(МетаВыборка, Уровень = Неопределено) Экспорт
Если Уровень = Неопределено Тогда
Уровень = МетаВыборка["Группировки"].Количество()-1;
КонецЕсли;
Если Уровень < 0 Тогда
Возврат Ложь;
КонецЕсли;
врВыборка = МетаВыборка["_Выборка"+Строка(Уровень)];
Если врВыборка.Следующий() Тогда
Возврат Истина;
КонецЕсли;
Если СледующийПоГруппировкамЛкс(МетаВыборка, Уровень-1) Тогда
МассивГруппировок = МетаВыборка["Группировки"];
врВыборкаРодитель = МетаВыборка["_Выборка"+Строка(Уровень-1)];
врВыборка = врВыборкаРодитель.Выбрать(МетаВыборка["ОбходРезультата"],МассивГруппировок[Уровень]);
МетаВыборка["_Выборка"+Строка(Уровень)] = врВыборка;
Если Уровень = МассивГруппировок.Количество()-1 Тогда
МетаВыборка["Выборка"] = врВыборка;
КонецЕсли;
Возврат СледующийПоГруппировкамЛкс(МетаВыборка, Уровень);
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции // зфСледующийПоГруппировкам
// ИспользоватьОбщийКаталогНастроек - использовать значение ключа ConfLocation из файла conf.cfg
Функция ПолучитьКаталогНастроекПриложения1СЛкс(ИспользоватьОбщийКаталогНастроек = Истина, СоздатьЕслиОтсутствует = Ложь, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ПолучитьКаталогНастроекПриложения1СЛкс(ИспользоватьОбщийКаталогНастроек, СоздатьЕслиОтсутствует);
Иначе
КаталогКонфигурацииПриложения = КаталогПрограммы() + "conf";
Если ИспользоватьОбщийКаталогНастроек Тогда
ФайлУказатель = Новый Файл(КаталогКонфигурацииПриложения + "\conf.cfg");
Если ФайлУказатель.Существует() Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ФайлУказатель.ПолноеИмя);
Текст = ТекстовыйДокумент.ПолучитьТекст();
НовыйКаталогКонфигурацииПриложения = ПолучитьСтрокуМеждуМаркерамиЛкс(Текст, "ConfLocation=", Символы.ПС);
НовыйКаталог = Новый Файл(НовыйКаталогКонфигурацииПриложения);
Если НовыйКаталог.Существует() Тогда
КаталогКонфигурацииПриложения = НовыйКаталогКонфигурацииПриложения;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СоздатьЕслиОтсутствует Тогда
Файл = Новый Файл(КаталогКонфигурацииПриложения);
Если Не Файл.Существует() Тогда
СоздатьКаталог(КаталогКонфигурацииПриложения);
КонецЕсли;
КонецЕсли;
Результат = КаталогКонфигурацииПриложения;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьТекстКонфигурационногоФайлаВнешнихСоединенийЛкс(АдресОтладчика = "") Экспорт
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст("
|
//|
|
|"
);
Возврат ТекстовыйДокумент;
КонецФункции
Функция ПолучитьИмяФайлаАктивнойНастройкиТехноЖурналаЛкс(НаСервере = Ложь) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ПолучитьИмяФайлаАктивнойНастройкиТехноЖурналаЛкс();
Иначе
КаталогКонфигурацииПриложения = ПолучитьКаталогНастроекПриложения1СЛкс(Ложь);
Результат = КаталогКонфигурацииПриложения + "\logcfg.xml";
Файл = Новый Файл(Результат);
Если Файл.Существует() Тогда
Возврат Результат;
КонецЕсли;
КаталогКонфигурацииПриложения = ПолучитьКаталогНастроекПриложения1СЛкс(Истина);
Результат = КаталогКонфигурацииПриложения + "\logcfg.xml";
Файл = Новый Файл(Результат);
Если Файл.Существует() Тогда
Возврат Результат;
КонецЕсли;
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьКаталогТехножурналаЛкс(НаСервере = Ложь) Экспорт
ИмяФайлаНастроекЖурнала = ПолучитьИмяФайлаАктивнойНастройкиТехноЖурналаЛкс(НаСервере);
Если ЗначениеЗаполнено(ИмяФайлаНастроекЖурнала) Тогда
ТекстХМЛ = ПрочитатьТекстИзФайлаЛкс(ИмяФайлаНастроекЖурнала, , НаСервере);
ЧтениеХМЛ = Новый ЧтениеXML;
ЧтениеХМЛ.УстановитьСтроку(ТекстХМЛ);
ПостроительДом = Новый ПостроительDOM();
Попытка
ДокументДОМ = ПостроительДом.Прочитать(ЧтениеХМЛ);
Исключение
Сообщить("Ошибка чтения настройки техножурнала: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
Если ДокументДОМ <> Неопределено Тогда
Узлы = ДокументДом.ПолучитьЭлементыПоИмени("log");
Если Узлы.Количество() > 0 Тогда
Атрибут = Узлы.Элемент(0).Атрибуты.ПолучитьИменованныйЭлемент("location");
Если Атрибут <> Неопределено Тогда
Результат = Атрибут.ТекстовоеСодержимое;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиТехножурналВключенЛкс(НаСервере = Ложь, ВыводитьСообщения = Ложь) Экспорт
КаталогЖурнала = "";
КаталогЖурналаВзятИзНастроекЧтения = Ложь;
Если НаСервере Тогда
#Если Клиент Тогда
КаталогЖурнала = ВосстановитьЗначение("ирАнализТехножурнала.КаталогЖурналаСервера");
КаталогЖурналаВзятИзНастроекЧтения = Истина;
#КонецЕсли
КонецЕсли;
Если Не ЗначениеЗаполнено(КаталогЖурнала) Тогда
КаталогЖурнала = ПолучитьКаталогТехножурналаЛкс(НаСервере);
КаталогЖурналаВзятИзНастроекЧтения = Ложь;
КонецЕсли;
Если ЗначениеЗаполнено(КаталогЖурнала) Тогда
Если Не ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала, НаСервере, ВыводитьСообщения) Тогда
Возврат Истина;
Иначе
Если ВыводитьСообщения Тогда
Если КаталогЖурналаВзятИзНастроекЧтения Тогда
Сообщить("Каталог техножурнала """ + КаталогЖурнала + """ недоступен. Использован каталог, заданный в настройках чтения анализа техножурнала", СтатусСообщения.Внимание);
Иначе
Сообщить("Каталог техножурнала """ + КаталогЖурнала + """ недоступен. Использован каталог, заданный в текущей настройке техножурнала", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Если ВыводитьСообщения Тогда
Если НаСервере Тогда
Сообщить("Каталог техножурнала сервера не удалось прочитать из текущей настройки техножурнала и не задан в настройках чтения инструмента ""Анализ техножурнала""");
Иначе
Сообщить("Каталог техножурнала клиента не удалось прочитать из текущей настройки техножурнала");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала, НаСервере = Ложь, ВыводитьСообщения = Истина) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала);
Иначе
Результат = Ложь;
ФайлКаталог = Новый Файл(КаталогЖурнала);
Если Не ФайлКаталог.Существует() Тогда
Результат = Истина;
Иначе
БлокирующиеФайлы = НайтиФайлы(КаталогЖурнала, "*.*");
Для Каждого БлокирующийФайл Из БлокирующиеФайлы Цикл
Если Не БлокирующийФайл.ЭтоКаталог() Тогда
Если ВыводитьСообщения Тогда
ТекстСообщения = "В корне каталога """ + КаталогЖурнала + """ техножурнала ";
Если НаСервере Тогда
ТекстСообщения = ТекстСообщения + "сервера";
Иначе
ТекстСообщения = ТекстСообщения + "клиента";
КонецЕсли;
Сообщить(ТекстСообщения + " обнаружены блокирующие файлы. Для работы журнала их необходимо удалить.",
СтатусСообщения.Внимание);
КонецЕсли;
Результат = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиКлиентЗапущенНаКомпьютереСервераЛкс() Экспорт
Результат = НРег(ирСервер.ПолучитьИмяКомпьютераЛкс()) = НРег(ИмяКомпьютера());
Возврат Результат;
КонецФункции
Функция ЗаписатьТекстВФайлЛкс(ПолноеИмяФайла, Текст, Кодировка = Неопределено, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
ирСервер.ЗаписатьТекстВФайлЛкс(ПолноеИмяФайла, Текст, Кодировка);
Иначе
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(Текст);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
ТекстовыйДокумент.Записать(ИмяВременногоФайла, Кодировка);
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
мПлатформа.ПереместитьФайлКакАдминистратор(ИмяВременногоФайла, ПолноеИмяФайла);
КонецЕсли;
КонецФункции
Функция ПрочитатьТекстИзФайлаЛкс(ПолноеИмяФайла, Кодировка = Неопределено, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ПрочитатьТекстИзФайлаЛкс(ПолноеИмяФайла, Кодировка);
Иначе
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ПолноеИмяФайла, Кодировка);
Результат = ТекстовыйДокумент.ПолучитьТекст();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НайтиИменаФайловЛкс(Путь, Маска = Неопределено, ИскатьВПодкаталогах = Истина, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
Результат = ирСервер.НайтиИменаФайловЛкс(Путь, Маска, ИскатьВПодкаталогах);
Иначе
Файлы = НайтиФайлы(Путь, Маска, ИскатьВПодкаталогах);
Результат = Новый Массив;
Для Каждого Файл Из Файлы Цикл
Результат.Добавить(Файл.ПолноеИмя);
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ИзданиеПлатформы - Строка(0,П)
//
Функция ПолучитьКаталогПустойИнфобазыЛкс(Знач ИзданиеПлатформы = "") Экспорт
Если Не ЗначениеЗаполнено(ИзданиеПлатформы) Тогда
ИзданиеПлатформы = ирКэш.Получить().ИДВерсииПлатформы;
КонецЕсли;
ShellApplication = Новый COMobject("Shell.Application");
КаталогПустойИнфобазы = ShellApplication.NameSpace(28).Self.Path;
КаталогПустойИнфобазы = КаталогПустойИнфобазы + "\1C\1Cv" + ИзданиеПлатформы + "\EmptyDB";
Результат = КаталогПустойИнфобазы;
Возврат Результат;
КонецФункции
// Параметры:
// СоздаватьБазуВСлучаеОтсутствия - Булево
//
Функция ПолучитьСтрокуСоединенияПустойИнфобазыЛкс(ИзданиеПлатформы = "", Знач СоздаватьБазуВСлучаеОтсутствия = Истина) Экспорт
КаталогПустойИнфобазы = ПолучитьКаталогПустойИнфобазыЛкс(ИзданиеПлатформы);
Если СоздаватьБазуВСлучаеОтсутствия Тогда
ФайлПустойИнфобазы = Новый Файл(КаталогПустойИнфобазы + "\1CV8.1CD");
Если Не ФайлПустойИнфобазы.Существует() Тогда
СтрокаПараметров = "CREATEINFOBASE File=" + КаталогПустойИнфобазы + ";";
//СтрокаПараметров = СтрокаПараметров + " /AddInList ууууу";
ИмяФайлаЛога = ПолучитьИмяВременногоФайла();
СтрокаПараметров = СтрокаПараметров + " /out" + ИмяФайлаЛога;
СтрокаЗапуска = """" + КаталогПрограммы() + "1cv8.exe"" " + СтрокаПараметров;
ирКэш.Получить().ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(СтрокаЗапуска); //ВыполнитьСкрытуюКомандуОС
КонецЕсли;
КонецЕсли;
СтрокаСоединения = "File=""" + КаталогПустойИнфобазы + """;";
Результат = СтрокаСоединения;
Возврат Результат;
КонецФункции
Функция СоздатьФайловуюБазу1СЛкс(Знач КаталогИнфобазы = "", ИмяФайлаКонфигурации = "", УдалитьСуществующую = Ложь) Экспорт
ФайлПустойИнфобазы = Новый Файл(КаталогИнфобазы + "\1CV8.1CD");
Если ФайлПустойИнфобазы.Существует() И УдалитьСуществующую Тогда
УдалитьФайлы(КаталогИнфобазы);
КонецЕсли;
Если Не ФайлПустойИнфобазы.Существует() Тогда
СтрокаПараметров = "CREATEINFOBASE File=""" + КаталогИнфобазы + """;";
// Антибаг платформы http://partners.v8.1c.ru/forum/thread.jsp?id=1076785#1076785
СтрокаПараметров = СтрокаПараметров + "Q=Q";
Если ЗначениеЗаполнено(ИмяФайлаКонфигурации) Тогда
СтрокаПараметров = СтрокаПараметров + " /UseTemplate """ + ИмяФайлаКонфигурации + """";
КонецЕсли;
//СтрокаПараметров = СтрокаПараметров + " /AddInList ууууу";
ПолноеИмяИсполняемогоФайла = ПолноеИмяИсполняемогоФайлаКонфигуратораЛкс();
ЗапуститьПриложение("""" + ПолноеИмяИсполняемогоФайла + """ " + СтрокаПараметров,, Истина);;
КонецЕсли;
Возврат "";
КонецФункции
Функция ПолноеИмяИсполняемогоФайлаКонфигуратораЛкс() Экспорт
ПолноеИмяИсполняемогоФайла = "" + КаталогПрограммы() + "1cv8.exe";
Возврат ПолноеИмяИсполняемогоФайла;
КонецФункции
Функция ПолучитьСтрокуСКавычкамиДляКоманднойСтрокиЛкс(Строка) Экспорт
Результат = """" + СтрЗаменить(Строка, """", """""") + """";
Возврат Результат;
КонецФункции
// Параметры:
// СтрокаСоединенияБазы - Строка - пустая строка трактуется как строка соединения пустой инфобазы
Функция ВыполнитьКомандуКонфигуратораЛкс(Знач КомандаКонфигуратора, Знач СтрокаСоединенияБазы = "", выхТекстЛога = "", ПодавлятьДиалоги = Ложь, Состояние = "" ) Экспорт
#Если Клиент Тогда
Если ЗначениеЗаполнено(Состояние) Тогда
Состояние(Состояние);
КонецЕсли;
#КонецЕсли
Если Не ЗначениеЗаполнено(СтрокаСоединенияБазы) Тогда
КаталогПустойИнфобазы = ПолучитьКаталогПустойИнфобазыЛкс();
СоздатьФайловуюБазу1СЛкс(КаталогПустойИнфобазы);
СтрокаСоединенияБазы = "File=""" + КаталогПустойИнфобазы + """;";
КонецЕсли;
СтрокаСоединенияБазы = "/IBConnectionString" + ПолучитьСтрокуСКавычкамиДляКоманднойСтрокиЛкс(СтрокаСоединенияБазы);
КодВозврата = Неопределено;
ИмяФайлаЛога = ПолучитьИмяВременногоФайла("txt");
ПолноеИмяИсполняемогоФайла = ПолноеИмяИсполняемогоФайлаКонфигуратораЛкс();
ПараметрыПакетногоЗапуска = "DESIGNER /Out""" + ИмяФайлаЛога + """ " + СтрокаСоединенияБазы + " " + КомандаКонфигуратора;
Если ПодавлятьДиалоги Тогда
ПараметрыПакетногоЗапуска = ПараметрыПакетногоЗапуска + " /DisableStartupDialogs /DisableStartupMessages";
КонецЕсли;
ЗапуститьПриложение("""" + ПолноеИмяИсполняемогоФайла + """ " + ПараметрыПакетногоЗапуска,, Истина, КодВозврата);;
ФайлЛога = Новый Файл(ИмяФайлаЛога);
Если ФайлЛога.Существует() Тогда
ТекстовыйДокументЛога = Новый ТекстовыйДокумент;
ТекстовыйДокументЛога.Прочитать(ФайлЛога.ПолноеИмя);
выхТекстЛога = ТекстовыйДокументЛога.ПолучитьТекст();
КонецЕсли;
Возврат КодВозврата = 0;
КонецФункции
// р5яф67оыйи
Функция ПараметрыЗапускаСеансаДляПодключенияКТекущемуОтладчикуЛкс(Знач ИдентификаторПроцессаОС) Экспорт
ПараметрыЗапускаДляОтладки = "";
ТекущийПроцесс = ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2:Win32_Process.Handle='" + XMLСтрока(ИдентификаторПроцессаОС) + "'");
КоманднаяСтрокаПроцесса = ТекущийПроцесс.CommandLine;
ВычислительРегулярныхВыражений = Новый COMОбъект("VBScript.RegExp");
ВычислительРегулярныхВыражений.IgnoreCase = Истина;
ВычислительРегулярныхВыражений.Pattern = "(/DebuggerUrl\s*.+?)( /|$)";
Вхождения = ВычислительРегулярныхВыражений.Execute(КоманднаяСтрокаПроцесса);
Если Вхождения.Count > 0 Тогда
ПараметрыЗапускаДляОтладки = Вхождения.Item(0).SubMatches(0);
КонецЕсли;
ВычислительРегулярныхВыражений.Pattern = "(/Debug\s+.+?)( /|$)";
Вхождения = ВычислительРегулярныхВыражений.Execute(КоманднаяСтрокаПроцесса);
Если Вхождения.Count > 0 Тогда
СтрокаОтладчика = Вхождения.Item(0).SubMatches(0);;
Иначе
СтрокаОтладчика = "/Debug";
КонецЕсли;
ПараметрыЗапускаДляОтладки = ПараметрыЗапускаДляОтладки + " " + СтрокаОтладчика;
Возврат ПараметрыЗапускаДляОтладки;
КонецФункции
// Создает COM объект клиента 1C и подключает его к базе по указанной строке соединения.
// Параметры:
// СтрокаСоединения - Строка
// ИмяПользователя - Строка
// ПарольПользователя - Строка
// ТипCOMОбъекта - Строка, *"Application" - "Application" или "ComConnector"
// Видимость - Булево - для Application
// ОбработатьИсключениеПодключения - Булево, *Ложь - при Истина исключение обрабатывается внутри метода и возвращется его описание в качестве результата
// ИмяСервераПроцессов - Строка - имя сервера, на котором создавать COM объект
//
// Возвращаемое значение:
// COMОбъект - клиента 1C, Строка - описание исключения
//
Функция СоздатьСеансИнфобазы1С8Лкс(Знач СтрокаСоединения = "", Знач ИмяПользователя = "", Знач ПарольПользователя = "",
Знач ТипCOMОбъекта = "Application", Знач Видимость = Ложь, Знач ОбработатьИсключениеПодключения = Ложь,
ОписаниеОшибки = "", ИмяСервераПроцессов = "", КодРазрешения = "") Экспорт
ДопСтрокаСоединения = "";
Если ЗначениеЗаполнено(ИмяПользователя) Тогда
ДопСтрокаСоединения = ДопСтрокаСоединения + "Usr=""" + ИмяПользователя + """;" + "Pwd=""" + ПарольПользователя + """;";
КонецЕсли;
Если ЗначениеЗаполнено(КодРазрешения) Тогда
ДопСтрокаСоединения = ДопСтрокаСоединения + "UC=""" + КодРазрешения + """;";
КонецЕсли;
#Если Клиент Тогда
Состояние("Подключение к базе через COM...");
#КонецЕсли
ИмяCOMКласса = "v" + ирКэш.Получить().ИДВерсииПлатформы;
Если Найти(ТипCOMОбъекта, ".") = 0 Тогда
ИмяCOMКласса = ИмяCOMКласса + ".";
КонецЕсли;
ИмяCOMКласса = ИмяCOMКласса + ТипCOMОбъекта;
Попытка
Соединение = Новый COMОбъект(ИмяCOMКласса, ИмяСервераПроцессов);
Исключение
ВызватьИсключение "Ошибка создания COM объекта " + ИмяCOMКласса + ": " + ОписаниеОшибки();
КонецПопытки;
Если Не ЗначениеЗаполнено(СтрокаСоединения) Тогда
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
КонецЕсли;
ПолнаяСтрокаСоединения = СтрокаСоединения + ДопСтрокаСоединения;
Попытка
РезультатСоединения = Соединение.Connect(ПолнаяСтрокаСоединения);
Исключение
#Если Клиент Тогда
Состояние("");
#КонецЕсли
Если ОбработатьИсключениеПодключения Тогда
ОписаниеОшибки = ОписаниеОшибки();
Возврат ОписаниеОшибки;
Иначе
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
#Если Клиент Тогда
Состояние("");
#КонецЕсли
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если Найти(ТипCOMОбъекта, "Application") > 0 Тогда
#Если Клиент Тогда
Состояние("Ожидание инициализации сеанса...");
Для Счетчик = 1 По 20 Цикл
ОбработкаПрерыванияПользователя();
Попытка
Соединение.Visible = Видимость;
Прервать;
Исключение
// Тонкий клиент еще не готов
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
мПлатформа.Sleep(1);
КонецЦикла;
Состояние("");
Результат = Соединение;
#КонецЕсли
ИначеЕсли Найти(ТипCOMОбъекта, "ComConnector") > 0 Тогда
Результат = РезультатСоединения;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЗапуститьСеансПодПользователемЛкс(ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, ТипCOMОбъекта = "", РежимЗапуска = "Авто", КодРазрешения = "",
СообщитьКоманднуюСтроку = Ложь, ОткрытьПортативныеИнструменты = Истина, ОчисткаКэшаКлиентСерверныхВызовов = Истина, РазрешитьОтладку = Истина, ДополнительныеПараметры = "",
РежимИнтерфейсаТакси = Ложь, Элевация = Ложь, РазделениеДанных = "") Экспорт
Если ЗначениеЗаполнено(ТипCOMОбъекта) Тогда
Соединение = СоздатьСеансИнфобазы1С8Лкс(, ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, ТипCOMОбъекта, Истина,,,, КодРазрешения);
Иначе
#Если Клиент Тогда
//Если ирКэш.Получить().ВерсияПлатформы = 802015 Тогда
// Предупреждение("В релиза 8.2.15 функция недоступна", 20); // Антибаг платформы 8.2.15
// Возврат;
//КонецЕсли;
Если РежимЗапуска = "Авто" Тогда
// Антибаг платформы. При передачи этого режима в явном виде в некоторых случаях пароль в командной строке игнорируется
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователяИнфобазы);
Если ПользовательИБ.РежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение Тогда
КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий";
ИначеЕсли ПользовательИБ.РежимЗапуска = РежимЗапускаКлиентскогоПриложения.ОбычноеПриложение Тогда
КонечныйРежимЗапуска = "ОбычноеПриложение";
Иначе //Авто
Если Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение Тогда
КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий";
Иначе
КонечныйРежимЗапуска = "ОбычноеПриложение";
КонецЕсли;
КонецЕсли;
Иначе
КонечныйРежимЗапуска = РежимЗапуска;
КонецЕсли;
ПараметрыЗапуска = ПолучитьПараметрыЗапускаПриложения1СТекущейБазыЛкс(ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, КодРазрешения, Ложь, КонечныйРежимЗапуска,
РазрешитьОтладку, ОчисткаКэшаКлиентСерверныхВызовов, ДополнительныеПараметры, СообщитьКоманднуюСтроку, , ОткрытьПортативныеИнструменты, РежимИнтерфейсаТакси,
РазделениеДанных);
ТекущаяДата = ирСервер.ПолучитьТекущуюДатуЛкс();
Если КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий" Тогда
СтрокаЗапуска = """" + КаталогПрограммы() + "1cv8c.exe"" " + ПараметрыЗапуска;
ЗапуститьПриложение(СтрокаЗапуска);
Иначе
Если Элевация Тогда
Платформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
Платформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтрокаЗапуска = """" + КаталогПрограммы() + "1cv8.exe"" " + ПараметрыЗапуска;
Платформа.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(СтрокаЗапуска,,,, Ложь, Истина);
Иначе
ЗапуститьСистему(ПараметрыЗапуска);
КонецЕсли;
КонецЕсли;
Состояние("Ожидание запуска сеанса...");
Успех = Ложь;
ДатаПоследнегоВопроса = ирСервер.ПолучитьТекущуюДатуЛкс();
Пока Не Успех Цикл
ОбработкаПрерыванияПользователя();
Если ирСервер.ПолучитьТекущуюДатуЛкс() - ДатаПоследнегоВопроса >= 5 Тогда
Ответ = Вопрос("Продолжить ожидание сеанса (5 сек)?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Нет Тогда
Прервать;
КонецЕсли;
ДатаПоследнегоВопроса = ирСервер.ПолучитьТекущуюДатуЛкс();
КонецЕсли;
Сеансы = ПолучитьСеансыИнформационнойБазы();
Успех = Ложь;
Для Каждого Сеанс Из Сеансы Цикл
Если Истина
И Сеанс.НачалоСеанса >= ТекущаяДата
И НРег(Сеанс.ИмяКомпьютера) = НРег(ИмяКомпьютера())
И Сеанс.Пользователь <> Неопределено
И НРег(Сеанс.Пользователь.Имя) = НРег(ИмяПользователяИнфобазы)
Тогда
Успех = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Состояние("");
#Иначе
ВызватьИсключение "Запуск приложения допускается только на клиенте";
#КонецЕсли
КонецЕсли;
Возврат Соединение;
КонецФункции
// Параметры:
// XML -
// Тип -
// ИспользоватьXDTO -
// СообщатьОбОшибках -
//
Функция ВосстановитьОбъектИзСтрокиXMLЛкс(Знач ФайлИлиXML = "", Знач Тип = "", Знач ИспользоватьXDTO = Истина, Знач СообщатьОбОшибках = Истина) Экспорт
Если Ложь
Или ТипЗнч(ФайлИлиXML) = Тип("Файл")
Или ЗначениеЗаполнено(ФайлИлиXML)
Тогда
ЧтениеXML = Новый ЧтениеXML;
Если ТипЗнч(ФайлИлиXML) = Тип("Файл") Тогда
ЧтениеXML.ОткрытьФайл(ФайлИлиXML);
Иначе
ЧтениеXML.УстановитьСтроку(ФайлИлиXML);
КонецЕсли;
Попытка
Если ИспользоватьXDTO Тогда
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Иначе
Результат = ПрочитатьXML(ЧтениеXML);
КонецЕсли;
Исключение
Если СообщатьОбОшибках Тогда
Сообщить(ОписаниеОшибки(), СтатусСообщения.Важное);
КонецЕсли;
ЧтениеXML.Закрыть();
КонецПопытки;
// Антибаг платформы 8.2-8.3.6 СериализаторXDTO некорректно восстанавливает пустую табличную часть поверх непустой https://partners.v8.1c.ru/forum/t/1329468/m/1329468
Попытка
Пустышка = Результат.Модифицированность();
МетаТЧи = Результат.Метаданные().ТабличныеЧасти;
Исключение
МетаТЧи = Новый Массив;
КонецПопытки;
Для Каждого МетаТЧ Из МетаТЧи Цикл
ТЧ = Результат[МетаТЧ.Имя];
Если ТЧ.Количество() = 0 Тогда
Попытка
ТЧ.Вставить(0);
Исключение
// Недоступна по разделению группа/элемент с неадекватной ошибкой https://partners.v8.1c.ru/forum/t/1374212/m/1374212
Продолжить;
КонецПопытки;
ТЧ.Удалить(0);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Результат = Неопределено Тогда
Если ЗначениеЗаполнено(Тип) Тогда
Результат = Новый (Тип);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ВосстановитьНастройкуКомпоновкиИзСтрокиXMLЛкс(Знач XML = "", Знач СообщатьОбОшибках = Истина) Экспорт
Результат = ВосстановитьОбъектИзСтрокиXMLЛкс(XML, Тип("НастройкиКомпоновкиДанных"), , СообщатьОбОшибках);
Возврат Результат;
КонецФункции
// Параметры:
// Объект -
// ИспользоватьXDTO -
//
Функция СохранитьОбъектВВидеСтрокиXMLЛкс(Знач Объект, Знач ИспользоватьXDTO = Истина, ИмяФайла = "", СообщатьОбОшибках = Истина) Экспорт
Поток = Новый ЗаписьXML;
Если ЗначениеЗаполнено(ИмяФайла) Тогда
Попытка
Поток.ОткрытьФайл(ИмяФайла);
Исключение
ВызватьИсключение ОписаниеОшибки(); // Чтобы в диалоге "Вычислить выражение" полное описание показывалось
КонецПопытки;
Иначе
Поток.УстановитьСтроку();
КонецЕсли;
Попытка
Если ИспользоватьXDTO Тогда
СериализаторXDTO.ЗаписатьXML(Поток, Объект);
Иначе
ЗаписатьXML(Поток, Объект);
КонецЕсли;
Исключение
Поток.Закрыть();
Если СообщатьОбОшибках Тогда
ВызватьИсключение;
КонецЕсли;
Поток = Неопределено;
КонецПопытки;
Если Поток = Неопределено Тогда
Результат = Неопределено;
Иначе
Результат = Поток.Закрыть();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЗаписатьОбъектДляОтладкиЛкс(Объект, АдресРезультата = Неопределено) Экспорт
#Если Не Клиент Тогда
Если ТранзакцияАктивна() Тогда
лАдресРезультата = ПоместитьВоВременноеХранилище(Неопределено, Новый УникальныйИдентификатор);
СтрокаХМЛ = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
Параметры = Новый Массив();
Параметры.Добавить(СтрокаХМЛ);
Параметры.Добавить(лАдресРезультата);
ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ЗаписатьОбъектДляОтладкиЛкс", Параметры,, "Запись объекта для отладки (ИР)");
ФоновоеЗадание.ОжидатьЗавершения(3);
Результат = ПолучитьИзВременногоХранилища(лАдресРезультата);
Иначе
#КонецЕсли
Если ТипЗнч(Объект) = Тип("Строка") Тогда
Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(Объект);
КонецЕсли;
Объект.Записать();
Результат = Объект.Ссылка;
Если АдресРезультата <> Неопределено Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
#Если Не Клиент Тогда
КонецЕсли;
#КонецЕсли
Возврат Результат;
КонецФункции
Функция ПолучитьАвтоУникальноеИмяВКоллекцииСтрокЛкс(ТаблицаЗначений, БазовоеИмяИлиСтрока, ИмяКлючевойКолонки = "Имя", ИмяДолжноБытьИдентификатором = Истина,
ЗаменаПустойСтроки = "_", Знач ДопустимаяДлинаИдентификатораЕслиНеЗаданаВКолонке = 50) Экспорт
ТекущийИндекс = 0;
Если Ложь
Или ТипЗнч(БазовоеИмяИлиСтрока) = Тип("СтрокаТаблицыЗначений")
Или ТипЗнч(БазовоеИмяИлиСтрока) = Тип("СтрокаДереваЗначений")
Тогда
ИсключаемаяСтрока = БазовоеИмяИлиСтрока;
БазовоеИмя = БазовоеИмяИлиСтрока[ИмяКлючевойКолонки];
//ТекущийИндекс = 1;
Иначе
БазовоеИмя = БазовоеИмяИлиСтрока;
КонецЕсли;
Если ИмяДолжноБытьИдентификатором Тогда
ДопустимаяДлинаИдентификатора = ТаблицаЗначений.Колонки[ИмяКлючевойКолонки].ТипЗначения.КвалификаторыСтроки.Длина;
Если Не ЗначениеЗаполнено(ДопустимаяДлинаИдентификатора) Тогда
ДопустимаяДлинаИдентификатора = ДопустимаяДлинаИдентификатораЕслиНеЗаданаВКолонке;
КонецЕсли;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
БазовоеИмя = мПлатформа.ПолучитьИдентификаторИзПредставления(БазовоеИмя, ЗаменаПустойСтроки);
БазовоеИмя = Лев(БазовоеИмя, ДопустимаяДлинаИдентификатора);
Иначе
Если ПустаяСтрока(БазовоеИмя) Тогда
БазовоеИмя = ЗаменаПустойСтроки;
КонецЕсли;
КонецЕсли;
Пока Истина Цикл
ТекущийПсевдоним = БазовоеИмя + Формат(ТекущийИндекс, "ЧГ=");
СтрокиОдноименных = ТаблицаЗначений.НайтиСтроки(Новый Структура(ИмяКлючевойКолонки, ТекущийПсевдоним));
Если Ложь
Или СтрокиОдноименных.Количество() = 0
Или (Истина
И СтрокиОдноименных.Количество() = 1
И ИсключаемаяСтрока <> Неопределено
И СтрокиРавныЛкс(ТекущийПсевдоним, ИсключаемаяСтрока[ИмяКлючевойКолонки])
)
Тогда
Прервать;
КонецЕсли;
ТекущийИндекс = ТекущийИндекс + 1;
КонецЦикла;
Возврат ТекущийПсевдоним;
КонецФункции
// Сравнение - Строка, ВидСравнения - "Авто" - для автоматического выбора, по умолчанию Равно или ВСписке
//
// Параметры:
// ЭлементОтбора - <тип> -
// Сравнение - <тип>, "" -
// Значение - <тип> -
// ЗначениеПо - <тип> -
// Использование - <тип>, Истина -
// ПриводитьТипДляНеопределено - <тип>, Истина -
//
// Возвращаемое значение:
//
Функция УстановитьЭлементОтбораЛкс(Знач ЭлементОтбора, Знач Сравнение = "", Знач Значение, Знач ЗначениеПо = Неопределено, Знач Использование = Истина,
Знач ПриводитьТипДляНеопределено = Истина) Экспорт
Если ТипЗнч(Значение) = Тип("ФиксированныйМассив") Тогда
Значение = Новый Массив(Значение);
КонецЕсли;
Если ТипЗнч(Значение) = Тип("Массив") Тогда
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(Значение);
Значение = СписокЗначений;
ИначеЕсли Истина
И ПриводитьТипДляНеопределено
И Значение = Неопределено
Тогда
Значение = ЭлементОтбора.ТипЗначения.ПривестиЗначение(Значение);
КонецЕсли;
// Вид сравнения
Если СтрокиРавныЛкс(Сравнение, "Авто") Тогда
Сравнение = ОпределитьВидСравненияПоЗначениюЛкс(Значение);
ИначеЕсли ТипЗнч(Сравнение) = Тип("ВидСравнения") Тогда
ИначеЕсли Истина
И Сравнение <> Неопределено
И Сравнение <> ""
Тогда // Добавлено 25.03.2012
ВызватьИсключение "Неверный тип сравнения """ + ТипЗнч(Сравнение) + """";
Иначе
Если ТипЗнч(Значение) = Тип("СписокЗначений") Тогда
Сравнение = ВидСравнения.ВСписке;
Иначе
Сравнение = ВидСравнения.Равно;
КонецЕсли;
КонецЕсли;
// Еще надо сделать автоопределение Сожержит, как у компоновки
ЭлементОтбора.ВидСравнения = Сравнение;
Попытка
Если ЗначениеПо <> Неопределено Тогда
ЭлементОтбора.ЗначениеС = Значение;
ЭлементОтбора.ЗначениеПО = ЗначениеПо;
Иначе
ЭлементОтбора.Значение = Значение;
КонецЕсли;
Исключение
ВызватьИсключение "Ошибка установки значения типа """ + ТипЗнч(Значение) + """ элементу отбора """ + ЭлементОтбора.Имя + """: " + ОписаниеОшибки();
КонецПопытки;
Попытка
ЭлементОтбора.Использование = Использование;
Исключение
// Сюда попадаем для элемента отбора набора записей с регистратором
КонецПопытки;
КонецФункции
// Установить отбор по структуре иис
//
// Параметры:
// Отбор - <тип> -
// СтруктураОтбора - <тип> -
// Сравнение - <тип>, "Авто" -
// ДобавлятьСсылкуВПутьКДанным - <тип>, Ложь -
// СброситьПередУстановкой - <тип>, Истина -
//
// Возвращаемое значение:
//
Функция УстановитьОтборПоСтруктуреЛкс(Знач Отбор, Знач СтруктураОтбора, Знач Сравнение = "Авто", Знач ДобавлятьСсылкуВПутьКДанным = Ложь,
Знач СброситьПередУстановкой = Истина) Экспорт
Если СброситьПередУстановкой Тогда
Отбор.Сбросить();
КонецЕсли;
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
ПутьКДанным = КлючИЗначение.Ключ;
Если ДобавлятьСсылкуВПутьКДанным Тогда
ПутьКДанным = "Ссылка." + ПутьКДанным;
КонецЕсли;
НайтиДобавитьЭлементОтбораЛкс(Отбор, ПутьКДанным, Сравнение, КлючИЗначение.Значение, , , КлючИЗначение.Ключ);
КонецЦикла;
КонецФункции
Процедура ЗаполнитьНаборЗаписейПоОтборуЛкс(НаборЗаписей) Экспорт
#Если Сервер И Не Сервер Тогда
НаборЗаписей = РегистрыСведений.Журнал_АвтозаданияИис.СоздатьНаборЗаписей();
#КонецЕсли
СтруктураЗначенийОтбора = Новый Структура;
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
Если ЭлементОтбора.Использование Тогда
СтруктураЗначенийОтбора.Вставить(ЭлементОтбора.Имя, ЭлементОтбора.Значение);
КонецЕсли;
КонецЦикла;
Для Каждого СтрокаНабора Из НаборЗаписей Цикл
ЗаполнитьЗначенияСвойств(СтрокаНабора, СтруктураЗначенийОтбора);
КонецЦикла;
КонецПроцедуры
// Параметры:
// Объект - - Ссылочный объект или запись регистра
// Отбор - Отбор
//
Функция УстановитьЗначенияРеквизитовПоОтборуЛкс(Объект, Отбор) Экспорт
Для Каждого ЭлементОтбора Из Отбор Цикл
Если Ложь
Или Не ЭлементОтбора.Использование
Или ЭлементОтбора.ВидСравнения <> ВидСравнения.Равно
Тогда
Продолжить;
КонецЕсли;
ИмяРеквизита = ЭлементОтбора.Имя;
ЗначениеОтбора = ЭлементОтбора.Значение;
Попытка
Объект[ИмяРеквизита] = ЗначениеОтбора;
Исключение
// Сюда попадаем например для ЭтоГруппа
КонецПопытки;
КонецЦикла;
КонецФункции
// Определить вид сравнения по значению иис
//
// Параметры:
// Значение - <тип> -
// РежимКомпоновки - <тип>, Ложь -
// ДоступныеВидыСравнения - <тип>, Неопределено -
//
// Возвращаемое значение:
//
Функция ОпределитьВидСравненияПоЗначениюЛкс(Знач Значение, Знач РежимКомпоновки = Ложь, Знач ДоступныеВидыСравнения = Неопределено) Экспорт
ТипЗначения = ТипЗнч(Значение);
Если РежимКомпоновки Тогда
КоллекцияВидовСравнения = ВидСравненияКомпоновкиДанных;
Иначе
КоллекцияВидовСравнения = ВидСравнения;
КонецЕсли;
Если ТипЗначения = Тип("СписокЗначений") Тогда
Результат = КоллекцияВидовСравнения.ВСписке;
ИначеЕсли Истина
И ТипЗначения = Тип("Строка")
И ДоступныеВидыСравнения <> Неопределено
И ДоступныеВидыСравнения.НайтиПоЗначению(КоллекцияВидовСравнения.Содержит) <> Неопределено
Тогда
Результат = КоллекцияВидовСравнения.Содержит;
Иначе
Результат = КоллекцияВидовСравнения.Равно;
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗначения);
Если ОбъектМД <> Неопределено Тогда
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ОбъектМД.ПолноеИмя());
Если ТипТаблицы = "Справочник" Тогда
Если ОбъектМД.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда
Если Значение.ЭтоГруппа Тогда
Результат = КоллекцияВидовСравнения.ВИерархии;
КонецЕсли;
Иначе // иерархия элементов
Результат = КоллекцияВидовСравнения.ВИерархии;
КонецЕсли;
ИначеЕсли ТипТаблицы = "ПланВидовХарактеристик" Тогда
Если Значение.ЭтоГруппа Тогда
Результат = КоллекцияВидовСравнения.ВИерархии;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Сравнение - Строка, ВидСравнения - "Авто" - для автоматического выбора, по умолчанию Равно или ВСписке
//
// Параметры:
// ОтборИлиОбъект - <тип> -
// ПутьКДанным - <тип>, "" -
// Сравнение - <тип>, "" -
// Значение - <тип>, Неопределено -
// ЗначениеПо - <тип>, Неопределено -
// Использование - <тип>, Истина -
// Имя - <тип>, "" -
// Представление - <тип>, "" -
//
// Возвращаемое значение:
//
Функция НайтиДобавитьЭлементОтбораЛкс(Знач ОтборИлиОбъект, Знач ПутьКДанным = "", Знач Сравнение = "", Знач Значение = Неопределено, Знач ЗначениеПо = Неопределено,
Знач Использование = Истина, Знач Имя = "", Знач Представление = "") Экспорт
Если ТипЗнч(ОтборИлиОбъект) = Тип("Отбор") Тогда
Отбор = ОтборИлиОбъект;
Иначе
Отбор = ОтборИлиОбъект.Отбор;
КонецЕсли;
// Ищем или добавляем новый элемент отбора
ЭлементОтбора = Неопределено;
//Если Имя <> Неопределено Тогда
// ЭлементОтбора= Отбор.Найти(Имя);
//КонецЕсли;
Если Имя <> Неопределено Тогда
Для Каждого ЭлОтбора Из Отбор Цикл
Если Ложь
Или ЭлОтбора.Имя = Имя
Или ЭлОтбора.Представление = Имя
Тогда
ЭлементОтбора = ЭлОтбора;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЭлементОтбора = Неопределено Тогда
Попытка
ЭлементОтбора = Отбор.Добавить(ПутьКДанным, Имя, Представление);
Исключение
ВызватьИсключение "Ошибка добавления элемента отбора """ + ПутьКДанным + """ построителя запроса: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
УстановитьЭлементОтбораЛкс(ЭлементОтбора, Сравнение, Значение, ЗначениеПо, Использование);
Результат = ЭлементОтбора;
Возврат Результат;
КонецФункции
Процедура ДобавитьПрефиксВсемПараметрамЗапросаЛкс(Запрос, Префикс = "Т") Экспорт
#Если Сервер И Не Сервер Тогда
Запрос = Новый Запрос;
#КонецЕсли
ТекстЗапроса = Запрос.Текст;
Параметры = Новый Структура;
СкопироватьУниверсальнуюКоллекциюЛкс(Запрос.Параметры, Параметры);
Для Каждого КлючИЗначение Из Параметры Цикл
Если Найти(КлючИЗначение.Ключ, Префикс) = 1 Тогда
ВызватьИсключение "Начало имени параметра " + КлючИЗначение.Ключ + " совпадает с префиксом " + Префикс;
КонецЕсли;
НовоеИмя = Префикс + КлючИЗначение.Ключ;
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&" + КлючИЗначение.Ключ, "&" + НовоеИмя);
Запрос.УстановитьПараметр(НовоеИмя, КлючИЗначение.Значение);
КонецЦикла;
Запрос.Текст = ТекстЗапроса;
КонецПроцедуры
// ТаблицаПараметров - ТаблицаЗначений, ТабличнаяЧасть
Функция НайтиДобавитьПараметрСсылкуВТаблицуЛкс(ТаблицаПараметров, ИмяКолонкиИмени = "Имя", ИмяКолонкиЗначения = "Значение", ЗначениеПараметра,
ИмяПараметра = Неопределено, ОбновитьКопиюСвойстваВНижнемРегистре = Ложь) Экспорт
Если ТипЗнч(ТаблицаПараметров) = Тип("ТаблицаЗначений") Тогда
МакетТаблицы = ТаблицаПараметров;
Иначе
МакетТаблицы = ТаблицаПараметров.ВыгрузитьКолонки();
КонецЕсли;
Строки = ТаблицаПараметров.НайтиСтроки(Новый Структура(ИмяКолонкиЗначения, ЗначениеПараметра));
Если Строки.Количество() > 0 Тогда
Результат = Строки[0];
Иначе
Если ТипЗнч(ЗначениеПараметра) = Тип("Строка") Тогда
ИмяПараметра = ПолучитьАвтоУникальноеИмяВКоллекцииСтрокЛкс(ТаблицаПараметров, "П", ИмяКолонкиИмени);
Иначе
ИмяТипа = ИмяТипаИзПолногоИмениМДЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеПараметра)));
//Префикс = НРег(Лев(ОбъектМД.Имя, 1));
Префикс = "";
Если ИмяПараметра = Неопределено Тогда
ИмяПараметра = "" + РасширенноеПредставлениеЗначенияЛкс(ЗначениеПараметра);
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяПараметра) Тогда
ИмяПараметра = СтрЗаменить(ИмяТипа, ".", "") + "Пустая";
КонецЕсли;
ИмяПараметра = Префикс + ирКэш.Получить().ПолучитьИдентификаторИзПредставления(ИмяПараметра);
ДопустимаяДлинаСтроки = МакетТаблицы.Колонки[ИмяКолонкиИмени].ТипЗначения.КвалификаторыСтроки.Длина;
Если ДопустимаяДлинаСтроки > 0 Тогда
ИмяПараметра = Лев(ИмяПараметра, ДопустимаяДлинаСтроки);
КонецЕсли;
КонецЕсли;
СтруктураСвойствПараметра = Новый Структура;
СтруктураСвойствПараметра.Вставить(ИмяКолонкиИмени, ИмяПараметра);
Счетчик = 0;
Пока ТаблицаПараметров.НайтиСтроки(СтруктураСвойствПараметра).Количество() > 0 Цикл
Счетчик = Счетчик + 1;
СтрокаНомера = "" + Счетчик;
Если ДопустимаяДлинаСтроки > 0 Тогда
лИмяПараметра = Лев(ИмяПараметра, ДопустимаяДлинаСтроки - СтрДлина(СтрокаНомера));
Иначе
лИмяПараметра = ИмяПараметра;
КонецЕсли;
СтруктураСвойствПараметра[ИмяКолонкиИмени] = лИмяПараметра + СтрокаНомера;
КонецЦикла;
СтруктураСвойствПараметра.Вставить("ЭтоВыражение", Ложь);
СтруктураСвойствПараметра.Вставить(ИмяКолонкиЗначения, ЗначениеПараметра);
СтрокаНовогоПараметра = ТаблицаПараметров.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаНовогоПараметра, СтруктураСвойствПараметра);
Если ОбновитьКопиюСвойстваВНижнемРегистре Тогда
ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаНовогоПараметра, ИмяКолонкиИмени);
КонецЕсли;
Результат = СтрокаНовогоПараметра;
КонецЕсли;
Возврат Результат;
КонецФункции // ДобавитьПараметрЗначение()
Функция ПолучитьНаборЗаписейПоКлючуЛкс(ПолноеИмяТаблицыИлиНаборЗаписей, КлючНабора, ДобавитьИЗаполнитьСтрокуНабора = Ложь) Экспорт
Если ТипЗнч(ПолноеИмяТаблицыИлиНаборЗаписей) = Тип("Строка") Тогда
НаборЗаписей = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыИлиНаборЗаписей);
Иначе
НаборЗаписей = ПолноеИмяТаблицыИлиНаборЗаписей;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
НаборЗаписей = РегистрыСведений.Журнал_АвтозаданияИис.СоздатьНаборЗаписей();
#КонецЕсли
//СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолучитьИмяТаблицыИзМетаданныхЛкс(НаборЗаписей.Метаданные()), Ложь);
//Для Каждого ПолеКлюча Из СтруктураКлюча Цикл
// ИмяПоля = ПолеКлюча.Ключ;
// Попытка
// ЗначениеКлюча = КлючНабора[ИмяПоля];
// Исключение
// // Имеет смысл для регистров сведений
// Продолжить;
// КонецПопытки;
// ЭлементОтбора = НаборЗаписей.Отбор[ИмяПоля];
// ЭлементОтбора.Значение = ЗначениеКлюча;
// ЭлементОтбора.Использование = Истина;
//КонецЦикла;
Если ЛиКлючЗаписиРегистраЛкс(КлючНабора) Тогда
КлючНабора = ПолучитьКлючНабораЗаписейИзКлючаЗаписиЛкс(КлючНабора, ПолноеИмяТаблицыИлиНаборЗаписей);
КонецЕсли;
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
ИмяПоля = ЭлементОтбора.Имя;
Попытка
ЗначениеКлюча = КлючНабора[ИмяПоля];
Исключение
// Имеет смысл для регистров сведений
Продолжить;
КонецПопытки;
ЭлементОтбора.Значение = ЗначениеКлюча;
ЭлементОтбора.Использование = Истина;
КонецЦикла;
Если ДобавитьИЗаполнитьСтрокуНабора Тогда
ЗаполнитьЗначенияСвойств(НаборЗаписей.Добавить(), КлючНабора);
КонецЕсли;
Возврат НаборЗаписей;
КонецФункции
// Получает копию таблицы значений с минимальными типами колонок для содержания всех данных.
// Параметры:
// ТаблицаДанных - ТаблицаЗначений
// СужатьТолькоПроизвольныеКолонки - Булево - обрабатывать только колонки с пустым (произвольным) типом
// ИмяКолонки - Строка - нужна только эта колонка
//
Функция ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(Знач ТаблицаДанных, СужатьТолькоПроизвольныеКолонки = Ложь, ИмяКолонки = "") Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаДанных = Новый ТаблицаЗначений;
#КонецЕсли
ОставляемыеКолонки = "";
СужаемыеКолонки = Новый Массив();
Для Каждого КолонкаДанных Из ТаблицаДанных.Колонки Цикл
Если ЗначениеЗаполнено(ИмяКолонки) И Не СтрокиРавныЛкс(ИмяКолонки, КолонкаДанных.Имя) Тогда
Продолжить;
КонецЕсли;
Если Истина
И СужатьТолькоПроизвольныеКолонки
И КолонкаДанных.ТипЗначения.Типы().Количество() > 0
Тогда
ОставляемыеКолонки = ОставляемыеКолонки + "," + КолонкаДанных.Имя;
Иначе
СужаемыеКолонки.Добавить(КолонкаДанных);
КонецЕсли;
КонецЦикла;
//Состояние("Оптимизация типов колонок");
НовыеКолонки = Новый Структура;
МетаданныеТаблицыИзменены = Ложь;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(СужаемыеКолонки.Количество(), "Анализ колонок");
Для Каждого КолонкаДанных Из СужаемыеКолонки Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
Типы = Новый Массив;
ТаблицаКолонки = ТаблицаДанных.Скопировать(, КолонкаДанных.Имя);
ТаблицаКолонки.Свернуть(КолонкаДанных.Имя);
СтароеОписаниеТипов = КолонкаДанных.ТипЗначения;
Для Каждого СтрокаДанных Из ТаблицаКолонки Цикл
ТипЗначения = ТипЗнч(СтрокаДанных[КолонкаДанных.Имя]);
Если Истина
И ТипЗначения <> Тип("Неопределено")
И Типы.Найти(ТипЗначения) = Неопределено
Тогда
Типы.Добавить(ТипЗначения);
КонецЕсли;
КонецЦикла;
Если Типы.Количество() = 0 Тогда
Типы = КолонкаДанных.ТипЗначения.Типы();
Если Типы.Количество() = 0 Тогда
Типы.ДОбавить(Тип("Булево"));
Типы.ДОбавить(Тип("Число"));
КонецЕсли;
// Чтобы от супертипов через точку не было много соединений, оставляем только 2 типа
Пока Типы.Количество() > 2 Цикл
Типы.Удалить(0);
КонецЦикла;
КонецЕсли;
Если Типы.Количество() <> СтароеОписаниеТипов.Типы().Количество() Тогда
МетаданныеТаблицыИзменены = Истина;
КонецЕсли;
НовоеОписаниеТипов = Новый ОписаниеТипов(Типы, , , СтароеОписаниеТипов.КвалификаторыЧисла, СтароеОписаниеТипов.КвалификаторыСтроки, СтароеОписаниеТипов.КвалификаторыДаты);
НовыеКолонки.Вставить(КолонкаДанных.Имя, НовоеОписаниеТипов);
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Если МетаданныеТаблицыИзменены Тогда
Если ОставляемыеКолонки <> "" Тогда
ТипизированнаяТаблица = ТаблицаДанных.Скопировать(, ОставляемыеКолонки);
Иначе
ТипизированнаяТаблица = Новый ТаблицаЗначений;
КонецЕсли;
Для Каждого КлючИЗначение Из НовыеКолонки Цикл
ТипизированнаяТаблица.Колонки.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Значение, ТаблицаДанных.Колонки[КлючИЗначение.Ключ].Заголовок);
КонецЦикла;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаДанных.Количество() / 100, "Оптимизация таблицы");
Для Индекс = 0 По ТаблицаДанных.Количество() - 1 Цикл
Если Индекс % 100 = 0 Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
Если ОставляемыеКолонки <> "" Тогда
СтрокаТипизированнойТаблицы = ТипизированнаяТаблица[Индекс];
Иначе
СтрокаТипизированнойТаблицы = ТипизированнаяТаблица.Добавить();
КонецЕсли;
ЗаполнитьЗначенияСвойств(СтрокаТипизированнойТаблицы, ТаблицаДанных[Индекс]);
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Иначе
ТипизированнаяТаблица = ТаблицаДанных;
КонецЕсли;
Результат = ТипизированнаяТаблица;
Возврат Результат;
КонецФункции
// ************************
// WMI
Функция ПолучитьСтруктуруИзЗначенияWMIЛкс(ЗначениеWMI) Экспорт
Результат = Новый Структура;
Для каждого СвойствоWMI из ЗначениеWMI Цикл
Если ТипЗнч(СвойствоWMI.Value) = Тип("COMSafeArray") Тогда
ЗначениеСвойства = СвойствоWMI.Value.Выгрузить();// возможно массив надо будет переделать
Иначе
ЗначениеСвойства = СвойствоWMI.Value;
//ИмяТипа = ПолучитьИмяТипаИзКвалификаторовWMIЛкс(СвойствоWMI);
//Если СтрокиРавныЛкс(ИмяТипа, "Дата") Тогда
Если СвойствоWMI.CIMTYPE = 101 Тогда //datetime
ЗначениеСвойства = СтрокаДатыWMIВДатуЛкс(ЗначениеСвойства);
КонецЕсли;
КонецЕсли;
Результат.Вставить(СвойствоWMI.Name, ЗначениеСвойства);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ПолучитьИмяТипаИзКвалификаторовWMIЛкс(Свойство) Экспорт
ИмяТипа = "";
Попытка
Квалификаторы = Свойство.Qualifiers_;
Исключение
// Нет у системных свойств
Квалификаторы = Новый Массив();
КонецПопытки;
Для Каждого Квалификатор Из Квалификаторы Цикл
Если СтрокиРавныЛкс("CIMTYPE", Квалификатор.Name) Тогда
ИмяТипа = Нрег(Квалификатор.Value);
Прервать;
КонецЕсли;
КонецЦикла;
Если Ложь
Или Найти(ИмяТипа, "int") > 0
Тогда
ИмяТипа = "Число";
ИначеЕсли Ложь
Или Найти(ИмяТипа, "date") > 0
Или Найти(ИмяТипа, "time") > 0
Тогда
ИмяТипа = "Дата";
ИначеЕсли Ложь
Или Найти(ИмяТипа, "string") > 0
Или Найти(ИмяТипа, "char") > 0
Тогда
ИмяТипа = "Строка";
ИначеЕсли ТипЗнч(ИмяТипа) = Тип("COMОбъект") Тогда
ИмяТипа = "COMОбъект.{WbemScripting.SwbemLocator}." + ИмяТипа;
КонецЕсли;
Возврат ИмяТипа;
КонецФункции
Функция ПолучитьОписаниеЭлементаWMIЛкс(ЭлементКоллекции, ИмяСвойства = "Description") Экспорт
ОписаниеЭлемента = "";
Квалификаторы = ЭлементКоллекции.qualifiers_;
Попытка
КвалификаторОписание = Квалификаторы.item(ИмяСвойства);
Исключение
КвалификаторОписание = Неопределено;
КонецПопытки;
Если КвалификаторОписание <> Неопределено Тогда
ОписаниеЭлемента = КвалификаторОписание.Value;
КонецЕсли;
Возврат ОписаниеЭлемента;
КонецФункции
Функция ПолучитьДокументациюСвойстваWMIЛкс(ИмяКласса, ИмяСвойства, СлужбаWMI = Неопределено) Экспорт
Если СлужбаWMI = Неопределено Тогда
СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс();
КонецЕсли;
wbemFlagUseAmendedQualifiers = 131072; //&H20000
ОписанияСвойств = СлужбаWMI.Get(ИмяКласса, wbemFlagUseAmendedQualifiers).Properties_;
Попытка
ОписаниеСвойства = ОписанияСвойств.item(ИмяСвойства);
Исключение
Возврат "";
КонецПопытки;
ТекстОписания = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства);
ТипЗначений = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства, "CIMTYPE");
Если ТипЗначений <> Неопределено Тогда
ТекстОписания = ТекстОписания + "
|Type: " + ТипЗначений;
КонецЕсли;
ЕдиницаИзмерения = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства, "Units");
Если ЗначениеЗаполнено(ЕдиницаИзмерения) Тогда
ТекстОписания = ТекстОписания + "
|Unit: " + ЕдиницаИзмерения;
КонецЕсли;
Возврат ТекстОписания;
КонецФункции
Функция ПолучитьДокументациюМетодаWMIЛкс(ИмяКласса, ИмяМетода, СлужбаWMI = Неопределено) Экспорт
Если СлужбаWMI = Неопределено Тогда
СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс();
КонецЕсли;
wbemFlagUseAmendedQualifiers = 131072; //&H20000
ОписанияМетодов = СлужбаWMI.Get(ИмяКласса, wbemFlagUseAmendedQualifiers).Methods_;
Попытка
ОписаниеМетода = ОписанияМетодов.item(ИмяМетода);
Исключение
Возврат "";
КонецПопытки;
ТекстОписания = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода);
ТипЗначений = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода, "CIMTYPE");
Если ТипЗначений <> Неопределено Тогда
ТекстОписания = ТекстОписания + "
|Type: " + ТипЗначений;
КонецЕсли;
ЕдиницаИзмерения = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода, "Units");
Если ЗначениеЗаполнено(ЕдиницаИзмерения) Тогда
ТекстОписания = ТекстОписания + "
|Unit: " + ЕдиницаИзмерения;
КонецЕсли;
Возврат ТекстОписания;
КонецФункции
// Параметры:
// СтрокаДаты - Строка(0,П)
//
Функция СтрокаДатыWMIВДатуЛкс(Знач СтрокаДаты = "") Экспорт
Если Не ЗначениеЗаполнено(СтрокаДаты) Тогда
Возврат Дата(1,1,1);
Иначе
Строка = Лев(СтрокаДаты, 4) + Сред(СтрокаДаты, 5, 2) + Сред(СтрокаДаты, 7, 2)
+ Сред (СтрокаДаты, 9, 2) + Сред(СтрокаДаты, 11, 2) + Сред(СтрокаДаты, 13, 2);
Попытка
Результат = Дата(Строка);
Исключение
Сообщить("Ошибка преобразования даты WMI из строки """ + СтрокаДаты + """: " + ОписаниеОшибки());
Возврат Дата(1,1,1);
КонецПопытки;
Результат = Результат + Вычислить("0." + Сред(СтрокаДаты, 16, 6));
КонецЕсли;
Возврат Результат;
КонецФункции
// WMI
// *************************
// ************************
// ADO
Функция ПолучитьКолонкиRecordsetADOЛкс(РезультатТаблица, РезультатRecordset, Типизировать1С = Неопределено) Экспорт
Если РезультатТаблица = Неопределено Тогда
РезультатТаблица = Новый ТаблицаЗначений;
КонецЕсли;
мПлатформа = ирКэш.Получить();
FieldКолонка = Новый Соответствие;
Для каждого Field Из РезультатRecordset.Fields Цикл
Если ПустаяСтрока(Field.Name) Тогда
ИмяКолонки = ":?";
Для о=1 По СтрДлина(Field.Name)-1 Цикл
ИмяКолонки = ИмяКолонки + "?";
КонецЦикла;
Иначе
ИмяКолонки = Field.Name;
КонецЕсли;
Если Не ЛиИмяПеременнойЛкс(ИмяКолонки) Тогда
ИмяКолонки = мПлатформа.ПолучитьИдентификаторИзПредставления(ИмяКолонки);
КонецЕсли;
// контроль полей - двойников по именам
НомерДвойника=0;
Пока РезультатТаблица.Колонки.Найти(ИмяКолонки + Формат(НомерДвойника,"ЧГ=0")) <> Неопределено Цикл
НомерДвойника = НомерДвойника + 1;
КонецЦикла;
ИмяКолонки = ИмяКолонки + Формат(НомерДвойника, "ЧГ=0");
Если Типизировать1С = Истина Тогда
Тип1С = FieldADO_ПолучитьТип1CЛкс(Field);
Иначе
Тип1С = Неопределено;
КонецЕсли;
//Если Тип1С=Неопределено Тогда
// Колонка = РезультатТаблица.Колонки.Добавить(ИмяКолонки,,"["+Name+"]");
//Иначе
Колонка = РезультатТаблица.Колонки.Добавить(ИмяКолонки,Тип1С);
//КонецЕсли;
FieldКолонка.Вставить(Field, Колонка);
КонецЦикла;
Возврат FieldКолонка;
КонецФункции
// Выгружает результат запроса ADO (объект 'ADODB.Recordset') в таблицу значений с выводом прогресса состояния выгрузки
Функция ПреобразоватьРезультатADOВТаблицуЗначенийЛкс(РезультатRecordset, Типизировать1С = Ложь, БинарныеВСтроку = Ложь, RecordsAffected = 0,
ИгнорироватьНеподдерживаемыеТипы = Ложь, ЗагружатьЭлементов = Неопределено, СмещениеГода = 0) Экспорт
РезультатТаблица = Новый ТаблицаЗначений;
Если РезультатRecordset = Неопределено Тогда
Возврат РезультатТаблица;
КонецЕсли;
Если ЗначениеЗаполнено(ЗагружатьЭлементов) Тогда
КоличествоЭлементов = Мин(ЗагружатьЭлементов, РезультатRecordset.RecordCount);
Иначе
КоличествоЭлементов = РезультатRecordset.RecordCount;
КонецЕсли;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, "Загрузка результата");
Если РезультатRecordset.State = 0 Тогда
// Выполнена команда
РезультатТаблица.Колонки.Добавить("ExecutionInfo",, "Информация о выполнении:");
Стр = РезультатТаблица.Добавить();
Стр.ExecutionInfo = "Число записей, обработанных запросом: " + RecordsAffected;
Иначе
FieldКолонка = ирОбщий.ПолучитьКолонкиRecordsetADOЛкс(РезультатТаблица, РезультатRecordset, Типизировать1С);
// Открыта выборка
ТипCOMSafeArray = Тип("COMSafeArray");
adBinaryType = ирОбщий.intTypeADOЛкс("adBinary");
adVarBinaryType = ирОбщий.intTypeADOЛкс("adVarBinary");
adLongVarBinaryType = ирОбщий.intTypeADOЛкс("adLongVarBinary");
ПервыйРаз = Истина;
Счетчик = 0;
Если РезультатRecordset.EOF() = 0 И РезультатRecordset.ВOF() = 0 Тогда
РезультатRecordset.MoveFirst();
КонецЕсли;
Пока РезультатRecordset.EOF() = 0 Цикл
Если Индикатор.Счетчик = КоличествоЭлементов Тогда
Прервать;
КонецЕсли;
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
Счетчик = Счетчик + 1;
СтрНов = РезультатТаблица.Добавить();
Для каждого Field Из РезультатRecordset.Fields Цикл
Попытка
ЗначениеПоля = Field.Value;
Исключение
Если Не ИгнорироватьНеподдерживаемыеТипы Тогда
ВызватьИсключение "ADO. Невозможно прочитать значение типа " + XMLСтрока(Field.Type) + " из колонки результата """ + Field.Name + """";
КонецЕсли;
ЗначениеПоля = Неопределено;
КонецПопытки;
Индекс = РезультатТаблица.Колонки.Индекс(FieldКолонка.Получить(Field));
Если Истина
И ТипЗнч(ЗначениеПоля) = ТипCOMSafeArray
И БинарныеВСтроку = Истина
И (Ложь
Или Field.Type = adBinaryType
Или Field.Type = adVarBinaryType
//ИЛИ (Field.Type=adLongVarBinaryType)
)
Тогда
// преобразование COMSafeArray в строку HEX
СтрНов[Индекс] = BinaryCOMSafeArrayToHEXЛкс(ЗначениеПоля);
ИначеЕсли СмещениеГода <> 0 И ТипЗнч(ЗначениеПоля) = Тип("Дата") Тогда
СтрНов[Индекс] = ДобавитьМесяц(ЗначениеПоля, - СмещениеГода * 12);
Иначе
// преобразование типа неявное
СтрНов[Индекс] = ЗначениеПоля;
КонецЕсли;
КонецЦикла;
РезультатRecordset.MoveNext();
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
Возврат РезультатТаблица;
КонецФункции
// *** УСТАНОВКА ПАРАМЕТРОВ ЗАПРОСА ADO ***
// подбирает описание типа 1С, соответствующее типу ADO
Функция ПреобразоватьТипADO_Тип1СЛкс(Type,Size,Precision0,NumericScale0, Справочно = Ложь) Экспорт
Тип1С = Неопределено;
Если Precision0 > 0 И NumericScale0 >= 0 Тогда
Если Precision0 < NumericScale0 Тогда
// кривой вариант настроек типа ADO (может иногда возвращаться провайдерами данных)
Precision = Precision0 + NumericScale0;
Иначе
Precision = Precision0;
КонецЕсли;
UseМаксЧисло = (Precision > 32);
Иначе
// совсем кривой вариант
UseМаксЧисло = Истина;
КонецЕсли;
NumericScale = ?(NumericScale0 < 0, 0, NumericScale0);
NumericScaleM = ?(NumericScale > 10, 10, NumericScale);
Если Type = intTypeADOЛкс("adEmpty") Тогда
ИначеЕсли Type = intTypeADOЛкс("adSmallInt")Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(5, 0, ДопустимыйЗнак.Любой));
ИначеЕсли Type = intTypeADOЛкс("adInteger") Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0, ДопустимыйЗнак.Любой));
ИначеЕсли Type = intTypeADOЛкс("adSingle") Тогда
Если UseМаксЧисло Тогда
// взвешанно-максимальный числовой тип
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой));
Иначе
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой));
КонецЕсли;
ИначеЕсли Type = intTypeADOЛкс("adDouble") Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision+NumericScale, NumericScale, ДопустимыйЗнак.Любой));
Если UseМаксЧисло Тогда
// взвешанно-максимальный числовой тип
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой));
Иначе
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой));
КонецЕсли;
ИначеЕсли Type = intTypeADOЛкс("adCurrency")Тогда
Если UseМаксЧисло Тогда
// взвешанно-максимальный числовой тип
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой));
Иначе
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой));
КонецЕсли;
ИначеЕсли Type = intTypeADOЛкс("adDate") Тогда
Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.Дата));
ИначеЕсли Type = intTypeADOЛкс("adBSTR") Тогда
Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная));
ИначеЕсли Type = intTypeADOЛкс("adIDispatch")Тогда
ИначеЕсли Type = intTypeADOЛкс("adError") Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли Type = intTypeADOЛкс("adBoolean") Тогда
Тип1С = Новый ОписаниеТипов("Булево");
ИначеЕсли Type = intTypeADOЛкс("adVariant") Тогда
ИначеЕсли Type = intTypeADOЛкс("adIUnknown")Тогда
ИначеЕсли Type = intTypeADOЛкс("adDecimal") Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой));
ИначеЕсли Type = intTypeADOЛкс("adTinyInt") Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(3, 0, ДопустимыйЗнак.Любой));
ИначеЕсли Type = intTypeADOЛкс("adUnsignedTinyInt")Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(3, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли Type = intTypeADOЛкс("adUnsignedSmallInt")Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(5, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли Type = intTypeADOЛкс("adUnsignedInt")Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли Type = intTypeADOЛкс("adBigInt") Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(20, 0, ДопустимыйЗнак.Любой));
ИначеЕсли Type = intTypeADOЛкс("adUnsignedBigInt")Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(20, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли Type = intTypeADOЛкс("adFileTime")Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли Type = intTypeADOЛкс("adGUID") Тогда
Если Справочно Тогда
Тип1С = Новый ОписаниеТипов("УникальныйИдентификатор");
КонецЕсли;
ИначеЕсли Type = intTypeADOЛкс("adBinary") Тогда
Если Справочно Тогда
Тип1С = Новый ОписаниеТипов("Двоичныеданные");
КонецЕсли;
ИначеЕсли Type = intTypeADOЛкс("adChar") Тогда
Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная));
ИначеЕсли Type = intTypeADOЛкс("adWChar") Тогда
Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная));
ИначеЕсли Type = intTypeADOЛкс("adNumeric") Тогда
Если UseМаксЧисло Тогда
// взвешанно-максимальный числовой тип
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой));
Иначе
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой));
КонецЕсли;
ИначеЕсли Type = intTypeADOЛкс("adUserDefined")Тогда
ИначеЕсли Type = intTypeADOЛкс("adDBDate") Тогда
Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.Дата));
ИначеЕсли Type = intTypeADOЛкс("adDBTime") Тогда
Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.Время));
ИначеЕсли Type = intTypeADOЛкс("adDBTimeStamp")Тогда
Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя));
ИначеЕсли Type = intTypeADOЛкс("adChapter") Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли Type = intTypeADOЛкс("adPropVariant")Тогда
ИначеЕсли Type = intTypeADOЛкс("adVarNumeric")Тогда
Если UseМаксЧисло Тогда
// взвешанно-максимальный числовой тип
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой));
Иначе
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой));
КонецЕсли;
ИначеЕсли Type = intTypeADOЛкс("adVarChar") Тогда
Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная));
ИначеЕсли Type = intTypeADOЛкс("adLongVarChar")Тогда
Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(0, ДопустимаяДлина.Переменная));
ИначеЕсли Type = intTypeADOЛкс("adVarWChar")Тогда
Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная));
ИначеЕсли Type = intTypeADOЛкс("adLongVarWChar")Тогда
Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(0, ДопустимаяДлина.Переменная));
ИначеЕсли Type = intTypeADOЛкс("adVarBinary")Тогда
Если Справочно Тогда
Тип1С = Новый ОписаниеТипов("Двоичныеданные");
КонецЕсли;
ИначеЕсли Type = intTypeADOЛкс("adLongVarBinary")Тогда
Если Справочно Тогда
Тип1С = Новый ОписаниеТипов("Двоичныеданные");
КонецЕсли;
ИначеЕсли Type = intTypeADOЛкс("AdArray") Тогда
Иначе // Тип1С = Неопределено;
КонецЕсли;
Возврат Тип1С;
КонецФункции // ПреобразоватьТипADO_Тип1СЛкс()
// возвращает описание типа 1С, соответствующее типу объекта ADODB.Field
// значение Неопределено соответствует значению произвольного типа 1С
Функция FieldADO_ПолучитьТип1CЛкс(FieldADOЛкс, Справочно = Ложь) Экспорт
Попытка
Type = FieldADOЛкс.Type;
DefinedSize = FieldADOЛкс.DefinedSize;
Precision = FieldADOЛкс.Precision;
NumericScale = FieldADOЛкс.NumericScale;
Исключение
Возврат Неопределено;
КонецПопытки;
Возврат ПреобразоватьТипADO_Тип1СЛкс(Type,DefinedSize,Precision,NumericScale, Справочно);
КонецФункции
// возвращает описание типа 1С, соответствующее типу объекта ADODB.Parameter
// значение Неопределено соответствует значению произвольного типа 1С
Функция ParameterADO_ПолучитьТип1CЛкс(ParameterADOЛкс) Экспорт
Попытка
Type = ParameterADOЛкс.Type;
Size = ParameterADOЛкс.Size;
Precision = ParameterADOЛкс.Precision;
NumericScale = ParameterADOЛкс.NumericScale;
Исключение
Возврат Неопределено;
КонецПопытки;
Возврат ПреобразоватьТипADO_Тип1СЛкс(Type,Size,Precision,NumericScale);
КонецФункции
// возвращает структуру с полями объекта ADODB.Field
Функция FieldADOЛкс(стрName,стрType,чисDefinedSize,чисPrecision,чисNumericScale,Value=Неопределено) Экспорт
ПолеADO = Новый Структура("Name,Type,DefinedSize,Precision,NumericScale,Value");
ТипЧисло = Тип("Число");
Если стрName <> Неопределено Тогда
ПолеADO.Вставить("Name",СокрЛП(стрName));
КонецЕсли;
Если стрType <> Неопределено Тогда
Если ТипЗнч(стрType) = ТипЧисло Тогда
// дополнительный контроль числа на допустимое значение
ПолеADO.Вставить("Type",intTypeADOЛкс(strTypeADOЛкс(стрType)));
Иначе
ПолеADO.Вставить("Type",intTypeADOЛкс(стрType));
КонецЕсли;
КонецЕсли;
Если чисDefinedSize <> Неопределено Тогда
Если ТипЗнч(чисDefinedSize)=ТипЧисло Тогда
ПолеADO.Вставить("DefinedSize",Цел(чисDefinedSize));
Иначе
ПолеADO.Вставить("DefinedSize",0);
КонецЕсли;
КонецЕсли;
Если чисPrecision <> Неопределено Тогда
Если ТипЗнч(чисPrecision)=ТипЧисло Тогда
ПолеADO.Вставить("Precision",Цел(чисPrecision));
Иначе
ПолеADO.Вставить("Precision",0);
КонецЕсли;
КонецЕсли;
Если чисNumericScale <> Неопределено Тогда
Если ТипЗнч(чисNumericScale)=ТипЧисло Тогда
ПолеADO.Вставить("NumericScale",Цел(чисNumericScale));
Иначе
ПолеADO.Вставить("NumericScale",0);
КонецЕсли;
КонецЕсли;
Если Value <> Неопределено Тогда
ПолеADO.Вставить("Value",Value);
КонецЕсли;
Возврат ПолеADO;
КонецФункции
// возвращает структуру с полями объекта ADODB.Parameter
Функция ParameterADOЛкс(стрName,стрDirection,стрType,чисSize,чисNumericScale,чисPrecision,чисAttributes=0,Value=Неопределено) Экспорт
ПараметрADO = Новый Структура("Name,Direction,Type,Size,NumericScale,Precision,Attributes,Value");
ТипЧисло = Тип("Число");
Если стрName <> Неопределено Тогда
ПараметрADO.Вставить("Name",СокрЛП(стрName));
КонецЕсли;
Если чисAttributes <> Неопределено Тогда
Если ТипЗнч(чисAttributes)=ТипЧисло И чисAttributes > 0 Тогда
ПараметрADO.Вставить("Attributes",Цел(чисAttributes));
КонецЕсли;
КонецЕсли;
Если стрDirection <> Неопределено Тогда
Если ТипЗнч(стрDirection) = ТипЧисло Тогда
// дополнительный контроль числа на допустимое значение
ПараметрADO.Вставить("Direction",intDirectionParADOЛкс(strDirectionParADOЛкс(стрDirection)));
Иначе
ПараметрADO.Вставить("Direction",intDirectionParADOЛкс(стрDirection));
КонецЕсли;
КонецЕсли;
Если стрType <> Неопределено Тогда
Если ТипЗнч(стрType) = ТипЧисло Тогда
// дополнительный контроль числа на допустимое значение
ПараметрADO.Вставить("Type",intTypeADOЛкс(strTypeADOЛкс(стрType)));
Иначе
ПараметрADO.Вставить("Type",intTypeADOЛкс(стрType));
КонецЕсли;
КонецЕсли;
Если чисSize <> Неопределено Тогда
Если ТипЗнч(чисSize)=ТипЧисло Тогда
ПараметрADO.Вставить("Size",Цел(чисSize));
Иначе
ПараметрADO.Вставить("Size",0);
КонецЕсли;
КонецЕсли;
Если чисNumericScale <> Неопределено Тогда
Если ТипЗнч(чисNumericScale)=ТипЧисло Тогда
ПараметрADO.Вставить("NumericScale",Цел(чисNumericScale));
Иначе
ПараметрADO.Вставить("NumericScale",0);
КонецЕсли;
КонецЕсли;
Если чисPrecision <> Неопределено Тогда
Если ТипЗнч(чисPrecision)=ТипЧисло Тогда
ПараметрADO.Вставить("Precision",Цел(чисPrecision));
Иначе
ПараметрADO.Вставить("Precision",0);
КонецЕсли;
КонецЕсли;
Если Value <> Неопределено Тогда
ПараметрADO.Вставить("Value",Value);
КонецЕсли;
Возврат ПараметрADO;
КонецФункции
Функция DigitDECtoHEXЛкс(ЦыфраD)
Если ЦыфраD=0 Тогда
Возврат "0";
ИначеЕсли ЦыфраD>=1 И ЦыфраD<=9 Тогда
Возврат ""+ЦыфраD;
ИначеЕсли ЦыфраD=10 Тогда
Возврат "A";
ИначеЕсли ЦыфраD=11 Тогда
Возврат "B";
ИначеЕсли ЦыфраD=12 Тогда
Возврат "C";
ИначеЕсли ЦыфраD=13 Тогда
Возврат "D";
ИначеЕсли ЦыфраD=14 Тогда
Возврат "E";
ИначеЕсли ЦыфраD=15 Тогда
Возврат "F";
Иначе
Возврат "?";
КонецЕсли;
КонецФункции
Функция DigitHEXtoDECЛкс(ЦыфраH)
Если ЦыфраH="0" ИЛИ ЦыфраH="1" ИЛИ ЦыфраH="2" ИЛИ ЦыфраH="3" ИЛИ ЦыфраH="4" ИЛИ ЦыфраH="5" ИЛИ ЦыфраH="6" ИЛИ ЦыфраH="7" ИЛИ ЦыфраH="8" ИЛИ ЦыфраH="9" Тогда
Возврат Цел(ЦыфраH);
ИначеЕсли ЦыфраH="a" ИЛИ ЦыфраH="A" Тогда
Возврат 10;
ИначеЕсли ЦыфраH="b" ИЛИ ЦыфраH="B" Тогда
Возврат 11;
ИначеЕсли ЦыфраH="c" ИЛИ ЦыфраH="C" Тогда
Возврат 12;
ИначеЕсли ЦыфраH="d" ИЛИ ЦыфраH="D" Тогда
Возврат 13;
ИначеЕсли ЦыфраH="e" ИЛИ ЦыфраH="E" Тогда
Возврат 14;
ИначеЕсли ЦыфраH="f" ИЛИ ЦыфраH="F" Тогда
Возврат 15;
Иначе
Возврат -1;
КонецЕсли;
КонецФункции
Функция СтрокаHEXtoINTЛкс(Знач СтрокаH) Экспорт
ПрефиксH = Лев(СтрокаH,2);
Если ПрефиксH="0x"
ИЛИ ПрефиксH="0X"
ИЛИ ПрефиксH="0х"
ИЛИ ПрефиксH="0Х" Тогда
СтрокаH=Сред(СтрокаH,3);
КонецЕсли;
Если ПустаяСтрока(СтрокаH) Тогда
Возврат 0;
КонецЕсли;
ДлинаH=СтрДлина(СтрокаH);
ЧислоD=0;
Для о = 1 По ДлинаH Цикл
ЦыфраH = Сред(СтрокаH,о,1);
ЦифраD = DigitHEXtoDECЛкс(ЦыфраH);
Если ЦифраD<0 Тогда
Возврат -1; // нарушение формата 16-тиричного числа
КонецЕсли;
ЧислоD = 16*ЧислоD + ЦифраD;
КонецЦикла;
Возврат ЧислоD;
КонецФункции
// преобразует 16-тиричную строку в COMSafeArray
Функция СтрокаHEXtoCOMSafeArrayЛкс(Знач СтрокаH) Экспорт
ПрефиксH = Лев(СтрокаH,2);
Если Ложь
Или ПрефиксH="0x"
ИЛИ ПрефиксH="0X"
ИЛИ ПрефиксH="0х"
ИЛИ ПрефиксH="0Х"
Тогда
СтрокаH=Сред(СтрокаH,3);
КонецЕсли;
Байты =СтрДлина(СтрокаH);
Байты = 2*Окр(Байты/2,0,1);
ArrayДанные = Новый Массив;
Поза=1;
Для о=1 По Байты Цикл
ДваБайт = Сред(СтрокаH,Поза,2);
ЗначInt = СтрокаHEXtoINTЛкс(ДваБайт);
Если ЗначInt<0 Тогда
Возврат Неопределено;
КонецЕсли;
ArrayДанные.Добавить(ЗначInt);
Поза=Поза+2;
КонецЦикла;
Array = Новый COMSafeArray(ArrayДанные,"VT_UI1",Байты/2);
Возврат Array;
КонецФункции
// преобразует объект УникальныйИдентификатор в COMSafeArray
Функция GUIDToCOMSafeArrayЛкс(GUID) Экспорт
ГУИД = СтрЗаменить(GUID,"-",Символы.ПС);
Если СтрЧислоСтрок(ГУИД)<>5 Тогда
// нарушена каноническая структура строки ГУИД: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12)
Возврат Неопределено; // вдруг ...
КонецЕсли;
// Соответсвие байтов в поле BINARY(16) с частями ГУИД: 4,5,3,2,1 - проверено для 1с-8.1.14
СтрокаH = СтрПолучитьСтроку(ГУИД,4) + СтрПолучитьСтроку(ГУИД,5)+ СтрПолучитьСтроку(ГУИД,3)+ СтрПолучитьСтроку(ГУИД,2)+ СтрПолучитьСтроку(ГУИД,1);
//Сообщить("ГУИД = "+ГУИД);
//Сообщить("СтрокаH = "+СтрокаH);
Возврат СтрокаHEXtoCOMSafeArrayЛкс(СтрокаH);
КонецФункции
// преобразует значение уникального идентификатора ссылки в COMSafeArray
Функция СсылкаToCOMSafeArrayЛкс(Ссылка) Экспорт
Попытка
ГУИД = СокрЛП(Ссылка.УникальныйИдентификатор());
Исключение
// переданное значение не ссылка
Возврат Неопределено;
КонецПопытки;
Возврат GUIDToCOMSafeArrayЛкс(ГУИД);
КонецФункции
// преобразоваение значения COMSafeArray, содержащие 2-байтовые целые в шестнадцатиричную строку
Функция BinaryCOMSafeArrayToHEXЛкс(Array) Экспорт
СтрHEX="";
Если ТипЗнч(Array)<>Тип("COMSafeArray") Тогда
Возврат "?COMSafeArray?";
КонецЕсли;
Массив=Array.Выгрузить();
Для каждого Слово Из Массив Цикл
Если ТипЗнч(Слово)=Тип("Число") Тогда
Слово=Цел(Слово);
Если (Слово<0)ИЛИ(Слово>255) Тогда
СтрHEX=СтрHEX+"??";
Иначе
Байт1=Слово%16;
Байт2=Цел(Слово/16);
СтрHEX=СтрHEX+DigitDECtoHEXЛкс(Байт2)+DigitDECtoHEXЛкс(Байт1);
КонецЕсли;
Иначе
СтрHEX=СтрHEX+"??";
КонецЕсли;
КонецЦикла;
Возврат "0x"+СтрHEX;
КонецФункции
// возвращает свойства параметра ADO из переданной структуры
// с автоматическим подбором значений свойств по значению 1С (если свойство неопределено)
Процедура ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils=Неопределено)
Перем ТипЗначения1С;
Если ТипЗнч(стТипADO)=Тип("Структура") Тогда
стТипADO.Свойство("Direction",Direction);
стТипADO.Свойство("Type",Type);
стТипADO.Свойство("Precision",Precision);
стТипADO.Свойство("NumericScale",NumericScale);
стТипADO.Свойство("Size",Size);
стТипADO.Свойство("Attributes",Attributes);
стТипADO.Свойство("ТипЗначения1С",ТипЗначения1С);
КонецЕсли;
Если Истина
И ТипЗнч(ТипЗначения1С) = Тип("ОписаниеТипов")
И ТипЗначения1С.Типы().Количество() > 0
И НЕ ТипЗначения1С.СодержитТип(ТипЗнч(Значение1С))
Тогда
// приведем значение 1С к указанному типу (актуально для значений Null, возвращаемых запросами 1С)
Значение1С = ТипЗначения1С.ПривестиЗначение(Значение1С);
КонецЕсли;
Если Direction=Неопределено Тогда
Direction=1; // 1 - входящий(Default) ... или 0 - неизвестно ???
КонецЕсли;
Тип1С=ТипЗнч(Значение1С);
Попытка
Ссылка = Значение1С.Ссылка;
Исключение
Ссылка = Неопределено;
Попытка
// перечисления стоят особняком среди "ссылочных" типов
МетаДата = Значение1С.Метаданные();
Если Метаданные.Перечисления.Содержит(МетаДата) Тогда
Ссылка = Значение1С;
КонецЕсли;
Исключение
КонецПопытки;
КонецПопытки;
Если Type=Неопределено Тогда
// попытаемся подобрать по типу 1С
Если Тип1С=Тип("Число") Тогда
//Type = 4; // adSingle
//Type = 5; // adDouble
//Type = 14; // adDecimal
//Type = 131; // adNumeric
//Type = 139; // adVarNumeric
Если Цел(Значение1С)=Значение1С Тогда
Если ?(Значение1С<0,-1,1)*Значение1С <= 2147483647 Тогда // 2^32-1
Type = intTypeADOЛкс("adInteger"); // 3
Иначе
Type = intTypeADOЛкс("adBigInt"); // 20
КонецЕсли;
Иначе
Type = 14; // adDecimal
КонецЕсли;
ИначеЕсли Тип1С=Тип("Строка") Тогда
//Type = 129; // adChar
//Type = 130; // adWChar
//Type = 200; // adVarChar
//Type = 201; // adLongVarChar
//Type = 202; // adVarWChar
//Type = 203; // adLongVarWChar
Если СтрДлина(Значение1С)<=4000 Тогда
Type = intTypeADOЛкс("adVarChar"); // 200
Иначе
Type = intTypeADOЛкс("adLongVarChar"); // 201
КонецЕсли;
ИначеЕсли Тип1С=Тип("Дата") Тогда
//Type = 134; // adDBTime
Если НачалоДня(Значение1С)=Значение1С Тогда
Type = intTypeADOЛкс("adDBDate"); // 133
Иначе
Type = intTypeADOЛкс("adDBTimeStamp"); // 135
КонецЕсли;
ИначеЕсли Тип1С=Тип("Булево") Тогда
Type = intTypeADOЛкс("adBoolean"); // 11
ИначеЕсли Тип1С=Тип("УникальныйИдентификатор") Тогда
Type = intTypeADOЛкс("adBinary"); // 128
Size = 16;
Иначе
Если Ссылка <> Неопределено Тогда
// ссылочный тип - преобразуем в COMSafeArray
Type = intTypeADOЛкс("adBinary"); // 128
Size = 16;
Иначе
Type = intTypeADOЛкс("adEmpty"); // 0? (Default)
КонецЕсли;
КонецЕсли;
КонецЕсли;
// ADOUtils.V8DateToDBDate( Дата ) // с учетом YearOffset
// ADOUtils.BooleanParameter( Значение ) // COMSafeArray(1)
// ADOUtils.TypeParameter( Значение ) // COMSafeArray(1) *_TYPE
// ADOUtils.TableNumberParameter( Значение ) // COMSafeArray(4) *_RTRef
// ADOUtils.DataVersionParameter( Значение ) // COMSafeArray(8) _Version
// ADOUtils.RRefParameter( Значение ) // COMSafeArray(16) *IDRRef
Если Ложь
Или Type = intTypeADOЛкс("adBinary") // 128
Или Type = intTypeADOЛкс("adVarBinary")
Тогда // 204
//Если ADOUtils = Неопределено Тогда
// ADOUtils = ПолучитьADOUtils();
// Если ADOUtils = Неопределено Тогда
// ADOUtils = Null; // для избежания повторных инициализаций
// КонецЕсли;
//КонецЕсли;
Если Ссылка <> Неопределено Тогда
// ссылочный тип - преобразуем в COMSafeArray(16)
ЗначениеADO = СсылкаToCOMSafeArrayЛкс(Ссылка);
//Если ADOUtils = Неопределено ИЛИ ADOUtils = Null Тогда
// ЗначениеADO = СсылкаToCOMSafeArrayЛкс(Ссылка);
//Иначе
// ЗначениеADO = ADOUtils.RRefParameter(Ссылка);
//КонецЕсли;
ИначеЕсли Тип1С=Тип("УникальныйИдентификатор") Тогда
// ГУИД - преобразуем в COMSafeArray(16)
ЗначениеADO = GUIDToCOMSafeArrayЛкс(Значение1С);
ИначеЕсли Тип1С=Тип("Булево") Тогда
// Булево - преобразуем в COMSafeArray(1)
ЗначениеADO = СтрокаHEXtoCOMSafeArrayЛкс(?(Значение1С,"0x01","0x00"));
//Если ADOUtils = Неопределено ИЛИ ADOUtils = Null Тогда
// ЗначениеADO = СтрокаHEXtoCOMSafeArrayЛкс(?(Значение1С,"0x01","0x00"));
//Иначе
// ЗначениеADO = ADOUtils.BooleanParameter(Значение1С);
//КонецЕсли;
Иначе
КонецЕсли;
КонецЕсли;
Если Precision=Неопределено Тогда
Если Ложь
Или Type = intTypeADOЛкс("adDecimal") // 14
ИЛИ Type = intTypeADOЛкс("adNumeric") // 131
ИЛИ Type = intTypeADOЛкс("adVarNumeric") // 139
Тогда
Precision = СтрДлина(СтрЗаменить(Строка(Значение1С)," ",""));
КонецЕсли;
КонецЕсли;
Если NumericScale=Неопределено Тогда
Если Ложь
Или Type = intTypeADOЛкс("adDecimal") // 14
ИЛИ Type = intTypeADOЛкс("adNumeric") // 131
ИЛИ Type = intTypeADOЛкс("adVarNumeric") // 139
Тогда
NumericScale = СтрДлина(Строка(Значение1С-Цел(Значение1С)));
КонецЕсли;
КонецЕсли;
Если Size=Неопределено Тогда
Если Ложь
Или Type = intTypeADOЛкс("adChar") // 129
ИЛИ Type = intTypeADOЛкс("adWChar") // 130
ИЛИ Type = intTypeADOЛкс("adVarChar") // 200
//ИЛИ Type = intTypeADOЛкс("adLongVarChar") // 201
ИЛИ Type = intTypeADOЛкс("adVarWChar") // 202
//ИЛИ Type = intTypeADOЛкс("adLongVarWChar") // 203
Тогда
Size = СтрДлина(Значение1С);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// создает массив объектов ADODB.Parameter по списку параметров ADO и по списку типов ADO
Функция ParametersArrayПолучитьЛкс(стПараметры,стПарТипADO, ADOUtils = Неопределено) Экспорт
ParametersArray = Новый Массив;
ТипаМассив = Тип("Массив");
ТипаСоответствие = Тип("Соответствие");
cтПараметрыТип = ТипЗнч(стПараметры);
cтПарТипADOТип = ТипЗнч(стПарТипADO);
Если стПараметры = Неопределено Тогда
Возврат ParametersArray;
ИначеЕсли cтПараметрыТип = ТипаМассив ИЛИ cтПараметрыТип = ТипаСоответствие Тогда
Если стПарТипADO <> Неопределено И cтПарТипADOТип <> cтПараметрыТип Тогда
ВызватьИсключение(
"Тип значения списка типов параметров ADO ('"+cтПарТипADOТип+"') не равен
|типу значения списка параметров запроса ('"+cтПараметрыТип+"') !");
КонецЕсли;
Иначе
ВызватьИсключение(
"Не предусмотренный тип значения списка параметров запроса ('"+cтПараметрыТип+"') !");
КонецЕсли;
ОбъектЗапрос = Новый COMОбъект("ADODB.Command");
Индекс = 0;
Для каждого Параметр Из стПараметры Цикл
Если cтПараметрыТип = ТипаМассив Тогда
ПараметрИмя = Неопределено;
Значение1С = Параметр;
ИначеЕсли cтПараметрыТип = ТипаСоответствие Тогда
ПараметрИмя = СокрЛП(Параметр.Ключ);
Значение1С = Параметр.Значение;
Иначе
Продолжить;
КонецЕсли;
Индекс = Индекс + 1;
стТипADO=Неопределено;
Если cтПарТипADOТип=ТипаМассив Тогда
Если Индекс<=стПарТипADO.Количество()-1 Тогда
стТипADO = стПарТипADO.Получить(Индекс);
КонецЕсли;
ИначеЕсли cтПарТипADOТип = ТипаСоответствие Тогда
стТипADO = стПарТипADO.Получить(Параметр.Ключ);
КонецЕсли;
ЗначениеADO = Неопределено;
Attributes = Неопределено;
Direction = Неопределено;
Type = Неопределено;
Precision = Неопределено;
NumericScale = Неопределено;
Size = Неопределено; // прочитаем свойства параметра ADO по полученной структуре типа и значению 1С
ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils);
// создадим параметр ADO и заполним его свойства
Parameter = ОбъектЗапрос.CreateParameter();
Если НЕ ПустаяСтрока(Type) Тогда
Parameter.Type=Type;
КонецЕсли;
Если НЕ ПустаяСтрока(Direction) Тогда
Parameter.Direction=Direction;
КонецЕсли;
Если НЕ ПустаяСтрока(Size) Тогда
Parameter.Size=Size;
КонецЕсли;
Если НЕ ПустаяСтрока(Attributes) Тогда
Parameter.Attributes=Attributes;
КонецЕсли;
Если НЕ ПустаяСтрока(ПараметрИмя) Тогда
Parameter.Name = ПараметрИмя;
КонецЕсли;
Если ЗначениеADO = Неопределено Тогда
Parameter.Value=Значение1С; // преобразование не явное
Иначе
Parameter.Value=ЗначениеADO;
КонецЕсли;
// добавим в массив
ParametersArray.Добавить(Parameter);
КонецЦикла;
Возврат ParametersArray;
КонецФункции // ParametersArrayПолучитьЛкс()
// формирует массив или соответствие со значениями параметров запроса из строки таблицы значений
Функция стПараметры_Получить_ТЗЛкс(тзПараметры,СтрокаПараметров,NamedParameters,Знач ParametersPrefix) Экспорт
Если NamedParameters=Истина Тогда
ParametersPrefix=СокрЛП(ParametersPrefix);
стПараметры=Новый Соответствие;
Для каждого Колонка Из тзПараметры.Колонки Цикл
стПараметры.Вставить(ParametersPrefix+Колонка.Имя,СтрокаПараметров.Получить(тзПараметры.Колонки.Индекс(Колонка)));
КонецЦикла;
Иначе
стПараметры=Новый Массив;
Для каждого Колонка Из тзПараметры.Колонки Цикл
стПараметры.Добавить(СтрокаПараметров.Получить(тзПараметры.Колонки.Индекс(Колонка)));
КонецЦикла;
КонецЕсли;
Возврат стПараметры;
КонецФункции // стПараметры_Получить_ТЗЛкс()
// добавляет и устанавливает объект ADODB.Parameter в коллекцию параметров
// если не заданы свойства параметра ADO, делается попытка их подбора по типу значения 1С
Функция ADODBCommand_УстановитьПараметрПо1СЛкс(ОбъектЗапрос,Инициализация,Индекс,Name,стТипADO,Значение1С,ADOUtils,ЕррорИнфо) Экспорт
ЗначениеADO=Неопределено;
Attributes=Неопределено;
Direction=Неопределено;
Type=Неопределено;
Precision=Неопределено;
NumericScale=Неопределено;
Size=Неопределено; // прочитаем свойства параметра ADO из переданной структуры по значению 1С
ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils);
ЕррорИнфо="";
Попытка
Если ОбъектЗапрос.Prepared = Ложь ИЛИ Инициализация <> Ложь Тогда
// инициализация параметров запроса
Добавить = Ложь;
Если Name = Неопределено Тогда
// по переданному индексу параметра
Parameter = ОбъектЗапрос.CreateParameter();
Добавить = Истина; // создаем без имени
Иначе
// по переданному имени параметра
Попытка
// если уже есть параметр с именем - используем его
Parameter = ОбъектЗапрос.Parameters.Item(Name);
Исключение
Parameter = Неопределено;
КонецПопытки;
Если Parameter = Неопределено Тогда
// если нет - создаем с указанным именем
Parameter = ОбъектЗапрос.CreateParameter();
Parameter.Name = Name;
Добавить = Истина;
КонецЕсли;
КонецЕсли;
Если НЕ ПустаяСтрока(Type) Тогда
Parameter.Type=Type;
КонецЕсли;
Если НЕ ПустаяСтрока(Direction) Тогда
Parameter.Direction=Direction;
КонецЕсли;
Если НЕ ПустаяСтрока(Size) Тогда
Parameter.Size=Size;
КонецЕсли;
Если НЕ ПустаяСтрока(Attributes) И Attributes <> 0 Тогда
Parameter.Attributes=Attributes;
КонецЕсли;
Если Добавить = Истина Тогда
ОбъектЗапрос.Parameters.Append(Parameter);
КонецЕсли;
Иначе
// установка параметра предварительно подготовленного параметризованного запроса
Если Name = Неопределено Тогда
// по переданному индексу параметра
Parameter = ОбъектЗапрос.Parameters.Item(Индекс);
Иначе
// по переданному имени параметра
Parameter = ОбъектЗапрос.Parameters.Item(Name);
КонецЕсли;
КонецЕсли;
Если ЗначениеADO = Неопределено Тогда
Parameter.Value=Значение1С; // преобразование не явное
Иначе
Parameter.Value=ЗначениеADO;
КонецЕсли;
Исключение
ЕррорИнфо=ОписаниеОшибки();
Возврат Ложь;
КонецПопытки;
Возврат Истина;
КонецФункции
// ^^^ УСТАНОВКА ПАРАМЕТРОВ ЗАПРОСА ADO ^^^
// *** ПЕРЕЧИСЛЕНИЯ ADO ***
// возвращает строковое представление типа параметра ADO(свойства Direction) по его числовому значению
Функция strDirectionParADOЛкс(intTypeADOЛкс) Экспорт
intType = Цел(intTypeADOЛкс);
Если intType = 0 Тогда Возврат "adParamUnknown"; // Direction unknown
ИначеЕсли intType = 1 Тогда Возврат "adParamInput"; // Input parameter (Default)
ИначеЕсли intType = 2 Тогда Возврат "adParamOutput"; // Output parameter
ИначеЕсли intType = 3 Тогда Возврат "adParamInputOutput"; // Input and output parameter
ИначеЕсли intType = 4 Тогда Возврат "adParamReturnValue"; // Return value
Иначе Возврат "adParamInput"; // как 1
КонецЕсли;
КонецФункции
// возвращает числовое значения типа параметра ADO(свойства Direction) по его числовому представлению
Функция intDirectionParADOЛкс(strTypeADOЛкс) Экспорт
strType = НРег(strTypeADOЛкс);
Если strType = Нрег("adParamUnknown") Тогда Возврат 0; // Direction unknown
ИначеЕсли strType = Нрег("adParamInput") Тогда Возврат 1; // Input parameter (Default)
ИначеЕсли strType = Нрег("adParamOutput") Тогда Возврат 2; // Output parameter
ИначеЕсли strType = Нрег("adParamInputOutput") Тогда Возврат 3; // Input and output parameter
ИначеЕсли strType = Нрег("adParamReturnValue") Тогда Возврат 4; // Return value
Иначе Возврат 1; // adParamInput
КонецЕсли;
КонецФункции
// возвращает строковое представление типа значения ADO по его числовому значению
Функция strTypeADOЛкс(intTypeADOЛкс) Экспорт
intType = Цел(intTypeADOЛкс);
Если intType = 0 Тогда Возврат "adEmpty"; // no value
ИначеЕсли intType = 2 Тогда Возврат "adSmallInt"; // 2-byte signed integer
ИначеЕсли intType = 3 Тогда Возврат "adInteger"; // 4-byte signed integer
ИначеЕсли intType = 4 Тогда Возврат "adSingle"; // single-precision floating-point value
ИначеЕсли intType = 5 Тогда Возврат "adDouble"; // double-precision floating-point value
ИначеЕсли intType = 6 Тогда Возврат "adCurrency"; // currency value
ИначеЕсли intType = 7 Тогда Возврат "adDate"; // number of days since December 30, 1899 + the fraction of a day
ИначеЕсли intType = 8 Тогда Возврат "adBSTR"; // null-terminated character string
ИначеЕсли intType = 9 Тогда Возврат "adIDispatch"; // pointer to an IDispatch interface on a COM object(currently not supported by ADO)
ИначеЕсли intType = 10 Тогда Возврат "adError"; // 32-bit error code
ИначеЕсли intType = 11 Тогда Возврат "adBoolean"; // boolean value
ИначеЕсли intType = 12 Тогда Возврат "adVariant"; // automation Variant(currently not supported by ADO)
ИначеЕсли intType = 13 Тогда Возврат "adIUnknown"; // pointer to an IUnknown interface on a COM object(currently not supported by ADO)
ИначеЕсли intType = 14 Тогда Возврат "adDecimal"; // exact numeric value with a fixed precision and scale
ИначеЕсли intType = 16 Тогда Возврат "adTinyInt"; // 1-byte signed integer
ИначеЕсли intType = 17 Тогда Возврат "adUnsignedTinyInt"; // 1-byte unsigned integer
ИначеЕсли intType = 18 Тогда Возврат "adUnsignedSmallInt"; // 2-byte unsigned integer
ИначеЕсли intType = 19 Тогда Возврат "adUnsignedInt"; // 4-byte unsigned integer
ИначеЕсли intType = 20 Тогда Возврат "adBigInt"; // 8-byte signed integer
ИначеЕсли intType = 21 Тогда Возврат "adUnsignedBigInt"; // 8-byte unsigned integer
ИначеЕсли intType = 64 Тогда Возврат "adFileTime"; // number of 100-nanosecond intervals since January 1,1601
ИначеЕсли intType = 72 Тогда Возврат "adGUID"; // globally unique identifier (GUID)
ИначеЕсли intType = 128 Тогда Возврат "adBinary"; // binary value
ИначеЕсли intType = 129 Тогда Возврат "adChar"; // string value
ИначеЕсли intType = 130 Тогда Возврат "adWChar"; // null-terminated Unicode character string
ИначеЕсли intType = 131 Тогда Возврат "adNumeric"; // exact numeric value with a fixed precision and scale
ИначеЕсли intType = 132 Тогда Возврат "adUserDefined"; // user-defined variable
ИначеЕсли intType = 133 Тогда Возврат "adDBDate"; // date value (yyyymmdd)
ИначеЕсли intType = 134 Тогда Возврат "adDBTime"; // time value (hhmmss)
ИначеЕсли intType = 135 Тогда Возврат "adDBTimeStamp"; // date/time stamp (yyyymmddhhmmss plus a fraction in billionths)
ИначеЕсли intType = 136 Тогда Возврат "adChapter"; // 4-byte chapter value that identifies rows in a child rowset
ИначеЕсли intType = 138 Тогда Возврат "adPropVariant"; // automation PROPVARIANT
ИначеЕсли intType = 139 Тогда Возврат "adVarNumeric"; // numeric value(Parameter object only)
ИначеЕсли intType = 200 Тогда Возврат "adVarChar"; // string value (Parameter object only)
ИначеЕсли intType = 201 Тогда Возврат "adLongVarChar"; // long string value
ИначеЕсли intType = 202 Тогда Возврат "adVarWChar"; // null-terminated Unicode character string
ИначеЕсли intType = 203 Тогда Возврат "adLongVarWChar"; // long null-terminated Unicode string value
ИначеЕсли intType = 204 Тогда Возврат "adVarBinary"; // binary value (Parameter object only)
ИначеЕсли intType = 205 Тогда Возврат "adLongVarBinary"; // long binary value
ИначеЕсли intType = 8192 Тогда Возврат "AdArray"; // 0x2000, flag value combined with another data type constant, indicates an array of that other data type
Иначе Возврат "adEmpty"; // как 0
КонецЕсли;
КонецФункции
// возвращает числовое значение типа значения ADO по его строковому представлению
Функция intTypeADOЛкс(strTypeADOЛкс) Экспорт
strType = НРег(strTypeADOЛкс);
Если strType = НРег("adEmpty") Тогда Возврат 0; // no value
ИначеЕсли strType = НРег("adSmallInt") Тогда Возврат 2; // 2-byte signed integer
ИначеЕсли strType = НРег("adInteger") Тогда Возврат 3; // 4-byte signed integer
ИначеЕсли strType = НРег("adSingle") Тогда Возврат 4; // single-precision floating-point value
ИначеЕсли strType = НРег("adDouble") Тогда Возврат 5; // double-precision floating-point value
ИначеЕсли strType = НРег("adCurrency") Тогда Возврат 6; // currency value
ИначеЕсли strType = НРег("adDate") Тогда Возврат 7; // number of days since December 30, 1899 + the fraction of a day
ИначеЕсли strType = НРег("adBSTR") Тогда Возврат 8; // null-terminated character string
ИначеЕсли strType = НРег("adIDispatch") Тогда Возврат 9; // pointer to an IDispatch interface on a COM object(currently not supported by ADO)
ИначеЕсли strType = НРег("adError") Тогда Возврат 10; // 32-bit error code
ИначеЕсли strType = НРег("adBoolean") Тогда Возврат 11; // boolean value
ИначеЕсли strType = НРег("adVariant") Тогда Возврат 12; // automation Variant(currently not supported by ADO)
ИначеЕсли strType = НРег("adIUnknown") Тогда Возврат 13; // pointer to an IUnknown interface on a COM object(currently not supported by ADO)
ИначеЕсли strType = НРег("adDecimal") Тогда Возврат 14; // exact numeric value with a fixed precision and scale
ИначеЕсли strType = НРег("adTinyInt") Тогда Возврат 16; // 1-byte signed integer
ИначеЕсли strType = НРег("adUnsignedTinyInt") Тогда Возврат 17; // 1-byte unsigned integer
ИначеЕсли strType = НРег("adUnsignedSmallInt") Тогда Возврат 18;// 2-byte unsigned integer
ИначеЕсли strType = НРег("adUnsignedInt") Тогда Возврат 19; // 4-byte unsigned integer
ИначеЕсли strType = НРег("adBigInt") Тогда Возврат 20; // 8-byte signed integer
ИначеЕсли strType = НРег("adUnsignedBigInt") Тогда Возврат 21; // 8-byte unsigned integer
ИначеЕсли strType = НРег("adFileTime") Тогда Возврат 64; // number of 100-nanosecond intervals since January 1,1601
ИначеЕсли strType = НРег("adGUID") Тогда Возврат 72; // globally unique identifier (GUID)
ИначеЕсли strType = НРег("adBinary") Тогда Возврат 128; // binary value
ИначеЕсли strType = НРег("adChar") Тогда Возврат 129; // string value
ИначеЕсли strType = НРег("adWChar") Тогда Возврат 130; // null-terminated Unicode character string
ИначеЕсли strType = НРег("adNumeric") Тогда Возврат 131; // exact numeric value with a fixed precision and scale
ИначеЕсли strType = НРег("adUserDefined") Тогда Возврат 132; // user-defined variable
ИначеЕсли strType = НРег("adDBDate") Тогда Возврат 133; // date value (yyyymmdd)
ИначеЕсли strType = НРег("adDBTime") Тогда Возврат 134; // time value (hhmmss)
ИначеЕсли strType = НРег("adDBTimeStamp") Тогда Возврат 135; // date/time stamp (yyyymmddhhmmss plus a fraction in billionths)
ИначеЕсли strType = НРег("adChapter") Тогда Возврат 136; // 4-byte chapter value that identifies rows in a child rowset
ИначеЕсли strType = НРег("adPropVariant") Тогда Возврат 138; // automation PROPVARIANT
ИначеЕсли strType = НРег("adVarNumeric") Тогда Возврат 139; // numeric value(Parameter object only)
ИначеЕсли strType = НРег("adVarChar") Тогда Возврат 200; // string value (Parameter object only)
ИначеЕсли strType = НРег("adLongVarChar") Тогда Возврат 201; // long string value
ИначеЕсли strType = НРег("adVarWChar") Тогда Возврат 202; // null-terminated Unicode character string
ИначеЕсли strType = НРег("adLongVarWChar") Тогда Возврат 203; // long null-terminated Unicode string value
ИначеЕсли strType = НРег("adVarBinary") Тогда Возврат 204; // binary value (Parameter object only)
ИначеЕсли strType = НРег("adLongVarBinary") Тогда Возврат 205; // long binary value
ИначеЕсли strType = НРег("AdArray") Тогда Возврат 8192; // 0x2000, flag value combined with another data type constant, indicates an array of that other data type
Иначе Возврат 0; // adEmpty
КонецЕсли;
КонецФункции
// возвращает числовое значение типа курсора по его строковому представлению
Функция strCursorTypeЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = -1 Тогда Возврат "adOpenUnspecified"; // Does not specify the type of cursor
ИначеЕсли intV = 0 Тогда Возврат "adOpenForwardOnly"; // Default. Uses a forward-only cursor. Like a static cursor, except... (Default)
ИначеЕсли intV = 1 Тогда Возврат "adOpenKeyset"; // Uses a keyset cursor. Like a dynamic cursor, except...
ИначеЕсли intV = 2 Тогда Возврат "adOpenDynamic"; // Uses a dynamic cursor
ИначеЕсли intV = 3 Тогда Возврат "adOpenStatic"; // Uses a static cursor
Иначе Возврат "adOpenForwardOnly"; // как 0
КонецЕсли;
КонецФункции
// возвращает строковое представление типа курсора по его числовому значению
Функция intCursorTypeЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adOpenUnspecified") Тогда Возврат -1; // Does not specify the type of cursor
ИначеЕсли strV = Нрег("adOpenForwardOnly") Тогда Возврат 0; // Default. Uses a forward-only cursor. Like a static cursor, except... (Default
ИначеЕсли strV = Нрег("adOpenKeyset") Тогда Возврат 1; // Uses a keyset cursor. Like a dynamic cursor, except...
ИначеЕсли strV = Нрег("adOpenDynamic") Тогда Возврат 2; // Uses a dynamic cursor
ИначеЕсли strV = Нрег("adOpenStatic") Тогда Возврат 3; // Uses a static cursor
Иначе Возврат 0; // adOpenForwardOnly
КонецЕсли;
КонецФункции
// возвращает числовое значение местоположения курсора по его строковому представлению
Функция strCursorLocationЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = 1 Тогда Возврат "adUseNone"; // Does not use cursor services
ИначеЕсли intV = 2 Тогда Возврат "adUseServer"; // Uses a server-side cursor (Default)
ИначеЕсли intV = 3 Тогда Возврат "adParamOutput"; // Uses a client-side cursor supplied by a local cursor library
Иначе Возврат "adUseServer"; // как 2
КонецЕсли;
КонецФункции
// возвращает строковое представление местоположения курсора по его числовому значению
Функция intCursorLocationЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adUseNone") Тогда Возврат 1; // Does not use cursor services
ИначеЕсли strV = Нрег("adUseServer") Тогда Возврат 2; // Uses a server-side cursor (Default)
ИначеЕсли strV = Нрег("adParamOutput") Тогда Возврат 3; // Uses a client-side cursor supplied by a local cursor library
Иначе Возврат 2; // adUseServer
КонецЕсли;
КонецФункции
// возвращает числовое значение типа блокировки данных по его строковому представлению
Функция strLockTypeЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = -1 Тогда Возврат "adLockUnspecified"; // Unspecified type of lock. Clones inherits lock type from the original Recordset
ИначеЕсли intV = 1 Тогда Возврат "adLockReadOnly"; // Read-only records
ИначеЕсли intV = 2 Тогда Возврат "adLockPessimistic"; // Pessimistic locking, record by record. The provider lock records immediately after editing
ИначеЕсли intV = 3 Тогда Возврат "adLockOptimistic"; // Optimistic locking, record by record. The provider lock records only when calling update
ИначеЕсли intV = 4 Тогда Возврат "adLockBatchOptimistic"; // Optimistic batch updates. Required for batch update mode
Иначе Возврат "adLockUnspecified"; // как -1
КонецЕсли;
КонецФункции
// возвращает строковое представление типа блокировки данных по его числовому значению
Функция intLockTypeЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adLockUnspecified") Тогда Возврат -1; // Unspecified type of lock
ИначеЕсли strV = Нрег("adLockReadOnly") Тогда Возврат 1; // Read-only records
ИначеЕсли strV = Нрег("adLockPessimistic") Тогда Возврат 2; // Pessimistic locking, record by record. The provider lock records immediately after editing
ИначеЕсли strV = Нрег("adLockOptimistic") Тогда Возврат 3; // Optimistic locking, record by record. The provider lock records only when calling update
ИначеЕсли strV = Нрег("adLockBatchOptimistic") Тогда Возврат 4; // Optimistic batch updates. Required for batch update mode
Иначе Возврат -1; // adLockUnspecified
КонецЕсли;
КонецФункции
// возвращает числовое значение опции MarshalOptions по его строковому представлению
Функция strMarshalOptionsЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = 0 Тогда Возврат "adMarshalAll"; // Returns all rows (Default)
ИначеЕсли intV = 1 Тогда Возврат "adMarshalModifiedOnly"; // Returns only modified rows
Иначе Возврат "adMarshalAll"; // как 0
КонецЕсли;
КонецФункции
// возвращает строковое представление опции MarshalOptions по его числовому значению
Функция intMarshalOptionsЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adMarshalAll") Тогда Возврат 0; // Returns all rows (Default)
ИначеЕсли strV = Нрег("adMarshalModifiedOnly") Тогда Возврат 1; // Returns only modified rows
Иначе Возврат 0; // adMarshalAll
КонецЕсли;
КонецФункции
// возвращает строковое представление типа команды ADO по его числовому значению
Функция strCommandTypeADOЛкс(intTypeADOЛкс) Экспорт
Если ТипЗнч(intTypeADOЛкс) = Тип("Число") Тогда
intType = Цел(intTypeADOЛкс);
Иначе
intType = 0;
КонецЕсли;
Если intType = -1 Тогда Возврат "adCmdUnspecified"; // Unspecified type of command
ИначеЕсли intType = 1 Тогда Возврат "adCmdText"; // строка оператора T-SQL
ИначеЕсли intType = 2 Тогда Возврат "adCmdTable"; // имя таблицы для выборки строк
ИначеЕсли intType = 4 Тогда Возврат "adCmdStoredProc"; // имя хранимой процедуры
ИначеЕсли intType = 8 Тогда Возврат "adCmdUnknown"; // неизвестно, проверять провайдером (Default)
ИначеЕсли intType = 256 Тогда Возврат "adCmdFile"; // имя файла of a persistently stored Recordset (with Recordset.Open or Requery only)
ИначеЕсли intType = 512 Тогда Возврат "adCmdTableDirect"; // имя таблицы whose columns are all returned (with Recordset.Open or Requery only)
Иначе Возврат "adCmdUnknown"; // как 8
КонецЕсли;
КонецФункции
// возвращает числовое значение типа команды ADO по его строковому представлению
Функция intCommandTypeADOЛкс(strTypeADOЛкс) Экспорт
strType = Нрег(strTypeADOЛкс);
Если strType = Нрег("adCmdUnspecified") Тогда Возврат -1; // Unspecified type of command
ИначеЕсли strType = Нрег("adCmdText") Тогда Возврат 1; // строка оператора T-SQL
ИначеЕсли strType = Нрег("adCmdTable") Тогда Возврат 2; // имя таблицы для выборки строк
ИначеЕсли strType = Нрег("adCmdStoredProc") Тогда Возврат 4; // имя хранимой процедуры
ИначеЕсли strType = Нрег("adCmdUnknown") Тогда Возврат 8; // неизвестно, проверять провайдером (Default)
ИначеЕсли strType = Нрег("adCmdFile") Тогда Возврат 256; // имя файла of a persistently stored Recordset (with Recordset.Open or Requery only)
ИначеЕсли strType = Нрег("adCmdTableDirect") Тогда Возврат 512; // имя таблицы whose columns are all returned (with Recordset.Open or Requery only)
Иначе Возврат 8; // adCmdUnknown
КонецЕсли;
КонецФункции
// возвращает строковое представление типа команды ADO по его числовому значению
Функция strExecuteOptionЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = -1 Тогда Возврат "adOptionUnspecified"; // Unspecified command
ИначеЕсли intV = 16 Тогда Возврат "adAsyncExecute"; // The command should execute asynchronously
ИначеЕсли intV = 32 Тогда Возврат "adAsyncFetch"; // The remaining rows after specified in the CacheSize should be retrieved asynchronously
ИначеЕсли intV = 64 Тогда Возврат "adAsyncFetchNonBlocking"; // The main thread never blocks while retrieving.
ИначеЕсли intV = 128 Тогда Возврат "adExecuteNoRecords"; // Discard, not return retrieved rows (with Command or Connection.Execute only)
ИначеЕсли intV = 256 Тогда Возврат "adExecuteStream"; // The results of a command execution is a stream (with Connection.Execute only)
ИначеЕсли intV = 512 Тогда Возврат "adExecuteRecord"; // Return a single row as a Record object
Иначе Возврат "adOptionUnspecified"; // как -1
КонецЕсли;
КонецФункции
// возвращает числовое значение типа команды ADO по его строковому представлению
Функция intExecuteOptionЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adOptionUnspecified") Тогда Возврат -1; // Unspecified command
ИначеЕсли strV = Нрег("adAsyncExecute") Тогда Возврат 16; // The command should execute asynchronously
ИначеЕсли strV = Нрег("adAsyncFetch") Тогда Возврат 32; // The remaining rows after specified in the CacheSize should be retrieved asynchronously
ИначеЕсли strV = Нрег("adAsyncFetchNonBlocking") Тогда Возврат 64; // The main thread never blocks while retrieving
ИначеЕсли strV = Нрег("adExecuteNoRecords") Тогда Возврат 128; // Discard, not return retrieved rows (with Command or Connection.Execute only)
ИначеЕсли strV = Нрег("adExecuteStream") Тогда Возврат 256; // The results of a command execution is a stream (with Connection.Execute only)
ИначеЕсли strV = Нрег("adExecuteRecord") Тогда Возврат 512; // Return a single row as a Record object
Иначе Возврат -1; // adOptionUnspecified
КонецЕсли;
КонецФункции
// возвращает строковое представление опции аттрибутов параметра ADO по числовому значению опции
Функция strParameterADOAttributesЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = 16 Тогда Возврат "adParamSigned"; // The parameter will accept signed values.
ИначеЕсли intV = 64 Тогда Возврат "adParamNullAble"; // The parameter will accept null values.
ИначеЕсли intV = 128 Тогда Возврат "adParamLong"; // The parameter will accept long binary data.
Иначе Возврат "adParamSigned"; // как 16
КонецЕсли;
КонецФункции
// возвращает числовое значение оцции аттрибутов параметра ADO по строковому представлению опции
Функция intParameterADOAttributesЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adParamSigned") Тогда Возврат 16; // The parameter will accept signed values.
ИначеЕсли strV = Нрег("adParamNullAble") Тогда Возврат 64; // The parameter will accept null values.
ИначеЕсли strV = Нрег("adParamLong") Тогда Возврат 128; // The parameter will accept long binary data.
Иначе Возврат 16; // adParamSigned
КонецЕсли;
КонецФункции
// ^^^ ПЕРЕЧИСЛЕНИЯ ADO ^^^
// ADO
// ************************
// В платформе все корневые элементы древовидных структур содержат в свойстве Родитель Неопределено.
// Поэтому возникает неудобство при работе с этим свойством, заключающееся в необходимости часто проверять его значение на Неопределено.
// Параметры:
// СтрокаДерева - СтрокаДереваЗначений, <Элемент любого иерархического объекта, имеющий родителя>
// Дерево - <Иерархический объект, которому принадлежит элемент> - для дерева значений не нужно передавать
//
Функция ПолучитьРодителяСтрокиДереваЛкс(СтрокаДерева, Дерево = Неопределено) Экспорт
Родитель = СтрокаДерева.Родитель;
Если Родитель = Неопределено Тогда
Если Дерево = Неопределено Тогда
Родитель = СтрокаДерева.Владелец();
Иначе
Родитель = Дерево;
КонецЕсли;
КонецЕсли;
Возврат Родитель;
КонецФункции
// Результат - Неопределено, "*", Число
Функция ПолучитьКоличествоЭлементовКоллекцииЛкс(Значение) Экспорт
Если Не ЭтоКоллекцияЛкс(Значение) Тогда
КоличествоЭлементов = Неопределено;
Иначе
КоличествоЭлементов = "*";
Если ТипЗнч(Значение) = Тип("COMSafeArray") Тогда
КоличествоЭлементов = Значение.GetLength();
ИначеЕсли ТипЗнч(Значение) = Тип("COMОбъект") Тогда
Попытка
КоличествоЭлементов = Значение.Count;
Исключение
КонецПопытки;
КонецЕсли;
Если КоличествоЭлементов = "*" Тогда
Попытка
КоличествоЭлементов = Значение.Количество();
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
Возврат КоличествоЭлементов;
КонецФункции
Функция ЭтоКоллекцияЛкс(Значение) Экспорт
// Антибаг платформы 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1017316#1017316
Если Значение = ПараметрыСеанса Тогда
Возврат Истина;
КонецЕсли;
Попытка
Для Каждого _Элемент Из Значение Цикл
Прервать;
КонецЦикла;
ЭтоКоллекция = Истина;
Исключение
ЭтоКоллекция = Ложь;
КонецПопытки;
Возврат ЭтоКоллекция;
КонецФункции
Функция ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД) Экспорт
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД);
ТипМетаданных = Фрагменты[0];
ИмяОбъекта = Фрагменты[1];
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
ТипОбъекта = Тип(ТипМетаданных + "Объект." + ИмяОбъекта);
Иначе
КэшТиповВнешнихМетаданных = ирПортативный.мКэшТиповВнешнихМетаданных;
ВнешнийОбъект = КэшТиповВнешнихМетаданных[ПолноеИмяМД];
Если ВнешнийОбъект <> Неопределено Тогда
ТипОбъекта = ТипЗнч(ВнешнийОбъект);
КонецЕсли;
КонецЕсли;
Если ТипОбъекта <> Неопределено Тогда
Результат = Новый (ТипОбъекта);
Иначе
Менеджер = ирПортативный.ПолучитьМенеджерТипаМетаданныхЛкс(ТипМетаданных);
ПолноеИмяФайла = ирПортативный.ПолучитьПолноеИмяФайлаПортативногоОбъектаМетаданныхЛкс(ИмяОбъекта, ТипМетаданных);
Попытка
Результат = Менеджер.Создать(ПолноеИмяФайла, Ложь);
//// Антибаг платформы 8.3 https://partners.v8.1c.ru/forum/t/1442085/m/1442085
//Если ИмяОбъекта = "ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой" Тогда
// Пустышка = Результат.ПолучитьФорму();
//КонецЕсли;
Исключение
// Это очень помогает при ошибках функций режима отладки
ВызватьИсключение ОписаниеОшибки();
КонецПопытки;
Если Истина
И КэшТиповВнешнихМетаданных <> Неопределено
// Такой прием ко всем нельзя применять, т.к. при получении формы у разных экземпляров будет возвращаться всегда форма первого экземпляра, если она открыта
И (Ложь
Или ИмяОбъекта = "ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой"
Или ИмяОбъекта = "ирПлатформа")
Тогда
КэшТиповВнешнихМетаданных[ПолноеИмяМД] = Результат;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьПолноеИмяМДТипаЛкс(Тип) Экспорт
ОбъектМетаданных = Метаданные.НайтиПоТипу(Тип);
Если ОбъектМетаданных <> Неопределено Тогда
Результат = ОбъектМетаданных.ПолноеИмя();
Если ЛиТипСсылкиТочкиМаршрутаЛкс(Тип) Тогда
Результат = Результат + ".Точки";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
#КонецЕсли
#Если Не ТонкийКлиент И Не ВебКлиент И Клиент Тогда
Функция ПолучитьКоординатыСтрокиДереваЛкс(СтрокаДерева, ИмяКлючевойКолонки = "") Экспорт
Координаты = Новый Массив();
Родитель = СтрокаДерева;
Пока Родитель <> Неопределено Цикл
Если ЗначениеЗаполнено(ИмяКлючевойКолонки) Тогда
Координата = Родитель[ИмяКлючевойКолонки];
Иначе
Координата = ПолучитьРодителяСтрокиДереваЛкс(Родитель).Строки.Индекс(Родитель);
КонецЕсли;
Координаты.Вставить(0, Координата);
Родитель = Родитель.Родитель;
КонецЦикла;
Возврат Координаты;
КонецФункции
Функция ПолучитьСтрокуДереваПоКоординатамЛкс(Дерево, Координаты, ИмяКлючевойКолонки = "") Экспорт
СтрокаДерева = Дерево;
Для Каждого Координата Из Координаты Цикл
Если ЗначениеЗаполнено(ИмяКлючевойКолонки) Тогда
СтрокаДерева = СтрокаДерева.Строки.Найти(Координата, ИмяКлючевойКолонки);
Иначе
СтрокаДерева = СтрокаДерева.Строки[Координата];
КонецЕсли;
КонецЦикла;
Возврат СтрокаДерева;
КонецФункции
Процедура УстановитьТекстПоляСохраняяПозициюЛкс(ПолеТекстовогоДокумента, НовыйТекст) Экспорт
НачальнаяКолонка = 0; НачальнаяСтрока = 0; КонечнаяКолонка = 0; КонечнаяСтрока = 0;
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка);
ПолеТекстовогоДокумента.УстановитьТекст(НовыйТекст);
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка);
КонецПроцедуры
Функция ПреобразоватьЗначениеИзSDBLЛкс(ЗначениеSDBL, АдресЧужойСхемыБД = "") Экспорт
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ЗначениеSDBL, ":");
Если Фрагменты.Количество() < 2 Тогда
Возврат Неопределено;
КонецЕсли;
СтрокаНомераТаблицы = Фрагменты[0];
ИдентификаторОбъекта = Фрагменты[1];
ПолноеИмяМД = ПолучитьМетаданныеПоНомеруСсылочнойТаблицыЛкс(СтрокаНомераТаблицы, АдресЧужойСхемыБД);
ОбъектМетаданныхНайден = Истина;
Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда
ПолноеИмяМД = "НеизвестныйСсылочныйТип" + СтрокаНомераТаблицы;
ОбъектМетаданныхНайден = Ложь;
КонецЕсли;
Результат = ПолноеИмяМД + "._" + ИдентификаторОбъекта;
Если ОбъектМетаданныхНайден И Не ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда
//СтруктураБД = ирКэш.ПолучитьСтруктуруХраненияБДЛкс(Ложь);
// Этот способ не работал для перечислений
//УникальныйИдентификатор = Новый УникальныйИдентификатор(ПолучитьГУИДПрямойИзИнверсногоЛкс(Фрагменты[1]));
//Массив = Новый Массив();
//Если ЗначениеЗаполнено(УникальныйИдентификатор) Тогда
// Массив.Добавить(УникальныйИдентификатор);
//КонецЕсли;
//Значение = Новый (Тип(ПолучитьИмяТипаСсылкиТаблицыБДЛкс(ПолноеИмяМД)), Массив);
//
ПустаяСсылка = Новый (Тип(ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяМД)));
ПустаяСсылкаВнутр = ЗначениеВСтрокуВнутр(ПустаяСсылка);
ФрагментыПустойСсылки = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПустаяСсылкаВнутр, ":");
СсылкаВнутр = ФрагментыПустойСсылки[0] + ":" + ИдентификаторОбъекта + "}";
Попытка
Результат = ЗначениеИзСтрокиВнутр(СсылкаВнутр);
Исключение
// Например, если Фрагменты[1] содержит неверное число символов
КонецПопытки;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьМетаданныеПоНомеруСсылочнойТаблицыЛкс(СтрокаНомерТаблицы, АдресЧужойСхемыБД = "") Экспорт
СтруктураБД = ирКэш.ПолучитьСтруктуруХраненияБДЛкс(,, АдресЧужойСхемыБД);
#Если Сервер И Не Сервер Тогда
СтруктураБД = Новый ТаблицаЗначений;
#КонецЕсли
СловарьШаблоновМетаданных = ирКэш.ПолучитьСловарьШаблоновМетаданныхЛкс(, АдресЧужойСхемыБД);
Для Каждого СтрокаШаблона Из СловарьШаблоновМетаданных.НайтиСтроки(Новый Структура("Значение", 1)) Цикл
ИмяКандидат = СтрЗаменить(СтрокаШаблона.Ключ, "1", СтрокаНомерТаблицы);
СтрокаСтруктуры = СтруктураБД.Найти(ИмяКандидат, "КраткоеИмяТаблицыХранения");
Если СтрокаСтруктуры <> Неопределено Тогда
Возврат СтрокаСтруктуры.Метаданные;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Функция ПолучитьИндексКартинкиСловаПодсказкиЛкс(ДанныеСтроки) Экспорт
Попытка
ТипЗначения = ДанныеСтроки.ТипЗначения;
Исключение
ТипЗначения = Неопределено;
КонецПопытки;
ИндексКартинки = -1;
Если Ложь
Или ДанныеСтроки.ТипСлова = "Ключевое слово"
Или ДанныеСтроки.ТипСлова = "Конструкция"
Тогда
ИндексКартинки = 13;
ИначеЕсли ТипЗначения = "Имя типа" Тогда
ИндексКартинки = 12;
ИначеЕсли ДанныеСтроки.ТипСлова = "Метод" Тогда
Попытка
Пустышка = ДанныеСтроки.Успех;
ЕстьУспех = Истина;
Исключение
ЕстьУспех = Ложь;
КонецПопытки;
Если Ложь
Или (Истина
И ЕстьУспех
И (Ложь
Или ДанныеСтроки.ТаблицаСтруктурТипов = Неопределено
Или ДанныеСтроки.ТаблицаСтруктурТипов.Количество() = 0
Или ДанныеСтроки.ТаблицаСтруктурТипов[0].ИмяОбщегоТипа = ""))
Или (Истина
И Не ЕстьУспех
И ДанныеСтроки.ТипЗначения = "")
Тогда
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 0;
ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда
ИндексКартинки = 6;
//ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда
// ИндексКартинки = 9;
Иначе
ИндексКартинки = 3;
КонецЕсли;
Иначе
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 1;
ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда
ИндексКартинки = 7;
//ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда
// ИндексКартинки = 10;
Иначе
ИндексКартинки = 4;
КонецЕсли;
КонецЕсли;
ИначеЕсли ДанныеСтроки.ТипСлова = "Свойство" Тогда
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 2;
ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда
ИндексКартинки = 8;
//ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда
// ИндексКартинки = 11;
Иначе
ИндексКартинки = 5;
КонецЕсли;
ИначеЕсли ДанныеСтроки.ТипСлова = "Таблица" Тогда
ИндексКартинки = 14;
ИначеЕсли ДанныеСтроки.ТипСлова = "Поле" Тогда
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 15;
Иначе
ИндексКартинки = 16;
КонецЕсли;
ИначеЕсли ДанныеСтроки.ТипСлова = "Группа" Тогда
ИндексКартинки = 18;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции
// Эта обертка нужно для возможности привязать ее к команде панели инструментов
Процедура ОтладитьОтложенныйОбъектБезПараметровЛкс() Экспорт
ОтладитьОтложенныйОбъектЛкс();
КонецПроцедуры
Процедура ОтладитьОтложенныйОбъектЛкс(СсылкаИлиИмяФайла = Неопределено, УдалитьОбъектПослеУспешногоОткрытия = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
Ссылка = Справочники.ирОбъектыДляОтладки.ПустаяСсылка();
#КонецЕсли
Если СсылкаИлиИмяФайла = Неопределено Тогда
СсылкаИлиИмяФайла = ПолучитьТекстИзБуфераОбменаОСЛкс();
ЭтоФайл = Неопределено;
Если Не ВвестиСтроку(СсылкаИлиИмяФайла, "Введите результат сохранения объекта") Тогда
СсылкаИлиИмяФайла = ВыбратьОтложенныйОбъектДляОтладкиЛкс();
КонецЕсли;
Если Не ЗначениеЗаполнено(СсылкаИлиИмяФайла) Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда
ВычислительРегулярныхВыражений = ирКэш.Получить().RegExp;
ВычислительРегулярныхВыражений.Pattern = "Файл ""(.+)""";
Результат = ВычислительРегулярныхВыражений.Execute(СсылкаИлиИмяФайла);
Если Результат.Count = 0 Тогда
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
ВычислительРегулярныхВыражений.Pattern = "\b([A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12})\b";
Результат = ВычислительРегулярныхВыражений.Execute(СсылкаИлиИмяФайла);
ЭтоФайл = Ложь;
КонецЕсли;
Иначе
ЭтоФайл = Истина;
КонецЕсли;
Если Результат.Count = 0 Тогда
Сообщить("Введен некорректный результат сохранения объекта для отладки");
Возврат;
КонецЕсли;
СсылкаИлиИмяФайла = Результат.Item(0).SubMatches(0);
Если ЭтоФайл Тогда
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
// Перекладываем из файла в новый элемент справочника
ФайлОбъектаДляОтладки = Новый Файл(СсылкаИлиИмяФайла);
ОбъектДляОтладки = ВосстановитьОбъектИзСтрокиXMLЛкс(ФайлОбъектаДляОтладки);
РезультатОтложения = ОтложитьУпакованныйОбъектДляОтладкиЛкс(ОбъектДляОтладки, СсылкаИлиИмяФайла);
Сообщить(РезультатОтложения);
УдалитьФайлы(ФайлОбъектаДляОтладки.ПолноеИмя);
КонецЕсли;
Иначе
СсылкаИлиИмяФайла = Справочники.ирОбъектыДляОтладки.ПолучитьСсылку(Новый УникальныйИдентификатор(СсылкаИлиИмяФайла));
Если Не ЗначениеЗаполнено(СсылкаИлиИмяФайла) Тогда
Возврат;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
//Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда
// СтрокаРезультата = ПолучитьИзВременногоХранилища(СсылкаИлиИмяФайла);
// Если СтрокаРезультата = Неопределено Тогда
// Сообщить("Временное хранилище пусто. Вероятно отлаживаемый сеанс завершился.");
// Возврат;
// КонецЕсли;
ЧтениеXML = Новый ЧтениеXML;
Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда
ЧтениеXML.ОткрытьФайл(СсылкаИлиИмяФайла);
Иначе
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
| ирОбъектыДляОтладки.XML
|ИЗ
| Справочник.ирОбъектыДляОтладки КАК ирОбъектыДляОтладки
|ГДЕ
| ирОбъектыДляОтладки.Ссылка = &Ссылка
|";
Запрос.УстановитьПараметр("Ссылка", СсылкаИлиИмяФайла);
ТаблицаРезультата = Запрос.Выполнить().Выгрузить();
Если ТаблицаРезультата.Количество() = 0 Тогда
Сообщить("Объект для отладки не найден в справочнике. Вероятно он был удален.");
Возврат;
КонецЕсли;
СтрокаРезультата = ТаблицаРезультата[0];
СтрокаРезультата = СтрокаРезультата.XML;
ЧтениеXML.УстановитьСтроку(СтрокаРезультата);
КонецЕсли;
Попытка
СтруктураПараметров = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Исключение
ОписаниеОшибки = ОписаниеОшибки();
Сообщить("Некорректный объект для отладки: " + ОписаниеОшибки, СтатусСообщения.Внимание);
Возврат;
КонецПопытки;
Объект = СтруктураПараметров.Объект;
ТипОперации = СтруктураПараметров.ТипОперации;
Если ТипОперации = "Отладить" Тогда
НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = СтруктураПараметров.НастройкаКомпоновки;
Если ТипЗнч(Объект) = Тип("Структура") Тогда
СтруктураЗапроса = Объект;
Объект = Новый Запрос;
Если Истина
И СтруктураЗапроса.Свойство("ВременныеТаблицы")
И СтруктураЗапроса.ВременныеТаблицы <> Неопределено
Тогда
Объект.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = "";
#Если Клиент Тогда
СостояниеЛкс("Подготовка временных таблиц");
#КонецЕсли
ТекстЗапросаПодготовки = "";
НеподдерживаемыеКолонки = "";
Для Каждого КлючИЗначение Из СтруктураЗапроса.ВременныеТаблицы Цикл
Если ТекстЗапросаПодготовки <> "" Тогда
ТекстЗапросаПодготовки = ТекстЗапросаПодготовки + ";";
НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц + ",";
КонецЕсли;
ТекстЗапросаПодготовки = ТекстЗапросаПодготовки + "ВЫБРАТЬ Т.* ПОМЕСТИТЬ " + КлючИЗначение.Ключ + " ИЗ &" + КлючИЗначение.Ключ + " КАК Т";
НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц + КлючИЗначение.Ключ;
ТаблицаЗначений = ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(КлючИЗначение.Значение, Истина);
#Если Сервер И Не Сервер Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
Если Ложь
Или Колонка.ТипЗначения.СодержитТип(Тип("МоментВремени"))
Или Колонка.ТипЗначения.СодержитТип(Тип("УникальныйИдентификатор"))
Тогда
Если НеподдерживаемыеКолонки <> "" Тогда
НеподдерживаемыеКолонки = НеподдерживаемыеКолонки + ", ";
КонецЕсли;
НеподдерживаемыеКолонки = НеподдерживаемыеКолонки + КлючИЗначение.Ключ + "." + Колонка.Имя;
КонецЕсли;
КонецЦикла;
Объект.Параметры.Вставить(КлючИЗначение.Ключ, ТаблицаЗначений);
КонецЦикла;
Если НеподдерживаемыеКолонки <> "" Тогда
// https://partners.v8.1c.ru/forum/t/1570237/m/1570237
ВызватьИсключение "Невозможно восстановить временные таблицы из-за недопустимых типов (МоментВремени, УникальныйИдентификатор) в колонках: " + НеподдерживаемыеКолонки;
КонецЕсли;
Если ЗначениеЗаполнено(ТекстЗапросаПодготовки) Тогда
Объект.Текст = ТекстЗапросаПодготовки;
Попытка
Объект.Выполнить();
Исключение
Сообщить("Ошибка восстановления временных таблиц: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЕсли;
Объект.Параметры.Очистить();
Объект.Текст = СтруктураЗапроса.Текст;
// Антибаг платформы 8.2.18. Некорректная серилизация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураЗапроса.Параметры, Объект.Параметры);
Для Каждого КлючИЗначение Из СтруктураЗапроса.Параметры Цикл
Объект.Параметры.Вставить(КлючИЗначение.Ключ, ЗначениеИзСтрокиВнутр(КлючИЗначение.Значение));
КонецЦикла;
КонецЕсли;
ОтладитьЛкс(Объект, , НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, СтруктураПараметров.ВнешниеНаборыДанных);
ИначеЕсли ТипОперации = "Исследовать" Тогда
ИсследоватьЛкс(Объект, , СтруктураПараметров.КакКоллекцию);
КонецЕсли;
Если УдалитьОбъектПослеУспешногоОткрытия Тогда
Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда
УдалитьФайлы(СсылкаИлиИмяФайла);
Иначе
УдалениеОбъекта = Новый УдалениеОбъекта(СсылкаИлиИмяФайла);
УдалениеОбъекта.ОбменДанными.Загрузка = Истина;
УдалениеОбъекта.Записать();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ВыбратьОтложенныйОбъектДляОтладкиЛкс()
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
СсылкаИлиИмяФайла = ВыбратьСсылкуЛкс(Метаданные.Справочники.ирОбъектыДляОтладки,, Ложь);
Иначе
ПутьДляФайловОбъектовДляОтладки = ирПортативный.ПолучитьКаталогОбъектовДляОтладкиЛкс();
Расширение = ПолучитьРасширениеФайловДляОтладкиЛкс();
лПолноеИмяФайла = ВыбратьФайлЛкс(, Расширение, "Файлы снимков объектов для отладки",, ПутьДляФайловОбъектовДляОтладки);
Если лПолноеИмяФайла <> Неопределено Тогда
СсылкаИлиИмяФайла = "Файл """ + лПолноеИмяФайла + """";
КонецЕсли;
КонецЕсли;
Возврат СсылкаИлиИмяФайла;
КонецФункции
// ОформляемыеКолонки - имена колонок, разделенные запятыми
Процедура ОтобразитьПустыеЗначенияВЯчейкахТабличногоПоля(ОформлениеСтроки, Знач ОформляемыеКолонки = "") Экспорт
ОформляемыеКолонки = Новый Структура(ОформляемыеКолонки);
НеФильтровтатьКолонки = (ОформляемыеКолонки.Количество() = 0);
Для Каждого Ячейка Из ОформлениеСтроки.Ячейки Цикл
Если Ложь
Или НеФильтровтатьКолонки
Или ОформляемыеКолонки.Свойство(Ячейка.Имя)
Тогда
ЗначениеЯчейки = Ячейка.Значение;
Если Не ЗначениеЗаполнено(ЗначениеЯчейки) Тогда
Ячейка.УстановитьТекст(ирКэш.Получить().мПолучитьПредставлениеПустогоЗначения(ЗначениеЯчейки));
Ячейка.ЦветФона = WebЦвета.Роса;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ОтобразитьПустыеЗначенияВЯчейкахТабличногоПоля()
Процедура ПолеВвода_ОкончаниеВводаТекстаЛкс(Элемент, Текст, Значение, СтандартнаяОбработка, РасширенноеЗначение = Null, ЛиТипСтрокаСлужебный = Ложь) Экспорт
Менеджер = Неопределено;
Если ТипЗнч(Элемент.Значение) = Тип("Строка") Тогда
Типы = Элемент.ТипЗначения.Типы();
Если Типы.Количество() > 1 Тогда
ПредставлениеЗначения = ПолучитьСтрокуМеждуМаркерамиЛкс(Элемент.Значение, "(", ")");
ЗначениеСсылки = ПреобразоватьЗначениеИзSDBLЛкс(ПредставлениеЗначения);
Если Не ЗначениеЗаполнено(ЗначениеСсылки) Тогда
//e1cib/data/Справочник.ирОбъектыДляОтладки?ref=aa3a0009dd50223411e1c2907cccb6b7
Маркер = "e1cib/data/";
Если СтрокиРавныЛкс(Нрег(Лев(Элемент.Значение, СтрДлина(Маркер))), Маркер) Тогда
ТекстСсылки = Сред(Элемент.Значение, СтрДлина(Маркер) + 1);
Разделитель = "?ref=";
Идентификатор = ПолучитьПоследнийФрагментЛкс(ТекстСсылки, Разделитель);
Идентификатор = ПолучитьГУИДПрямойИзИнверсногоЛкс(Идентификатор);
ПолноеИмяМД = ПолучитьПервыйФрагментЛкс(ТекстСсылки, Разделитель);
лМенеджер = Новый (СтрЗаменить(ПолноеИмяМД, ".", "Менеджер."));
ЗначениеСсылки = лМенеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(Идентификатор));
КонецЕсли;
КонецЕсли;
Если Истина
И ЗначениеСсылки <> Неопределено
И ТипЗнч(ЗначениеСсылки) <> Тип("Строка")
И Элемент.ТипЗначения.СодержитТип(ТипЗнч(ЗначениеСсылки))
Тогда
Ответ = КодВозвратаДиалога.Да;
Если Не ЛиТипСтрокаСлужебный Тогда
Ответ = Вопрос("Хотите вставить строку как ссылку?", РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Нет);
КонецЕсли;
Если Ответ = КодВозвратаДиалога.Да Тогда
Значение = ЗначениеСсылки;
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(ЗначениеСсылки) Тогда
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(Элемент.Значение);
Если Фрагменты.Количество() > 1 Тогда
ИмяТипа = Фрагменты[0] + "." + Фрагменты[1];
Попытка
ОписаниеТипов = Новый ОписаниеТипов(ИмяТипа);
Исключение
ОписаниеТипов = Неопределено;
КонецПопытки;
Если ОписаниеТипов <> Неопределено Тогда
Значение = ОписаниеТипов.ПривестиЗначение();
Менеджер = ПолучитьМенеджерЛкс(Значение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И ЛиТипСтрокаСлужебный
И СтандартнаяОбработка
И ЗначениеЗаполнено(Элемент.Значение)
Тогда
Значение = "";
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЛиТипСсылкиБДЛкс(ТипЗнч(Элемент.Значение)) Тогда
Менеджер = ПолучитьМенеджерЛкс(Элемент.Значение);
КонецЕсли;
Если Менеджер <> Неопределено Тогда
УникальныйИдентификатор = ирКэш.Получить().ПолучитьУникальныйИдентификаторИзСтроки(Текст);
Если УникальныйИдентификатор <> Неопределено Тогда
СтандартнаяОбработка = Ложь;
Значение = Менеджер.ПолучитьСсылку(УникальныйИдентификатор);
Иначе
ОбъектМД = Элемент.Значение.Метаданные();
ПредставлениеТипаДокумента = ОбъектМД.Представление();
Если Найти(Текст, ПредставлениеТипаДокумента) = 1 Тогда
ЧастьТекста = Сред(Текст, СтрДлина(ПредставлениеТипаДокумента) + 2);
RegExp = ирКэш.Получить().RegExp;
RegExp.Pattern = "\ от\ (\d+\.\d+\.\d+\ \d+\:\d+\:\d+)$";
Результаты = RegExp.Execute(ЧастьТекста);
Если Результаты.Count > 0 Тогда
Номер = Лев(ЧастьТекста, Результаты.Item(0).FirstIndex);
Дата = Результаты.Item(0).Submatches(0);
Попытка
Дата = Дата(Дата);
Исключение
Дата = Неопределено;
КонецПопытки;
Если Дата <> Неопределено Тогда
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
| _Т.Ссылка
|ИЗ
| " + ОбъектМД.ПолноеИмя() + " КАК _Т
|ГДЕ
| _Т.Номер = &Номер
| И _Т.Дата = &Дата
|";
Запрос.УстановитьПараметр("Номер", Номер);
Запрос.УстановитьПараметр("Дата", Дата);
Значение = Новый СписокЗначений;
Значение.ЗагрузитьЗначения(Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(0));
Если Значение.Количество() > 0 Тогда
Для Каждого ЭлементСписка Из Значение Цикл
ЭлементСписка.Представление = "" + ЭлементСписка.Значение + " (" + ЭлементСписка.Значение.УникальныйИдентификатор() + ")";
КонецЦикла;
КонецЕсли;
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Если Ложь
Или (Истина
И РасширенноеЗначение <> Null
И ТипЗнч(РасширенноеЗначение) <> ТипЗнч(Элемент.Значение))
Или Элемент.ОграничениеТипа.ПривестиЗначение(Элемент.Значение) <> Элемент.Значение
Тогда
// Откат
СтандартнаяОбработка = Ложь;
Значение = Новый СписокЗначений;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Результат - Булево - Истина если значение было изменено
Функция ОткрытьФормуПроизвольногоЗначенияЛкс(РасширенноеЗначение, РедактированиеРазрешено = Истина, СтандартнаяОбработка = Истина,
ЗаголовокФормы = "", РедактироватьМодально = Истина, ПринудительноВОтдельнойФорме = Истина, ЭлементУправления = Неопределено) Экспорт
Результат = Ложь;
ТипРасширенногоЗначения = ТипЗнч(РасширенноеЗначение);
ХмлТип = XMLТипЗнч(РасширенноеЗначение);
Если Ложь
Или ТипРасширенногоЗначения = Тип("ТаблицаЗначений")
Или ТипРасширенногоЗначения = Тип("ДеревоЗначений")
Или ТипРасширенногоЗначения = Тип("МоментВремени")
Или ТипРасширенногоЗначения = Тип("ТабличныйДокумент")
Или ТипРасширенногоЗначения = Тип("Массив")
Или ТипРасширенногоЗначения = Тип("Граница")
Или ТипРасширенногоЗначения = Тип("УникальныйИдентификатор")
Или ТипРасширенногоЗначения = Тип("Тип")
Или ТипРасширенногоЗначения = Тип("ОписаниеТипов")
Или ТипРасширенногоЗначения = Тип("СписокЗначений")
Или ТипРасширенногоЗначения = Тип("ДвоичныеДанные")
Или ТипРасширенногоЗначения = Тип("ХранилищеЗначения")
Или (Истина
И ТипРасширенногоЗначения = Тип("Строка")
И (Ложь
Или ПринудительноВОтдельнойФорме
Или СтрДлина(РасширенноеЗначение) > 150
Или Не РедактированиеРазрешено))
Тогда
СтандартнаяОбработка = Ложь;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если Ложь
Или ТипРасширенногоЗначения = Тип("ТаблицаЗначений")
Или ТипРасширенногоЗначения = Тип("ДеревоЗначений")
Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ТаблицаЗначений", , РасширенноеЗначение);
ФормаРедактирования.ТабличноеПоле = ЭлементУправления;
ИначеЕсли ТипРасширенногоЗначения = Тип("МоментВремени") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("МоментВремени", , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("ТабличныйДокумент") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ТабличныйДокумент", , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("Граница") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("Граница", , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("Массив") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("Массив", , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("УникальныйИдентификатор") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("УникальныйИдентификатор", , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("СписокЗначений") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("СписокЗначений", , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("Строка") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("Текст", , Новый УникальныйИдентификатор());
ИначеЕсли ТипРасширенногоЗначения = Тип("Тип") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ВыборРедактируемыхТипов", , Новый УникальныйИдентификатор());
ФормаРедактирования.МножественныйВыбор = Ложь;
ИначеЕсли ТипРасширенногоЗначения = Тип("ОписаниеТипов") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ВыборРедактируемыхТипов", , РасширенноеЗначение);
ФормаРедактирования.МножественныйВыбор = Истина;
ИначеЕсли ТипРасширенногоЗначения = Тип("ХранилищеЗначения") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ХранилищеЗначения", , Новый УникальныйИдентификатор());
ИначеЕсли ТипРасширенногоЗначения = Тип("ДвоичныеДанные") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ДвоичныеДанные", , Новый УникальныйИдентификатор());
КонецЕсли;
Если ЗначениеЗаполнено(ЗаголовокФормы) Тогда
ФормаРедактирования.Заголовок = ЗаголовокФормы;
КонецЕсли;
Если ФормаРедактирования.Открыта() Тогда
ФормаРедактирования.Активизировать();
Возврат Результат;
КонецЕсли;
ФормаРедактирования.ТолькоПросмотр = Не РедактированиеРазрешено;
Если РедактированиеРазрешено Тогда
ФормаРедактирования.НачальноеЗначениеВыбора = ПолучитьКопиюОбъектаЛкс(РасширенноеЗначение); // Опасно
Иначе
ФормаРедактирования.НачальноеЗначениеВыбора = РасширенноеЗначение;
КонецЕсли;
Если РедактированиеРазрешено И РедактироватьМодально Тогда
РезультатВыбора = ФормаРедактирования.ОткрытьМодально();
Если РезультатВыбора <> Неопределено Тогда
РасширенноеЗначение = РезультатВыбора;
Результат = Истина;
КонецЕсли;
Иначе
ФормаРедактирования.Открыть();
КонецЕсли;
ИначеЕсли Ложь
Или ТипРасширенногоЗначения = Тип("Число")
Или ТипРасширенногоЗначения = Тип("Строка")
Или ТипРасширенногоЗначения = Тип("Дата")
Или ТипРасширенногоЗначения = Тип("Булево")
Или ТипРасширенногоЗначения = Тип("Неопределено")
Или ТипРасширенногоЗначения = Тип("Null")
Или ТипРасширенногоЗначения = Тип("ПолеКомпоновкиДанных")
Или ТипРасширенногоЗначения = Тип("СтандартнаяДатаНачала")
Или ТипРасширенногоЗначения = Тип("СтандартныйПериод")
Или ТипРасширенногоЗначения = Тип("ВидДвиженияНакопления")
Или ТипРасширенногоЗначения = Тип("ВидДвиженияБухгалтерии")
Или ТипРасширенногоЗначения = Тип("ВидСчета")
Или (Истина
И ХмлТип <> Неопределено
И Найти(ХмлТип.ИмяТипа, "Ref.") > 0)
Тогда
Если ЛиТипСсылкиБДЛкс(ТипРасширенногоЗначения, Ложь) Тогда
Если ЗначениеЗаполнено(РасширенноеЗначение) Тогда
Запрос = Новый Запрос("ВЫБРАТЬ 1 ИЗ " + ПолучитьПолноеИмяМДТипаЛкс(ТипРасширенногоЗначения) + " ГДЕ Ссылка = &Ссылка");
Запрос.УстановитьПараметр("Ссылка", РасширенноеЗначение);
ОбъектСуществует = Не Запрос.Выполнить().Пустой();
Если Не ОбъектСуществует Тогда
//ОткрытьСсылкуЯчейкиВРедактореОбъектаБДЛкс(ТабличноеПоле);
ОткрытьСсылкуВРедактореОбъектаБДЛкс(РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Ложь
Или Не СтандартнаяОбработка
Или Не РедактированиеРазрешено
Тогда
Если ЛиТипСсылкиБДЛкс(ТипРасширенногоЗначения, Ложь) Тогда
Если Истина
И ЗначениеЗаполнено(РасширенноеЗначение)
И ОбъектСуществует
Тогда
ОткрытьЗначение(РасширенноеЗначение);
КонецЕсли;
СтандартнаяОбработка = Ложь;
КонецЕсли;
Если СтандартнаяОбработка Тогда
ОткрытьЗначение(РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
Иначе
//Если Истина
// И ТипЗначения1 <> Неопределено
// И ТипЗначения1.ПривестиЗначение(РасширенноеЗначение) <> РасширенноеЗначение
//Тогда
ИсследоватьЛкс(РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
//КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОткрытьРедакторИзПоляТабличногоДокументаЛкс(ПолеТабличногоДокумента) Экспорт
Копия = Новый ТабличныйДокумент;
Копия.Вывести(ПолеТабличногоДокумента);
ЗаполнитьЗначенияСвойств(Копия, ПолеТабличногоДокумента);
Результат = ирОбщий.ОткрытьФормуПроизвольногоЗначенияЛкс(Копия,,,, Ложь);
Возврат Результат;
КонецФункции
// Результат - Булево - Истина если значение было изменено
Функция ЯчейкаТабличногоПоляРасширенногоЗначения_ВыборЛкс(ТабличноеПоле, СтандартнаяОбработка = Ложь, РасширенноеЗначение = Null,
РедактированиеРазрешено = Истина, ПринудительноВОтдельнойФорме = Ложь, Данные = "") Экспорт
Колонка = ТабличноеПоле.ТекущаяКолонка;
Если Не ЗначениеЗаполнено(Данные) Тогда
Данные = Колонка.Данные;
КонецЕсли;
Если РасширенноеЗначение = Null Тогда
Если Не ЗначениеЗаполнено(Данные) Тогда
Возврат Ложь;
КонецЕсли;
РасширенноеЗначение = ТабличноеПоле.ТекущиеДанные[Данные];
КонецЕсли;
Если ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда
ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(ТабличноеПоле.ТекущаяСтрока);
Ячейка = ОформлениеСтроки.Ячейки[Колонка.Имя];
РедактированиеРазрешено = РедактированиеРазрешено И Не Ячейка.ТолькоПросмотр;
КонецЕсли;
Если Колонка.ЭлементУправления <> Неопределено Тогда
ТипЗначения1 = Колонка.ЭлементУправления.ТипЗначения;
КонецЕсли;
РедактированиеРазрешено = Истина
И РедактированиеРазрешено
И Не ТабличноеПоле.ТолькоПросмотр
И Не Колонка.ТолькоПросмотр
И Колонка.ЭлементУправления <> Неопределено
И Не Колонка.ЭлементУправления.ТолькоПросмотр;
Результат = ОткрытьФормуПроизвольногоЗначенияЛкс(РасширенноеЗначение, РедактированиеРазрешено, СтандартнаяОбработка,,, ПринудительноВОтдельнойФорме);
Если Результат Тогда
НовоеЗначение = РасширенноеЗначение; // Сохраняем значение, т.к. оно может испортиться следующей строкой
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначение); // Почему то запрещенные для поля ввода значения здесь превращаются в строку (например МоментВремени, УникальныйИдентификатор)
РасширенноеЗначение = НовоеЗначение;
КонецЕсли;
Возврат Результат;
КонецФункции // ОткрытьЗначениеЯчейки()
// Результат - Булево - Истина если значение было изменено
Функция ПолеВводаРасширенногоЗначения_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка, РасширенноеЗначение = Null) Экспорт
Если РасширенноеЗначение = Null Тогда
РасширенноеЗначение = Элемент.Значение;
КонецЕсли;
ЗначениеИзменено = Ложь;
Если РасширенноеЗначение = Неопределено Тогда
СтандартнаяОбработка = Ложь;
ОграничениеТипа = Элемент.ОграничениеТипа;
НовыйТип = ирОбщий.ВыбратьРедактируемыйТипЛкс(ОграничениеТипа);
Если НовыйТип <> Неопределено Тогда
МассивТипов = ирОбщий.БыстрыйМассивЛкс(НовыйТип);
НовоеОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
НовоеЗначение = НовоеОписаниеТипов.ПривестиЗначение(Неопределено);
РасширенноеЗначение = НовоеЗначение;
Элемент.Значение = РасширенноеЗначение; //
ЗначениеИзменено = Истина;
КонецЕсли;
Иначе
Результат = ирОбщий.ОткрытьФормуПроизвольногоЗначенияЛкс(РасширенноеЗначение, Истина, СтандартнаяОбработка);
Если Результат Тогда
Элемент.Значение = РасширенноеЗначение;
КонецЕсли;
Если Не СтандартнаяОбработка Тогда
Элемент.Значение = РасширенноеЗначение;
КонецЕсли;
КонецЕсли;
Возврат ЗначениеИзменено;
КонецФункции
// Результат - Булево - Истина если значение было изменено
Функция ПолеВводаКолонкиРасширенногоЗначения_НачалоВыбораЛкс(ТабличноеПоле, СтандартнаяОбработка, РасширенноеЗначение = Null, ИспользоватьОграничениеТипа = Ложь,
СтруктураОтбора = Неопределено, Данные = "") Экспорт
Колонка = ТабличноеПоле.ТекущаяКолонка;
Если Не ЗначениеЗаполнено(Данные) Тогда
Данные = Колонка.Данные;
РазрешитьВыборТипа = Истина;
Иначе
РазрешитьВыборТипа = Ложь;
КонецЕсли;
Если РасширенноеЗначение = Null Тогда
РасширенноеЗначение = ТабличноеПоле.ТекущиеДанные[Данные];
КонецЕсли;
ЗначениеИзменено = Ложь;
Если РасширенноеЗначение = Неопределено Тогда
Если Не РазрешитьВыборТипа Тогда
Возврат ЗначениеИзменено;
КонецЕсли;
СтандартнаяОбработка = Ложь;
ОграничениеТипа = Неопределено;
Если ИспользоватьОграничениеТипа Тогда
ОграничениеТипа = Колонка.ЭлементУправления.ОграничениеТипа;
Если ОграничениеТипа.Типы().Количество() = 0 Тогда
ОграничениеТипа = Колонка.ЭлементУправления.ТипЗначения;
КонецЕсли;
КонецЕсли;
НовыйТип = ВыбратьРедактируемыйТипЛкс(ОграничениеТипа);
Если НовыйТип <> Неопределено Тогда
МассивТипов = БыстрыйМассивЛкс(НовыйТип);
НовоеОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
НовоеЗначение = НовоеОписаниеТипов.ПривестиЗначение(Неопределено);
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначение); // Почему то запрещенные для поля ввода значения здесь превращаются в строку (например МоментВремени)
РасширенноеЗначение = НовоеЗначение;
ЗначениеИзменено = Истина;
Если ЛиСсылкаНаОбъектБДЛкс(РасширенноеЗначение, Ложь) Тогда
ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РасширенноеЗначение)), СтруктураОтбора,, Колонка.ЭлементУправления, Истина,, РасширенноеЗначение);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если РасширенноеЗначение <> Неопределено Тогда
ЗначениеИзменено = ЯчейкаТабличногоПоляРасширенногоЗначения_ВыборЛкс(ТабличноеПоле, СтандартнаяОбработка, РасширенноеЗначение, Истина, Истина, Данные) Или ЗначениеИзменено;
//Если ЗначениеИзменено Тогда
Если Не СтандартнаяОбработка Тогда
ТабличноеПоле.ТекущиеДанные[Данные] = РасширенноеЗначение;//
КонецЕсли;
Если СтандартнаяОбработка Тогда
Если ЛиСсылкаНаОбъектБДЛкс(РасширенноеЗначение, Ложь) Тогда
ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РасширенноеЗначение)), СтруктураОтбора,, Колонка.ЭлементУправления, Истина,, РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ЗначениеИзменено;
КонецФункции
// ИменаКолонокСПиктограммамиТипов - Массив, Строка
Процедура ТабличноеПолеПриВыводеСтрокиЛкс(Элемент, ОформлениеСтроки, ДанныеСтроки, КнопкаРежимаОтображения = Неопределено, Знач ИменаКолонокСПиктограммамиТипов = "", РасширенныеКолонки = Неопределено,
РасширенноеПредставлениеХранилищЗначений = Ложь) Экспорт
СостоянияКнопки = ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс();
ЛиОтбражатьПустые = Истина
И КнопкаРежимаОтображения <> Неопределено
И (Ложь
Или КнопкаРежимаОтображения.Текст = СостоянияКнопки[1]
Или КнопкаРежимаОтображения.Текст = СостоянияКнопки[2]);
ОтображатьИдентификаторы = Истина
И КнопкаРежимаОтображения <> Неопределено
И (Ложь
Или КнопкаРежимаОтображения.Текст = СостоянияКнопки[2]);
ирПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
ирПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если ТипЗнч(ИменаКолонокСПиктограммамиТипов) = Тип("Строка") Тогда
ИменаКолонокСПиктограммамиТипов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаКолонокСПиктограммамиТипов, ",", Истина);
КонецЕсли;
Для Каждого Колонка Из Элемент.Колонки Цикл
Ячейка = ОформлениеСтроки.Ячейки[Колонка.Имя];
КолонкаДанных = Неопределено;
Если РасширенныеКолонки <> Неопределено Тогда
РасширенныеКолонки.Свойство(Колонка.Имя, КолонкаДанных);
КонецЕсли;
КолонкаОтображаетДанныеФлажка = Ложь;
Если КолонкаДанных <> Неопределено Тогда
ЗначениеЯчейки = ДанныеСтроки[КолонкаДанных];
Иначе
Если Истина
И Не ЗначениеЗаполнено(Колонка.Данные)
И ЗначениеЗаполнено(Колонка.ДанныеФлажка)
Тогда
ЗначениеЯчейки = Ячейка.ЗначениеФлажка;
КолонкаОтображаетДанныеФлажка = Истина;
Иначе
ЗначениеЯчейки = Ячейка.Значение;
КонецЕсли;
КонецЕсли;
Если Ложь
Или КолонкаОтображаетДанныеФлажка
Или Формат(ЗначениеЯчейки, Колонка.Формат) = Ячейка.Текст
Тогда // Здесь могут быть обращения к БД
ПредставлениеЗначения = "";
Если Истина
И Не КолонкаОтображаетДанныеФлажка
И ТипЗнч(ЗначениеЯчейки) <> Тип("Строка")
Тогда
ПредставлениеЗначения = РасширенноеПредставлениеЗначенияЛкс(ЗначениеЯчейки, Колонка,, РасширенноеПредставлениеХранилищЗначений);
КонецЕсли;
Если ЛиОтбражатьПустые И Не ЭтоКоллекцияЛкс(ЗначениеЯчейки) Тогда
ЦветПустых = ЦветФонаЯчеекПустыхЗначенийЛкс();
Если ТипЗнч(ЗначениеЯчейки) = Тип("Строка") Тогда
ПредставлениеЗначения = """" + ЗначениеЯчейки + """";
Ячейка.ЦветФона = ЦветПустых;
Иначе
Попытка
ЗначениеНепустое = ЗначениеЗаполнено(ЗначениеЯчейки) И ЗначениеЯчейки <> Ложь;
Исключение
ЗначениеНепустое = Истина;
КонецПопытки;
Если Не ЗначениеНепустое Тогда
ПредставлениеЗначения = ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ЗначениеЯчейки);
Ячейка.ЦветФона = ЦветПустых;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ПредставлениеЗначения <> "" Тогда
Ячейка.УстановитьТекст(ПредставлениеЗначения);
КонецЕсли;
КонецЕсли;
Если ОтображатьИдентификаторы Тогда
ИдентификаторСсылки = ПолучитьИдентификаторСсылкиЛкс(ЗначениеЯчейки);
Если ИдентификаторСсылки <> Неопределено Тогда
XMLТип = XMLТипЗнч(ЗначениеЯчейки);
Ячейка.УстановитьТекст(ИдентификаторСсылки + "." + XMLТип.ИмяТипа);
КонецЕсли;
КонецЕсли;
Если ИменаКолонокСПиктограммамиТипов.Найти(Колонка.Имя) <> Неопределено Тогда
Если ТипЗнч(ЗначениеЯчейки) <> Тип("ПолеКомпоновкиДанных") Тогда
ТипЗначения = ТипЗнч(ЗначениеЯчейки);
Если Истина
И ТипЗначения = Тип("Булево")
И Ячейка.ОтображатьФлажок
Тогда
Продолжить;
КонецЕсли;
КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения);
Если КартинкаТипа <> Неопределено Тогда
Ячейка.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ИмяКолонкиНомерСтроки = ирКэш.ИмяКолонкиНомерСтрокиЛкс();
Если ОформлениеСтроки.Ячейки.Найти(ИмяКолонкиНомерСтроки) <> Неопределено Тогда
Если ТипЗнч(ДанныеСтроки) = Тип("СтрокаДереваЗначений") Тогда
ИндексСтроки = ПолучитьРодителяСтрокиДереваЛкс(ДанныеСтроки, ДанныеСтроки.Владелец()).Строки.Индекс(ДанныеСтроки);
Иначе
ИндексСтроки = ДанныеСтроки.Владелец().Индекс(ДанныеСтроки);
КонецЕсли;
ОформлениеСтроки.Ячейки[ИмяКолонкиНомерСтроки].УстановитьТекст(XMLСтрока(ИндексСтроки + 1));
ОформлениеСтроки.Ячейки[ИмяКолонкиНомерСтроки].ЦветТекста = Новый Цвет(128, 128, 128);
КонецЕсли;
КонецПроцедуры
Функция ЦветФонаЯчеекПустыхЗначенийЛкс() Экспорт
ЦветПустых = Новый Цвет(250, 255, 250); //WebЦвета.Роса;
Возврат ЦветПустых;
КонецФункции
Функция ПолучитьИдентификаторСсылкиЛкс(Ссылка) Экспорт
ИдентификаторСсылки = Неопределено;
XMLТип = XMLТипЗнч(Ссылка);
Если Истина
И XMLТип <> Неопределено
И Найти(XMLТип.ИмяТипа, "Ref.") > 0
Тогда
Если Найти(XMLТип.ИмяТипа, "ExternalDataSourceTableRef.") > 0 Тогда
ИдентификаторСсылки = "{" + ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ЗначениеВСтрокуВнутр(Ссылка), "," + Символы.ПС + "{", "}" + Символы.ПС + "}") + "}";
ИдентификаторСсылки = СтрЗаменить(ИдентификаторСсылки, Символы.ПС, "");
Иначе
ИдентификаторСсылки = XMLСтрока(Ссылка);
КонецЕсли;
КонецЕсли;
Возврат ИдентификаторСсылки;
КонецФункции
Процедура ТабличноеПолеВставитьКолонкуНомерСтрокиЛкс(Знач ТабличноеПоле) Экспорт
ИмяКолонкиНомерСтроки = ирКэш.ИмяКолонкиНомерСтрокиЛкс();
Если ТабличноеПоле.Колонки.Найти(ИмяКолонкиНомерСтроки) = Неопределено Тогда
КолонкаТП = ТабличноеПоле.Колонки.Вставить(0);
КолонкаТП.Имя = ИмяКолонкиНомерСтроки;
КолонкаТП.ТекстШапки = "№";
КолонкаТП.ПодсказкаВШапке = "Номер элемента в пределах родителя (служебная)";
КолонкаТП.ТолькоПросмотр = Истина;
КолонкаТП.Ширина = 3;
КонецЕсли;
КонецПроцедуры // ОбновитьТаблицуКолонок()
Процедура _РасширенныйВыборПравогоЗначенияОтбораКомпоновкиЛкс(ТабличноеПолеОтбора) Экспорт
ТекущаяСтрока = ТабличноеПолеОтбора.ТекущаяСтрока;
Если Ложь
Или ТекущаяСтрока = Неопределено
Или ТипЗнч(ТекущаяСтрока) = Тип("ОтборКомпоновкиДанных")
Или ТипЗнч(ТекущаяСтрока) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
Тогда
Возврат;
КонецЕсли;
ЗначениеОтбора = ТекущаяСтрока.ПравоеЗначение;
КолонкаТП = ТабличноеПолеОтбора.Колонки.ПравоеЗначениеДляКраткогоОтображенияЭлемента;
ТабличноеПолеОтбора.ТекущаяКолонка = КолонкаТП;
Если ТипЗнч(ЗначениеОтбора) <> Тип("СписокЗначений") Тогда
Если ЛиСсылкаНаОбъектБДЛкс(ЗначениеОтбора, Ложь) Тогда
ТабличноеПолеОтбора.ИзменитьСтроку();
ирОбщий.ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеОтбора)),,, КолонкаТП.ЭлементУправления, Истина,, ЗначениеОтбора);
КонецЕсли;
Иначе
Результат = ирОбщий.ОткрытьФормуПроизвольногоЗначенияЛкс(ЗначениеОтбора, Истина);
Если Результат Тогда
ТекущаяСтрока.ПравоеЗначение = ЗначениеОтбора;
ТекущаяСтрока.Использование = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура КнопкаОтображатьПустыеИИдентификаторыНажатиеЛкс(Кнопка) Экспорт
МассивСостояний = ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс();
Если Кнопка.Текст = МассивСостояний[2] Тогда
Кнопка.Пометка = Ложь;
Кнопка.Текст = МассивСостояний[0];
Кнопка.Картинка = ПолучитьОбщуюКартинкуЛкс("ирПусто");
ИначеЕсли Кнопка.Текст = МассивСостояний[1] Тогда
Кнопка.Пометка = Истина;
Кнопка.Текст = МассивСостояний[2];
Кнопка.Картинка = ПолучитьОбщуюКартинкуЛкс("ирИдентификатор");
Иначе//Если Кнопка.Текст = МассивСостояний[0] Тогда
Кнопка.Пометка = Истина;
Кнопка.Текст = МассивСостояний[1];
Кнопка.Картинка = ПолучитьОбщуюКартинкуЛкс("ирПусто");
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс()
МассивСостояний = Новый Массив;
МассивСостояний.Добавить("Не отображать");
МассивСостояний.Добавить("Отображать пустые");
МассивСостояний.Добавить("Отображать пустые и идентификаторы");
Возврат МассивСостояний;
КонецФункции
Процедура ПрименитьИзмененияИЗакрытьФормуЛкс(ЭтаФорма, ЗначениеВыбора = Неопределено) Экспорт
ЭтаФорма.Модифицированность = Ложь;
Если Ложь
Или ЭтаФорма.ВладелецФормы <> Неопределено
Или Не ЭтаФорма.Открыта()
Тогда
ЭтаФорма.ОповеститьОВыборе(ЗначениеВыбора);
КонецЕсли;
Если ЭтаФорма.Открыта() Тогда
ЭтаФорма.Закрыть(ЗначениеВыбора);
КонецЕсли;
//Если ЭтаФорма.Открыта() Тогда
// ЭтаФорма.Закрыть(ЗначениеВыбора);
//Иначе//Если ЭтаФорма.МодальныйРежим Тогда
// ЭтаФорма.ОповеститьОВыборе(ЗначениеВыбора);
//КонецЕсли;
КонецПроцедуры // ПрименитьИзмененияИЗакрытьФорму()
Функция НайтиВозможныеСтрокиОписанияСловаВСинтаксПомощникеЛкс(Знач Слово, ЯзыкПрограммы = 0, ПоискСУчетомТипаСлова = Истина) Экспорт
мПлатформа = ирКэш.Получить();
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
МассивВозможныхТиповСлова = Новый Массив;
МассивВозможныхТиповСлова.Добавить("Конструктор");
Слово = НРег(Слово);
Если Ложь
Или Не ПоискСУчетомТипаСлова
Или Прав(Слово, 1) = "("
Тогда
Если Прав(Слово, 1) = "(" Тогда
Слово = ПолучитьСтрокуБезКонцаЛкс(Слово, 1);
КонецЕсли;
МассивВозможныхТиповСлова.Добавить("Метод");
КонецЕсли;
Если Ложь
Или Не ПоискСУчетомТипаСлова
Или Прав(Слово, 1) <> "("
Тогда
МассивВозможныхТиповСлова.Добавить("Свойство");
МассивВозможныхТиповСлова.Добавить("Конструкция");
МассивВозможныхТиповСлова.Добавить("Событие");
МассивВозможныхТиповСлова.Добавить("Таблица");
КонецЕсли;
ТаблицаСтруктурВозможныхТиповКонтекста = мПлатформа.ПолучитьНовуюТаблицуСтруктурТипа();
Для Каждого ВозможныйТипСлова Из МассивВозможныхТиповСлова Цикл
Если ВозможныйТипСлова = "Конструктор" Тогда
КлючПоиска = Новый Структура("ТипКонтекста, ТипСлова, ЯзыкПрограммы, ТипЯзыка", Слово, ВозможныйТипСлова, ЯзыкПрограммы, "");
Иначе
КлючПоиска = Новый Структура("НСлово, ТипСлова, ЯзыкПрограммы, ТипЯзыка", Слово, ВозможныйТипСлова, ЯзыкПрограммы, "");
КонецЕсли;
НайденныеСтроки = мПлатформа.ТаблицаКонтекстов.НайтиСтроки(КлючПоиска);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока));
КонецЦикла;
НайденныеСтроки = мПлатформа.ТаблицаШаблоновКонтекстов.НайтиСтроки(КлючПоиска);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока));
КонецЦикла;
КонецЦикла;
КлючПоиска = Новый Структура("НСлово, ЯзыкПрограммы", Слово, ЯзыкПрограммы);
НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока));
КонецЦикла;
Возврат ТаблицаСтруктурВозможныхТиповКонтекста;
КонецФункции // НайтиВозможныеСтрокиОписанияСлова()
// Открывает форму синтакс-помощника и загружает в нее нужную страницу, подсвечивая заданную строку.
//
// Параметры:
// ВнутреннийПутьКОписанию – Строка – внутренний путь к странице синтакс-помощника;
// СтрокаДляПодсветки – Строка – которую нужно подсветить в тексте страницы.
//
// Возвращаемое значение:
// Форма.
//
Функция ОткрытьСтраницуСинтаксПомощникаЛкс(ВнутреннийПутьКОписанию, СтрокаДляПодсветки = "", ВладелецФормы = Неопределено, КлючУникальности = Неопределено) Экспорт
Если ВнутреннийПутьКОписанию = "" Тогда
Возврат Неопределено;
КонецЕсли;
ФормаСправка = ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма", , , КлючУникальности);
ФормаСправка.ВладелецФормы = ВладелецФормы;
ФормаСправка.ОткрытьАдрес(ВнутреннийПутьКОписанию, СтрокаДляПодсветки);
ФормаСправка.ВладелецФормы = Неопределено;
Возврат ФормаСправка;
КонецФункции // ОткрытьСтраницуСинтаксПомощникаЛкс()
// Обходит строки табличного поля и имитирует редактирование и выбор пользователем заданного значения.
//
// Параметры:
// ТабличноеПоле - ТабличноеПоле;
// ЗначениеОбработки - Произвольные - значение, которое будем записывать в ячейки;
// *ФормаИнициатор - Форма, *Неопределено - форма, от имени которой будет записывать;
// *ТипИсточника – Строка, *Неопределено – "ТаблицаЗначений", "ТабличнаяЧасть";
// *Колонка – КолонкаТабличногоПоля, *Неопределено – колонка в которой обходим ячейки, по умолчанию текущая;
// *ТолькоВыделенныеСтроки - Булево, *Истина - обходить только выделенные строки.
//
Процедура УстановитьЗначениеВКолонкеТабличногоПоляТЧИлиТЗЛкс(ТабличноеПоле, ЗначениеОбработки,
ФормаИнициатор = Неопределено, Знач ТипИсточника = Неопределено, Знач Колонка = Неопределено,
Знач ТолькоВыделенныеСтроки = Истина, Знач ИнтерактивноеУстановка = Истина) Экспорт
мПлатформа = ирКэш.Получить();
Если Колонка = Неопределено Тогда
Колонка = ТабличноеПоле.ТекущаяКолонка;
Иначе
ТабличноеПоле.ТекущаяКолонка = Колонка;
КонецЕсли;
ЗначениеТабличногоПоля = ТабличноеПоле.Значение;
Если ТипИсточника = "" Тогда
ТипЗначенияТабличногоПоля = ТипЗнч(ЗначениеТабличногоПоля);
Если ТипЗначенияТабличногоПоля = Тип("ТаблицаЗначений") Тогда
ТипИсточника = "ТаблицаЗначений";
ИначеЕсли ТипЗначенияТабличногоПоля = Тип("ДеревоЗначений") Тогда
ТипИсточника = "ДеревоЗначений";
Иначе
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
СтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзКонкретногоТипа(ТипЗначенияТабличногоПоля);
Если Найти(СтруктураТипа.ИмяОбщегоТипа, "<Имя табличной части>") > 0 Тогда
ТипИсточника = "ТабличнаяЧасть";
ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "НаборЗаписей.") > 0 Тогда
ТипИсточника = "НаборЗаписей";
КонецЕсли;
КонецЕсли;
КонецЕсли;
ЕстьОтборСтрок = Ложь
Или ТипИсточника = "ТабличнаяЧасть"
Или ТипИсточника = "НаборЗаписей";
Если ТолькоВыделенныеСтроки Тогда
Если Истина
И ТабличноеПоле.ВыделенныеСтроки.Количество() = 1
И ТипИсточника <> "ДеревоЗначений"
Тогда
ТекстОтбора = "";
Если ЕстьОтборСтрок Тогда
ТекстОтбора = " удовлетворяющие отбору";
КонецЕсли;
Ответ = Вопрос("Выделена только одна строка. Хотите обработать все" + ТекстОтбора + " строки?",
РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Да Тогда
ТолькоВыделенныеСтроки = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КлючиСтрокДляОбработки = Новый Массив;
Если ТолькоВыделенныеСтроки Тогда
Для Каждого ВыделеннаяСтрока Из ТабличноеПоле.ВыделенныеСтроки Цикл
КлючиСтрокДляОбработки.Добавить(ВыделеннаяСтрока);
КонецЦикла;
Иначе
Если ЕстьОтборСтрок Тогда
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ЗначениеТабличногоПоля);
Построитель.ВыбранныеПоля.Очистить();
Построитель.ВыбранныеПоля.Добавить("НомерСтроки");
СкопироватьОтборЛкс(Построитель.Отбор, ТабличноеПоле.ОтборСтрок, Истина);
ТаблицаРезультата = Построитель.Результат.Выгрузить();
Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл
КлючиСтрокДляОбработки.Добавить(СтрокаРезультата.НомерСтроки - 1);
КонецЦикла;
ИначеЕсли ТипИсточника = "ТаблицаЗначений" Тогда
Для Каждого СтрокаТаблицы Из ТабличноеПоле.Значение Цикл
КлючиСтрокДляОбработки.Добавить(СтрокаТаблицы);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Индикатор = ПолучитьИндикаторПроцессаЛкс(КлючиСтрокДляОбработки.Количество(), "Групповая установка значения");
// Нужно встать на редактируемую колонку, чтобы сработал режим редактирования
Для Каждого КлючСтроки Из КлючиСтрокДляОбработки Цикл
ОбработатьИндикаторЛкс(Индикатор);
Если ТипЗнч(КлючСтроки) = Тип("Число") Тогда
ТекущаяСтрока = ТабличноеПоле.Значение[КлючСтроки];
Иначе
ТекущаяСтрока = КлючСтроки;
КонецЕсли;
Если ТипЗнч(ЗначениеОбработки) = Тип("Структура") Тогда
ЗаполнитьЗначенияСвойств(ЗначениеОбработки.Параметры, ТекущаяСтрока);
НовоеЗначение = ВычислитьВыражение(ЗначениеОбработки.Формула, ЗначениеОбработки.Параметры);
Иначе
НовоеЗначение = ЗначениеОбработки;
КонецЕсли;
Если ИнтерактивноеУстановка Тогда
ТабличноеПоле.ТекущаяСтрока = ТекущаяСтрока;
//ТабличноеПоле.ИзменитьСтроку();
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначение, ФормаИнициатор);
ТабличноеПоле.ЗакончитьРедактированиеСтроки(Ложь);
Иначе
ТекущаяСтрока[Колонка.Имя] = НовоеЗначение;
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс(Индикатор);
КонецПроцедуры // ИнтерактивноУстановитьЗначениеВКолонкеТабличногоПоляТЧИлиТЗ()
Процедура ОформитьФонТекущейСтрокиЛкс(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
Если Элемент.ТекущаяСтрока = ДанныеСтроки Тогда
ОформлениеСтроки.ЦветФона = WebЦвета.СветлоНебесноГолубой;
КонецЕсли;
КонецПроцедуры
Функция ПроверитьЗапуститьОтладчик(Знач ВремяОжиданияЗапуска = 5) Экспорт
ИдентификаторПроцессаОтладчика = Неопределено;
Платформа = ирКэш.Получить();
ПортОтладки = Платформа.ПолучитьПортДляПодключенияОтладчика(ИдентификаторПроцессаОтладчика);
Если ИдентификаторПроцессаОтладчика = Неопределено Тогда
//Если Не УФ(сПроверитьДоступностьКонфигуратора) Тогда
// Сообщить("Конфигуратор уже открыт, но отладка не подключена. Выполните подключение отладчика вручную");
// Перейти ~Конец;
//КонецЕсли;
// Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1003164#1003164
Если Платформа.ВерсияПлатформы = 802015 Тогда
Предупреждение("Из-за ошибки платформы 8.2.15 запуск и подключение отладчика необходимо выполнять вручную", 20);
Возврат Неопределено;
КонецЕсли;
Если ПортОтладки = Неопределено Тогда
Предупреждение("Включите разрешение отладки в главном меню ""Сервис/Параметры/Системные"" и повторите операцию снова");
Возврат Неопределено;
КонецЕсли;
ПараметрыЗапуска = "CONFIG /DEBUG /DEBUGTARGET""tcp://127.0.0.1:" + ПортОтладки + """";
ЗапуститьСистему(ПараметрыЗапуска);
Платформа.Sleep(ВремяОжиданияЗапуска);
Если ИдентификаторПроцессаОтладчика = Неопределено Тогда
ИдентификаторПроцессаОтладчика = 0;
КонецЕсли;
Пока Истина Цикл
Платформа.ПолучитьПортДляПодключенияОтладчика(ИдентификаторПроцессаОтладчика);
Если ИдентификаторПроцессаОтладчика = Неопределено Тогда
Ответ = Вопрос("Отладчик еще не подключился. Повторить снова?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Прервать;
КонецЦикла;
Иначе
Платформа.АктивизироватьОкноПроцесса1С8(Число(ИдентификаторПроцессаОтладчика));
КонецЕсли;
Если ИдентификаторПроцессаОтладчика <> Неопределено Тогда
Результат = Число(ИдентификаторПроцессаОтладчика);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОткрытьСсылкуЯчейкиВРедактореОбъектаБДЛкс(ТабличноеПоле, ИмяКолонки = "") Экспорт
Если ТабличноеПоле.ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Если ТабличноеПоле.ТекущаяКолонка = Неопределено Тогда
Возврат;
КонецЕсли;
ИмяКолонки = ТабличноеПоле.ТекущаяКолонка.Данные;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Возврат;
КонецЕсли;
ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные[ИмяКолонки];
XMLТип = XMLТипЗнч(ЗначениеЯчейки);
Если XMLТип = Неопределено Тогда
Возврат;
КонецЕсли;
Если Найти(XMLТип.ИмяТипа, "Ref.") = 0 Тогда
Возврат;
КонецЕсли;
//Если Ложь
// Или Найти(XMLТип.ИмяТипа, "EnumRef.") > 0
// Или Найти(XMLТип.ИмяТипа, "BusinessProcessRoutePointRef.") > 0
//Тогда
// ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеЯчейки)),, Истина,,,, ЗначениеЯчейки);
//Иначе
ОткрытьСсылкуВРедактореОбъектаБДЛкс(ЗначениеЯчейки);
//КонецЕсли;
КонецПроцедуры
Функция ОткрытьСсылкуВРедактореОбъектаБДЛкс(КлючОбъекта, пИскомоеЗначение = Неопределено) Экспорт
Форма = ПолучитьФормуСсылки(КлючОбъекта, пИскомоеЗначение);
Форма.Открыть();
Возврат Форма;
КонецФункции
Функция ОткрытьОбъектВРедактореОбъектаБДЛкс(ОбъектБД, пИскомоеЗначение = Неопределено, КлючУникальности = Неопределено) Экспорт
Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма",,, КлючУникальности);
#Если Сервер И Не Сервер Тогда
Форма = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
Форма.мПараметрКлючИлиОбъект = ОбъектБД;
Форма.мПараметрПрочитатьОбъект = Ложь;
Форма.мПараметрИскомоеЗначение = пИскомоеЗначение;
Форма.Открыть();
Возврат Форма;
КонецФункции
Функция ПолучитьФормуСсылки(КлючОбъекта, пИскомоеЗначение = Неопределено)
Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма",,, КлючОбъекта);
#Если Сервер И Не Сервер Тогда
Форма = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
Форма.мПараметрКлючИлиОбъект = КлючОбъекта;
Форма.мПараметрПрочитатьОбъект = Истина;
Форма.мПараметрИскомоеЗначение = пИскомоеЗначение;
Возврат Форма;
КонецФункции
Процедура НайтиИПоказатьСсылкиНаОбъектБД(СсылкаНаКоторуюИщемСсылки) Экспорт
Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма");
#Если Сервер И Не Сервер Тогда
Форма = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
Форма.мПараметрКлючИлиОбъект = СсылкаНаКоторуюИщемСсылки;
Форма.Открыть();
Форма.НайтиИПоказатьСсылкиВФорме();
КонецПроцедуры // НайтиСсылки()
// ВариантПросмотра - Строка - "Компактный", "ЯзыкЗапросов", "ВстроенныйЯзык", ...
Функция ПолучитьФормуТекстаЛкс(Текст, Знач Заголовок = "", ВариантПросмотра = "Компактный", ТолькоПросмотр = Ложь, КлючУникальности = Неопределено, ВладелецФормы = Неопределено) Экспорт
Если КлючУникальности = Неопределено Тогда
КлючУникальности = Новый УникальныйИдентификатор();
КонецЕсли;
ФормаПросмотра = ирКэш.Получить().ПолучитьФорму("Текст", ВладелецФормы, КлючУникальности);
ФормаПросмотра.НачальноеЗначениеВыбора = Текст;
ФормаПросмотра.РекомендуемыйВариант = ВариантПросмотра;
ФормаПросмотра.ТолькоПросмотр = ТолькоПросмотр;
Если Не ЗначениеЗаполнено(Заголовок) Тогда
//Заголовок = ФормаПросмотра.Заголовок;
Заголовок = ""; // Чтобы при повторном открытии не оставался старый текст
КонецЕсли;
ФормаПросмотра.Заголовок = Заголовок;
Возврат ФормаПросмотра;
КонецФункции
Функция ОткрытьТекстЛкс(Текст, Знач Заголовок = "", ВариантПросмотра = "Компактный", ТолькоПросмотр = Ложь, КлючУникальности = Неопределено, ВладелецФормы = Неопределено) Экспорт
ФормаПросмотра = ПолучитьФормуТекстаЛкс(Текст, Заголовок, ВариантПросмотра, ТолькоПросмотр, КлючУникальности, ВладелецФормы);
ФормаПросмотра.Открыть();
Возврат ФормаПросмотра;
КонецФункции
Процедура ПолеВводаТекста_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка) Экспорт
Если ТипЗнч(Элемент.Значение) = Тип("Строка") Тогда
СтандартнаяОбработка = Ложь;
ФормаРедактора = ирКэш.Получить().ПолучитьФорму("Текст", Элемент, Новый УникальныйИдентификатор);
ФормаРедактора.РежимВыбора = Истина;
ФормаРедактора.НачальноеЗначениеВыбора = Элемент.Значение;
ФормаРедактора.Открыть();
КонецЕсли;
КонецПроцедуры
Функция ПолучитьПутьКДаннымКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, Колонка = Неопределено) Экспорт
Если Колонка = Неопределено Тогда
Колонка = ТабличноеПоле.ТекущаяКолонка;
КонецЕсли;
Если Истина
И Колонка <> Неопределено
И ТабличноеПоле.ТекущиеДанные <> Неопределено
Тогда
ДанныеКолонки = Колонка.Данные;
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
ДанныеКолонки = Колонка.ДанныеФлажка;
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
Если Ложь
Или ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений")
Или ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений")
Тогда
ДанныеКолонки = Колонка.ДанныеКартинки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ДанныеКолонки;
КонецФункции
Процедура ТабличноеПоле_ОтборБезЗначенияВТекущейКолонке_КнопкаЛкс(Знач ТабличноеПоле) Экспорт
ДанныеКолонки = ПолучитьПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
Возврат;
КонецЕсли;
Попытка
Отбор = ТабличноеПоле.Значение.Отбор;
Исключение
Отбор = ТабличноеПоле.ОтборСтрок;
КонецПопытки;
//:Отбор = Новый ("Отбор");
ЭлементОтбора = Отбор[ДанныеКолонки];
ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные[ДанныеКолонки];
Если ЭлементОтбора.Использование Тогда
Если ЭлементОтбора.ВидСравнения = ВидСравнения.НеРавно Тогда
Если Ложь
Или ТипЗнч(ЗначениеЯчейки) <> Тип("Булево")
Или ЭлементОтбора.ТипЗначения.Типы().Количество() > 1
Тогда
СписокЗначений = Новый СписокЗначений;
СписокЗначений.Добавить(ЭлементОтбора.Значение);
СписокЗначений.Добавить(ЗначениеЯчейки);
ЭлементОтбора.ВидСравнения = ВидСравнения.НеВСписке;
ЭлементОтбора.Значение = СписокЗначений;
КонецЕсли;
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравнения.НеВСписке Тогда
СписокЗначений = ЭлементОтбора.Значение;
СписокЗначений.Добавить(ЗначениеЯчейки);
// Для обновления отбора
ЭлементОтбора.Использование = Ложь;
ЭлементОтбора.Использование = Истина;
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке Тогда
СписокЗначений = ЭлементОтбора.Значение;
СписокЗначений.Удалить(СписокЗначений.НайтиПоЗначению(ЗначениеЯчейки));
// Для обновления отбора
ЭлементОтбора.Использование = Ложь;
ЭлементОтбора.Использование = Истина;
Иначе
ЭлементОтбора.Использование = Ложь;
КонецЕсли;
КонецЕсли;
Если Не ЭлементОтбора.Использование Тогда
ЭлементОтбора.Использование = Истина;
Если Истина
И ЭлементОтбора.ТипЗначения.СодержитТип(Тип("Строка"))
И ЭлементОтбора.ТипЗначения.КвалификаторыСтроки.Длина = 0
Тогда
Если Не ЗначениеЗаполнено(ЗначениеЯчейки) Тогда
// Особенность платформы
ЭлементОтбора.ВидСравнения = ВидСравнения.Содержит;
Иначе
ЭлементОтбора.ВидСравнения = ВидСравнения.НеСодержит;
КонецЕсли;
Иначе
ЭлементОтбора.ВидСравнения = ВидСравнения.НеРавно;
КонецЕсли;
ЭлементОтбора.Значение = ЗначениеЯчейки;
КонецЕсли;
КонецПроцедуры
Функция ЗагрузитьЗначениеИзФайлаЛкс(Расширение = "", ОписаниеФормата = "", Сжатие = Истина) Экспорт
ПолноеИмяФайла = ВыбратьФайлЛкс(, Расширение, ОписаниеФормата);
Если ПолноеИмяФайла = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если Сжатие Тогда
ВременныйКаталог = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ВременныйКаталог);
ЗипЧтение = Новый ЧтениеZipФайла(ПолноеИмяФайла);
ЗипЧтение.ИзвлечьВсе(ВременныйКаталог);
ПолноеИмяФайла = ВременныйКаталог + "\" + ЗипЧтение.Элементы[0].Имя;
КонецЕсли;
ЧтениеХМЛ = Новый ЧтениеXML;
ЧтениеХМЛ.ОткрытьФайл(ПолноеИмяФайла);
Попытка
//Результат = ЗначениеИзФайла(ВыборФайла.ПолноеИмяФайла);
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеХМЛ);
Исключение
Сообщить(ОписаниеОшибки());
Результат = Неопределено;
КонецПопытки;
ЧтениеХМЛ.Закрыть();
Если Сжатие Тогда
УдалитьФайлы(ВременныйКаталог, "*");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СохранитьЗначениеВФайлИнтерактивноЛкс(Значение, Расширение = "", ОписаниеФормата = "", Сжатие = Истина, УровеньСжатия = Неопределено) Экспорт
ПолноеИмяФайла = ВыбратьФайлЛкс(Ложь, Расширение, ОписаниеФормата);
Если ПолноеИмяФайла = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Результат = СохранитьЗначениеВФайлЛкс(Значение, ПолноеИмяФайла, Сжатие, УровеньСжатия);
Возврат Результат;
КонецФункции
Функция СохранитьЗначениеВФайлЛкс(Знач Значение, Знач ПолноеИмяФайла, Сжатие = Ложь, УровеньСжатия = Неопределено) Экспорт
ЗаписьХМЛ = Новый ЗаписьXML;
ЗаписьХМЛ.ОткрытьФайл(ПолноеИмяФайла);
Попытка
//ЗначениеВФайл(ВыборФайла.ПолноеИмяФайла, Значение);
СериализаторXDTO.ЗаписатьXML(ЗаписьХМЛ, Значение);
Результат = Истина;
Исключение
Сообщить(ОписаниеОшибки());
Результат = Ложь;
КонецПопытки;
ЗаписьХМЛ.Закрыть();
Если Сжатие Тогда
ВременныйКаталог = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ВременныйКаталог);
Файл = Новый Файл(ПолноеИмяФайла);
ИмяВременногоФайла = ВременныйКаталог + "\" + Файл.Имя;
ПереместитьФайл(Файл.ПолноеИмя, ИмяВременногоФайла);
ЗаписьЗип = Новый ЗаписьZipФайла(ПолноеИмяФайла,,,, УровеньСжатия);
ЗаписьЗип.Добавить(ИмяВременногоФайла);
ЗаписьЗип.Записать();
УдалитьФайлы(ВременныйКаталог, "*");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ВыбратьРедактируемыйТипЛкс(ОграничениеТипа = Неопределено, ТолькоПросмотр = Ложь, НачальноеЗначениеВыбора = Неопределено) Экспорт
Если ОграничениеТипа = Неопределено Тогда
ОграничениеТипа = Новый ОписаниеТипов;
КонецЕсли;
ФормаРедактора = ирКэш.Получить().ПолучитьФорму("ВыборРедактируемыхТипов");
ФормаРедактора.ОграничениеТипа = ОграничениеТипа;
ФормаРедактора.НачальноеЗначениеВыбора = НачальноеЗначениеВыбора;
ФормаРедактора.МножественныйВыбор = Ложь;
ФормаРедактора.ТолькоПросмотр = ТолькоПросмотр;
РезультатВыбора = ФормаРедактора.ОткрытьМодально();
Возврат РезультатВыбора;
КонецФункции // РедактироватьДопустимыеТипы()
Функция РедактироватьОписаниеРедактируемыхТиповЛкс(ОграничениеТипаИлиПолеВвода, ТолькоПросмотр = Ложь) Экспорт
Если ТипЗнч(ОграничениеТипаИлиПолеВвода) = Тип("ОписаниеТипов") Тогда
ВладелецФормы = Неопределено;
ОграничениеТипа = ОграничениеТипаИлиПолеВвода;
Иначе
ВладелецФормы = ОграничениеТипаИлиПолеВвода;
ОграничениеТипа = ОграничениеТипаИлиПолеВвода.Значение;
КонецЕсли;
ФормаРедактора = ирКэш.Получить().ПолучитьФорму("ВыборРедактируемыхТипов", ВладелецФормы);
//ФормаРедактора.ОграничениеТипа = ОграничениеТипа;
ФормаРедактора.НачальноеЗначениеВыбора = ОграничениеТипа;
ФормаРедактора.МножественныйВыбор = Истина;
ФормаРедактора.ТолькоПросмотр = ТолькоПросмотр;
РезультатВыбора = ФормаРедактора.ОткрытьМодально();
Возврат РезультатВыбора;
КонецФункции // РедактироватьДопустимыеТипы()
// ПолноеИмяНачальногоТипаВыбора - Строка - полное имя метаданного
Функция ОткрытьПодборСВыборомТипаЛкс(ВладелецФормы, ОписаниеТипов = Неопределено, Знач НачальноеЗначениеВыбора = Неопределено, ИспользоватьДинамическийСписокИР = Истина) Экспорт
Если ТипЗнч(ОписаниеТипов) = Тип("Строка") Тогда
ДоступныеОбъекты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ОписаниеТипов, ",", Истина);
ИначеЕсли ОписаниеТипов <> Неопределено Тогда
ДоступныеОбъекты = Новый Массив();
Для Каждого Тип Из ОписаниеТипов.Типы() Цикл
ДоступныеОбъекты.Добавить(ПолучитьПолноеИмяМДТипаЛкс(Тип));
КонецЦикла;
КонецЕсли;
Если НачальноеЗначениеВыбора <> Неопределено Тогда
ПолноеИмяНачальногоТипаВыбора = ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(НачальноеЗначениеВыбора));
КонецЕсли;
Если Ложь
Или ДоступныеОбъекты = Неопределено
Или ДоступныеОбъекты.Количество() = 0
Или ДоступныеОбъекты.Количество() > 1
Тогда
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", ВладелецФормы);
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ДоступныеОбъекты", ДоступныеОбъекты);
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", ПолноеИмяНачальногоТипаВыбора);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
Результат = Форма.ОткрытьМодально();
Если Результат = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ПолноеИмяМД = Результат.ПолноеИмяОбъекта;
Иначе
ПолноеИмяМД = ДоступныеОбъекты[0];
КонецЕсли;
Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда
Возврат Неопределено;
КонецЕсли;
Если ПолноеИмяНачальногоТипаВыбора <> ПолноеИмяМД Тогда
НачальноеЗначениеВыбора = Неопределено;
КонецЕсли;
ТекущаяСтрока = Неопределено;
Отбор = Неопределено;
Если НачальноеЗначениеВыбора <> Неопределено Тогда
ИмяXMLТипа = СериализаторXDTO.XMLТипЗнч(НачальноеЗначениеВыбора).ИмяТипа;
Если Ложь
Или Найти(ИмяXMLТипа, "Ref.") > 0
Или Найти(ИмяXMLТипа, "RecordKey.") > 0
Тогда
ТекущаяСтрока = НачальноеЗначениеВыбора;
Иначе
Отбор = НачальноеЗначениеВыбора.Отбор;
КонецЕсли;
КонецЕсли;
ФормаВыбора = ОткрытьФормуСпискаЛкс(ПолноеИмяМД, Отбор, ИспользоватьДинамическийСписокИР, ВладелецФормы, Истина, Истина, ТекущаяСтрока);
Возврат ФормаВыбора;
КонецФункции
Функция ПолучитьФормуВыбораОбъектаМетаданныхЛкс(ВладелецФормы, КлючУникальности, НачальноеЗначениеВыбора, МножественныйВыбор = Ложь, ОтображатьСсылочныеОбъекты = Ложь,
ОтображатьВыборочныеТаблицы = Ложь, ОтображатьРегистры = Ложь, ОтображатьПоследовательности = Ложь, ОтображатьКонстанты = Ложь, ОтображатьТабличныеЧасти = Ложь,
ОтображатьТаблицыИзменений = Ложь, ОтображатьВнешниеИсточникиДанных = Ложь, ЗапретитьВыбиратьСсылочныеОбъекты = Ложь, ТолькоИспользованиеПолнотекстовогоПоиска = Ложь) Экспорт
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", ВладелецФормы, КлючУникальности);
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора);
лСтруктураПараметров.Вставить("ОтображатьКонстанты", ОтображатьКонстанты);
лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", ОтображатьВыборочныеТаблицы);
лСтруктураПараметров.Вставить("ОтображатьТаблицыИзменений", ОтображатьТаблицыИзменений);
лСтруктураПараметров.Вставить("ОтображатьТабличныеЧасти", ОтображатьТабличныеЧасти);
лСтруктураПараметров.Вставить("ОтображатьРегистры", ОтображатьРегистры);
лСтруктураПараметров.Вставить("ОтображатьПоследовательности", ОтображатьПоследовательности);
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", ОтображатьСсылочныеОбъекты);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", ОтображатьВнешниеИсточникиДанных);
лСтруктураПараметров.Вставить("МножественныйВыбор", МножественныйВыбор);
лСтруктураПараметров.Вставить("ЗапретитьВыбиратьСсылочныеОбъекты", ЗапретитьВыбиратьСсылочныеОбъекты);
лСтруктураПараметров.Вставить("ТолькоИспользованиеПолнотекстовогоПоиска", ТолькоИспользованиеПолнотекстовогоПоиска);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
Возврат Форма;
КонецФункции
Функция ПолучитьФормуВыбораТаблицыСтруктурыБДЛкс(ЛиИменаБД, ИмяТаблицыХранения = "") Экспорт
Форма = ирОбщий.ПолучитьФормуЛкс("Обработка.ирСтруктураХраненияБД.Форма",,, Истина);
Форма.РежимВыбора = Истина;
Форма.ПараметрИмяТаблицыХранения = ИмяТаблицыХранения;
Форма.ПараметрПоказыватьSDBL = Не ЛиИменаБД;
Форма.ПараметрПоказыватьСУБД = ЛиИменаБД;
Возврат Форма
КонецФункции
Функция РедактироватьАлгоритмЛкс(СтрокаXMLАлгоритма, ВнешниеПараметры) Экспорт
#Если Сервер И Не Сервер Тогда
ВнешниеПараметры = Новый ТаблицаЗначений;
#КонецЕсли
СтруктураАлгоритма = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаXMLАлгоритма);
ОбработкаКонсольКода = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольКода");
ФормаКонсоли = ОбработкаКонсольКода.ПолучитьФорму();
КопияПараметров = ВнешниеПараметры.Скопировать();
Если КопияПараметров.Колонки.Найти("Значение") = Неопределено Тогда
КопияПараметров.Колонки.Добавить("Значение");
КонецЕсли;
Если КопияПараметров.Колонки.Найти("Фиксированный") = Неопределено Тогда
КопияПараметров.Колонки.Добавить("Фиксированный");
КонецЕсли;
КопияПараметров.ЗаполнитьЗначения(Истина, "Фиксированный");
Если СтруктураАлгоритма <> Неопределено Тогда
Если СтруктураАлгоритма.Свойство("ТекстАлгоритма") Тогда
ФормаКонсоли.ПараметрТекст = СтруктураАлгоритма.ТекстАлгоритма;
КонецЕсли;
Если СтруктураАлгоритма.Свойство("ВнутренниеПараметры") Тогда
ЗагрузитьВТаблицуЗначенийЛкс(СтруктураАлгоритма.ВнутренниеПараметры, КопияПараметров, Новый Структура("Вход", Истина));
КонецЕсли;
КонецЕсли;
ФормаКонсоли.мСписокВнешнихПараметров = КопияПараметров;
ФормаКонсоли.ОткрытьМодально();
РезультатФормы = ФормаКонсоли.РезультатФормы;
Результат = РезультатФормы <> Неопределено;
Если Результат Тогда
ВнутренниеПараметры = РезультатФормы.Параметры.Скопировать(Новый Структура("Вход, Выход, Фиксированный", Истина, Ложь, Ложь), "Имя, Значение");
СтруктураАлгоритма = Новый Структура("ТекстАлгоритма, ВнутренниеПараметры", РезультатФормы.Текст, ВнутренниеПараметры);
СтрокаXMLАлгоритма = ирОбщий.СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураАлгоритма);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОбработатьСобытиеЛкс(ТаблицаСобытий, ИмяСобытия, выхОписаниеОшибки, П0 = null, П1 = null, П2 = null, П3 = null, П4 = null, П5 = null, П6 = null, П7 = null) Экспорт
СтрокаСобытия = ТаблицаСобытий.Найти(ИмяСобытия, "ИмяСобытия");
СтрокаXMLАлгоритма = СтрокаСобытия.Алгоритм;
Если Не ЗначениеЗаполнено(СтрокаXMLАлгоритма) Тогда
Возврат Истина;
КонецЕсли;
Если ТаблицаСобытий.Колонки.Найти("АлгоритмОбъект") = Неопределено Тогда
ТаблицаСобытий.Колонки.Добавить("АлгоритмОбъект");
КонецЕсли;
АлгоритмОбъект = СтрокаСобытия.АлгоритмОбъект;
Если АлгоритмОбъект = Неопределено Тогда
Попытка
АлгоритмОбъект = ДесериализоватьАлгоритмОбъектЛкс(СтрокаXMLАлгоритма);
Исключение
ВызватьИсключение "Ошибка десериализации алгоритма для события " + ИмяСобытия + ": " + ОписаниеОшибки();
КонецПопытки;
СтрокаСобытия.АлгоритмОбъект = АлгоритмОбъект;
КонецЕсли;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Попытка
Результат = мПлатформа.ВыполнитьМетодАлгоритма(АлгоритмОбъект, 0, П0, П1, П2, П3, П4, П5, П6, П7);
Исключение
//выхОписаниеОшибки = ПолучитьПричинуОшибки(ОписаниеОшибки());
выхОписаниеОшибки = ОписаниеОшибки();
Возврат Ложь;
КонецПопытки;
Возврат Истина;
КонецФункции
Функция ДесериализоватьАлгоритмОбъектЛкс(Знач СтрокаXMLАлгоритма) Экспорт
СтруктураАлгоритма = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаXMLАлгоритма);
АлгоритмОбъект = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирАлгоритмОбъект");
#Если Сервер И Не Сервер Тогда
АлгоритмОбъект = Обработки.ирАлгоритмОбъект.Создать();
#КонецЕсли
АлгоритмОбъект.ТекстАлгоритма = СтруктураАлгоритма.ТекстАлгоритма;
ЗагрузитьВТаблицуЗначенийЛкс(СтруктураАлгоритма.ВнутренниеПараметры, АлгоритмОбъект.Параметры, Новый Структура("Вход", Истина));
Возврат АлгоритмОбъект;
КонецФункции
Процедура ОформитьЯчейкуАлгоритмаВТабличномПолеЛкс(Знач ОформлениеСтроки, ИмяКолонки = "Алгоритм") Экспорт
Если ЗначениеЗаполнено(ОформлениеСтроки.ДанныеСтроки[ИмяКолонки]) Тогда
СтруктураАлгоритма = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(ОформлениеСтроки.ДанныеСтроки[ИмяКолонки],,, Ложь);
Если СтруктураАлгоритма <> Неопределено И СтруктураАлгоритма.Свойство("ТекстАлгоритма") Тогда
ОформлениеСтроки.Ячейки[ИмяКолонки].УстановитьТекст(СокрП(СтруктураАлгоритма.ТекстАлгоритма));
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// ИсторияФайлов - СписокЗначений
// Кнопки - КнопкиКоманднойПанели
Процедура ОбновитьПодменюИсторииФайловЛкс(ИсторияФайлов, Кнопки, ИмяДействия = "ОткрытьФайлИзИстории") Экспорт
Кнопки.Очистить();
ДлинаПредставления = 100;
ДействиеКнопки = Новый Действие(ИмяДействия);
Для Каждого СтрокаФайла Из ИсторияФайлов Цикл
Файл = Новый Файл(СтрокаФайла.Значение);
ДлинаПути = ДлинаПредставления - СтрДлина(Файл.Имя);
Представление = Лев(Файл.Имя, ДлинаПредставления);
Если ДлинаПути > 0 Тогда
Если ДлинаПути < СтрДлина(Файл.Путь) + 3 Тогда
Представление = Лев(Файл.Путь, ДлинаПути) + "...\" + Представление;
Иначе
Представление = Файл.Путь + Представление;
КонецЕсли;
КонецЕсли;
КнопкаФайла = Кнопки.Добавить("_" + Формат(ИсторияФайлов.Индекс(СтрокаФайла), "ЧГ=;ЧН="), ТипКнопкиКоманднойПанели.Действие, Представление, ДействиеКнопки);
КонецЦикла;
КонецПроцедуры
Процедура ДобавитьВИсториюЭлементЛкс(СписокИстории, ЗначениеЭлемента, РазмерИстории = 20) Экспорт
ЭлементИстории = СписокИстории.НайтиПоЗначению(ЗначениеЭлемента);
Если ЭлементИстории <> Неопределено Тогда
СписокИстории.Удалить(ЭлементИстории);
КонецЕсли;
СписокИстории.Вставить(0, ЗначениеЭлемента);
Пока СписокИстории.Количество() > РазмерИстории Цикл
СписокИстории.Удалить(РазмерИстории);
КонецЦикла;
КонецПроцедуры
Процедура ПоместитьТекстВБуферОбменаОСЛкс(Текст) Экспорт
// http://partners.v8.1c.ru/forum/thread.jsp?id=1075241#1075241
Документ = ирКэш.Получить().СлужебноеПолеHtmlДокумента.Документ; // Так падает после нескольких вызовов
//Документ = Новый COMОбъект("HTMLFILE");
Окно = Документ.parentWindow;
Окно.ClipboardData.SetData("Text", Текст);
Конецпроцедуры
Функция ПолучитьТекстИзБуфераОбменаОСЛкс() Экспорт
// http://partners.v8.1c.ru/forum/thread.jsp?id=1075241#1075241
Документ = ирКэш.Получить().СлужебноеПолеHtmlДокумента.Документ; // Так падает после нескольких вызовов
//Документ = Новый COMОбъект("HTMLFILE");
Окно = Документ.parentWindow;
Результат = Окно.ClipboardData.GetData("Text");
Возврат Результат;
КонецФункции
Функция ПолучитьИспользованиеДинамическогоСпискаВместоОсновнойФормыЛкс(ПолноеИмяМД) Экспорт
Возврат ВосстановитьЗначение("ирДинамическийСписок.ВместоОсновной." + ПолноеИмяМД) <> Ложь;
КонецФункции // УстановитьОбъектМетаданных()
// Параметры:
// Отбор - Структура, Отбор, *Неопределено
Функция ОткрытьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено, ВладелецФормы = Неопределено, РежимВыбора = Ложь,
МножественныйВыбор = Ложь, ТекущаяСтрока = Неопределено, Модально = Ложь) Экспорт
ФормаСписка = ПолучитьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор, ИспользоватьДинамическийСписокИР, ВладелецФормы, РежимВыбора, МножественныйВыбор, ТекущаяСтрока);
Если ФормаСписка = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если Модально Тогда
Результат = ФормаСписка.ОткрытьМодально();
Возврат Результат;
Иначе
ФормаСписка.Открыть();
Возврат ФормаСписка;
КонецЕсли;
КонецФункции
// Параметры:
// Отбор - Структура, Отбор, *Неопределено
Функция ПолучитьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено, ВладелецФормы = Неопределено, РежимВыбора = Ложь,
МножественныйВыбор = Ложь, ТекущаяСтрока = Неопределено) Экспорт
Если ТипЗнч(ИмяТаблицыИлиМДИлиТип) = Тип("ОбъектМетаданных") Тогда
ИмяТаблицы = ИмяТаблицыИлиМДИлиТип.ПолноеИмя();
ИначеЕсли ТипЗнч(ИмяТаблицыИлиМДИлиТип) = Тип("Тип") Тогда
ИмяТаблицы = ПолучитьПолноеИмяМДТипаЛкс(ИмяТаблицыИлиМДИлиТип);
Иначе
ИмяТаблицы = ИмяТаблицыИлиМДИлиТип;
КонецЕсли;
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ИмяТаблицы);
//МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД);
Если Ложь
Или ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы)
Или ТипТаблицы = "Изменения"
Или ТипТаблицы = "Перерасчет"
//Или ТипТаблицы = "Внешняя"
//Или МассивФрагментов.Количество() > 2
Тогда
Сообщить("Для таблицы " + ИмяТаблицы + " форма списка не предусмотрена");
Возврат Неопределено;
КонецЕсли;
Если ИспользоватьДинамическийСписокИР = Неопределено Тогда
ИспользоватьДинамическийСписокИР = ПолучитьИспользованиеДинамическогоСпискаВместоОсновнойФормыЛкс(ИмяТаблицы);
КонецЕсли;
Если Истина
И РежимВыбора = Истина
И ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы)
Тогда
ИспользоватьДинамическийСписокИР = Истина; // Потому что у форм списков регистров режим выбора можно включить только через основной элемент управления
КонецЕсли;
Если ТипТаблицы = "Точки" Тогда
ИспользоватьДинамическийСписокИР = Истина;
КонецЕсли;
Если ИспользоватьДинамическийСписокИР = Неопределено Тогда
Ответ = Вопрос("Хотите использовать Динамический список (ИР)?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет);
ИспользоватьДинамическийСписокИР = Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если Истина
И ИспользоватьДинамическийСписокИР
И ТипТаблицы <> "Внешняя"
Тогда
КлючУникальности = ИмяТаблицы;
//Если Не РежимВыбора Тогда
// КлючУникальности = Новый УникальныйИдентификатор;
//КонецЕсли;
ФормаСписка = ирОбщий.ПолучитьФормуЛкс("Обработка.ирДинамическийСписок.Форма",, ВладелецФормы, КлючУникальности);
ФормаСписка.РежимВыбора = РежимВыбора; // Чтобы заголовок сразу правильный сформировался
ФормаСписка.УстановитьОбъектМетаданных(ИмяТаблицы);
ОтборДинамическогоСписка = ФормаСписка.Отбор;
Иначе
Если ТипЗнч(Отбор) = Тип("Отбор") Тогда
СтруктураОтбора = Новый Структура;
Для Каждого ЭлементОтбора Из Отбор Цикл
Если Истина
И ЭлементОтбора.Использование
И ЭлементОтбора.ВидСравнения = ВидСравнения.Равно
Тогда
СтруктураОтбора.Вставить(ЭлементОтбора.Имя, ЭлементОтбора.Значение);
КонецЕсли;
КонецЦикла;
Иначе
СтруктураОтбора = Отбор;
КонецЕсли;
ПараметрыФормы = Новый Структура("РежимВыбора, МножественныйВыбор, ЗакрыватьПриВыборе, ТекущаяСтрока, Отбор",
РежимВыбора, МножественныйВыбор, Не МножественныйВыбор, ТекущаяСтрока, СтруктураОтбора);
Если РежимВыбора Тогда
Попытка
ФормаСписка = ПолучитьФормуЛкс(ИмяТаблицы + ".ФормаВыбора", ПараметрыФормы, ВладелецФормы);
Исключение
// Например у регистров нет форм выбора
КонецПопытки;
КонецЕсли;
Если ФормаСписка = Неопределено Тогда
ФормаСписка = ПолучитьФормуЛкс(ИмяТаблицы + ".ФормаСписка", ПараметрыФормы, ВладелецФормы);
КонецЕсли;
Если ТипЗнч(ФормаСписка) = Тип("Форма") Тогда
Попытка
ОтборДинамическогоСписка = ФормаСписка.Отбор;
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ФормаСписка) = Тип("Форма") Тогда
ФормаСписка.РежимВыбора = РежимВыбора;
ФормаСписка.ЗакрыватьПриВыборе = Не МножественныйВыбор;
ФормаСписка.НачальноеЗначениеВыбора = ТекущаяСтрока;
Попытка
ФормаСписка.МножественныйВыбор = МножественныйВыбор;
Исключение
// Есть не у всех форм
КонецПопытки;
Попытка
ФормаСписка.ПараметрТекущаяСтрока = ТекущаяСтрока;
Исключение
// Есть не у всех форм
КонецПопытки;
КонецЕсли;
Если Истина
И ОтборДинамическогоСписка <> Неопределено
И Отбор <> Неопределено
Тогда
Если ТипЗнч(Отбор) = Тип("Структура") Тогда
Для Каждого КлючИЗначение Из Отбор Цикл
ЭлементОтбора = ОтборДинамическогоСписка.Найти(КлючИЗначение.Ключ);
Если ЭлементОтбора <> Неопределено Тогда
УстановитьЭлементОтбораЛкс(ЭлементОтбора,, КлючИЗначение.Значение);
КонецЕсли;
КонецЦикла;
Иначе
СкопироватьОтборДинамическогоСпискаЛкс(ОтборДинамическогоСписка, Отбор);
КонецЕсли;
КонецЕсли;
Возврат ФормаСписка;
КонецФункции
Процедура ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(ПолеВвода, КлючИстории, ЗапоминатьПоследние = 20, НеЗапоминатьПустыеТипизированные = Истина) Экспорт
Если Ложь
Или (Истина
И Не НеЗапоминатьПустыеТипизированные
И ПолеВвода.Значение <> ПолеВвода.ТипЗначения.ПривестиЗначение(Неопределено))
Или ЗначениеЗаполнено(ПолеВвода.Значение)
Тогда
НовоеЗначениеXML = СохранитьОбъектВВидеСтрокиXMLЛкс(ПолеВвода.Значение);
Если СтрДлина(НовоеЗначениеXML) > 1000 Тогда
Возврат;
КонецЕсли;
КлючНастройки = КлючИстории + "." + ПолеВвода.Имя + ".ПоследниеЗначения";
ПоследниеЗначения = ВосстановитьЗначение(КлючНастройки);
Если ТипЗнч(ПоследниеЗначения) <> Тип("Массив") Тогда
ПоследниеЗначения = Новый Массив;
КонецЕсли;
ПоследниеЗначенияXML = Новый Массив;
Для Каждого Значение Из ПоследниеЗначения Цикл
ПоследниеЗначенияXML.Добавить(СохранитьОбъектВВидеСтрокиXMLЛкс(Значение));
КонецЦикла;
Индекс = ПоследниеЗначенияXML.Найти(НовоеЗначениеXML);
Если Индекс <> Неопределено Тогда
ПоследниеЗначения.Удалить(Индекс);
КонецЕсли;
ПоследниеЗначения.Вставить(0, ПолеВвода.Значение);
Для Счетчик = ЗапоминатьПоследние По ПоследниеЗначения.ВГраница() Цикл
ПоследниеЗначения.Удалить(ЗапоминатьПоследние);
КонецЦикла;
СохранитьЗначение(КлючНастройки, ПоследниеЗначения);
КонецЕсли;
КонецПроцедуры
Процедура ПолеВводаСИсториейВыбора_НачалоВыбораИзСпискаЛкс(ПолеВвода, КлючИстории) Экспорт
// Запоминать последние
КлючНастройки = КлючИстории + "." + ПолеВвода.Имя + ".ПоследниеЗначения";
ПоследниеЗначения = ВосстановитьЗначение(КлючНастройки);
Если ТипЗнч(ПоследниеЗначения) = Тип("Массив") Тогда
ПолеВвода.СписокВыбора.Очистить();
Для Каждого Значение Из ПоследниеЗначения Цикл
НовыйЭлемент = ПолеВвода.СписокВыбора.Добавить(Значение);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ПолеФайловогоКаталога_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка) Экспорт
СтандартнаяОбработка = Ложь;
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
ВыборФайла.Каталог = Элемент.Значение;
Если Не ВыборФайла.Выбрать() Тогда
Возврат;
КонецЕсли;
ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, ВыборФайла.Каталог);
КонецПроцедуры
Функция ОткрытьСсылкуВСпискеЛкс(Ссылка) Экспорт
ПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)).ПолноеИмя();
СтруктураПараметры = Новый Структура;
СтруктураПараметры.Вставить("ТекущаяСтрока", Ссылка);
ФормаСписка = ПолучитьФормуЛкс(ПолноеИмяМД + ".ФормаСписка", СтруктураПараметры, , Новый УникальныйИдентификатор);
ФормаСписка.Открыть();
Возврат ФормаСписка;
КонецФункции
// ИменаКолонок - Строка - имена колонок через запятую
Процедура ТабличноеПоле_ОтобразитьФлажкиЛкс(ОформлениеСтроки, Знач ИменаКолонок) Экспорт
Если ТипЗнч(ИменаКолонок) = Тип("Строка") Тогда
ИменаКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаКолонок, ",", Истина);
КонецЕсли;
Для Каждого ИмяКолонки Из ИменаКолонок Цикл
Ячейка = ОформлениеСтроки.Ячейки[ИмяКолонки];
//Если Ячейка.ТолькоПросмотр Тогда
// Продолжить;
//КонецЕсли;
Если ТипЗнч(Ячейка.Значение) = Тип("Булево") Тогда
Ячейка.УстановитьФлажок(Ячейка.Значение);
Ячейка.УстановитьТекст("");
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ТабличноеПоле__ПриИзмененииФлажкаЛкс(Элемент, Знач Колонка) Экспорт
Если ТипЗнч(Колонка.ЭлементУправления) = Тип("ПолеВвода") Тогда
ОформлениеСтроки = Элемент.ОформлениеСтроки(Элемент.ТекущаяСтрока);
Ячейка = ОформлениеСтроки.Ячейки[Колонка.Имя];
Если Не Ячейка.ТолькоПросмотр Тогда
Если Истина
И Колонка.Данные = ""
И Колонка.ДанныеФлажка = ""
Тогда
Колонка.ЭлементУправления.Значение = Не Ячейка.Значение;
//ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(Элемент, Колонка, Не ОформлениеСтроки.Ячейки[Колонка.Имя].Значение);
Иначе
//МетаданныеТипа = глПолучитьМетаданныеТипа(ТипЗнч(Элемент.Значение), "ТипСписка", Истина);
//РедактированиеВДиалоге = Ложь;
//Если Истина
// И МетаданныеТипа <> Неопределено
// И МетаданныеТипа.КлассМетаданных.Предок = оСсылочный
//Тогда
// Попытка
// ВыбранныйСпособРедактирования = Элемент.СпособРедактирования;
// Исключение
// КонецПопытки;
// РедактированиеВДиалоге = ВыбранныйСпособРедактирования <> СпособРедактированияСписка.ВСписке;
//КонецЕсли;
//РазрешитьИзменение = Истина;
//Если РедактированиеВДиалоге Тогда
//Иначе
//Элемент.ЗакончитьРедактированиеСтроки(Ложь);
Элемент.ИзменитьСтроку();
ЗначениеЯчейки = Колонка.ЭлементУправления.Значение;
Если ТипЗнч(ЗначениеЯчейки) = Тип("Булево") Тогда
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(Элемент, Колонка, Не ЗначениеЯчейки, , , Ложь);
//Элемент.ТекущаяКолонка = Колонка;
КонецЕсли;
Элемент.ЗакончитьРедактированиеСтроки(Ложь);
//КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьПиктограммуТипаЛкс(Тип) Экспорт
ИмяОбщегоТипа = Неопределено;
КлючПоиска = Новый Структура("ИД", ПолучитьИдентификаторТипаЛкс(Тип));
мПлатформа = ирКэш.Получить();
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
Иначе
//СтруктураТипа = ирКэш.Получить().ПолучитьСтруктуруТипаИзКонкретногоТипа(Тип);
//ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
ОбъектМД = Метаданные.НайтиПоТипу(Тип);
Если ОбъектМД <> Неопределено Тогда
ТекущееИмяТипа = ОбъектМД.ПолноеИмя();
ИмяОбщегоТипа = ПолучитьПервыйФрагментЛкс(ТекущееИмяТипа);
КонецЕсли;
КонецЕсли;
Картинка = Неопределено;
Если ИмяОбщегоТипа <> Неопределено Тогда
ИмяКартинки = "ир" + ПолучитьПервыйФрагментЛкс(ИмяОбщегоТипа);
Попытка
Картинка = ПолучитьОбщуюКартинкуЛкс(ИмяКартинки);
Исключение
ИмяКартинки = ИмяОбщегоТипа;
Попытка
Картинка = БиблиотекаКартинок[ИмяКартинки];
Исключение
КонецПопытки;
КонецПопытки;
КонецЕсли;
Возврат Картинка;
КонецФункции
Функция ПрочитатьДополнительныеПоляСсылающихсяОбъектовЛкс(Знач ТабличноеПоле, Знач КомпоновщикДопПолей, Знач ТаблицаДанных = Неопределено, ИмяПоляСсылки = "Данные") Экспорт
#Если Сервер И Не Сервер Тогда
КомпоновщикДопПолей = Новый КомпоновщикНастроекКомпоновкиДанных;
#КонецЕсли
КолонкаДата = ТабличноеПоле.Колонки.Дата;
Если ТаблицаДанных = Неопределено Тогда
ТаблицаДанных = ТабличноеПоле.Значение;
КонецЕсли;
КомпоновщикДопПолей.Восстановить(СпособВосстановленияНастроекКомпоновкиДанных.Полное);
МассивДопПолей = Новый Структура();
ДопустимоеЧислоДопПолей = 5;
Счетчик = 1;
СтрокаПорядка = "";
СтрокаВыбора = "";
Для Каждого ПолеПорядка Из КомпоновщикДопПолей.Настройки.Порядок.Элементы Цикл
Если ПолеПорядка.Использование Тогда
ИмяПоля = "" + ПолеПорядка.Поле;
ИмяКолонки = "Реквизит" + Счетчик;
ДоступноеПоле = КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(ПолеПорядка.Поле);
Если Счетчик > ДопустимоеЧислоДопПолей Тогда
Сообщить("Дополнительное поле """ + ДоступноеПоле.Заголовок + """ пропущено, т.к. допускается не более " + ДопустимоеЧислоДопПолей + " полей");
Продолжить;
КонецЕсли;
МассивДопПолей.Вставить(ИмяКолонки, ИмяПоля);
КолонкаТП = ТабличноеПоле.Колонки[ИмяКолонки];
КолонкаТП.Видимость = Истина;
КолонкаТП.ТекстШапки = ДоступноеПоле.Заголовок;
Если СтрокаПорядка <> "" Тогда
СтрокаПорядка = СтрокаПорядка + ",";
КонецЕсли;
СтрокаПорядка = СтрокаПорядка + ИмяКолонки + " ";
Если ПолеПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда
СтрокаПорядка = СтрокаПорядка + "Возр";
Иначе
СтрокаПорядка = СтрокаПорядка + "Убыв";
КонецЕсли;
СтрокаВыбора = СтрокаВыбора + ",
| Т." + ИмяПоля + " КАК " + ИмяКолонки;
Счетчик = Счетчик + 1;
КонецЕсли;
КонецЦикла;
Если Не ЗначениеЗаполнено(СтрокаПорядка) Тогда
СтрокаПорядка = "Дата";
КонецЕсли;
Для Счетчик = Счетчик По ДопустимоеЧислоДопПолей Цикл
ИмяКолонки = "Реквизит" + Счетчик;
КолонкаТП = ТабличноеПоле.Колонки[ИмяКолонки];
КолонкаТП.Видимость = Ложь;
КонецЦикла;
СтандартныеРеквизиты = Новый Структура;
СтандартныеРеквизиты.Вставить("ПометкаУдаления", "ЛОЖЬ");
СтандартныеРеквизиты.Вставить("Проведен", "ЛОЖЬ");
СтандартныеРеквизиты.Вставить("ЭтоГруппа", "ЛОЖЬ");
СтандартныеРеквизиты.Вставить("Дата", "ДАТАВРЕМЯ(1,1,1)");
Для Каждого КлючИЗначение Из СтандартныеРеквизиты Цикл
ИмяРеквизита = КлючИЗначение.Ключ;
Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(Новый ПолеКомпоновкиДанных("Объект." + ИмяРеквизита)) = Неопределено Тогда
Продолжить;
КонецЕсли;
СтрокаВыбора = СтрокаВыбора + ",
| ЕСТЬNULL(Т.Объект." + ИмяРеквизита + ", " + КлючИЗначение.Значение + ") КАК " + ИмяРеквизита;
КонецЦикла;
Если ТипЗнч(ТаблицаДанных) <> Тип("ТаблицаЗначений") Тогда
КопияТаблицыДанных = ТаблицаДанных.Выгрузить(, ИмяПоляСсылки);
Иначе
КопияТаблицыДанных = ТаблицаДанных;
КонецЕсли;
КопияТаблицыДанных = ирОбщий.ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(КопияТаблицыДанных,, ИмяПоляСсылки);
ОписаниеТиповСсылки = КопияТаблицыДанных.Колонки[ИмяПоляСсылки].ТипЗначения;
ПорцияОбъектов = Новый ТаблицаЗначений;
ПорцияОбъектов.Колонки.Добавить("Объект", ОписаниеТиповСсылки);
ПорцияОбъектов.Колонки.Добавить("Индекс", Новый ОписаниеТипов("Число"));
РазмерПорции = 10000;
КоличествоПорций = Цел(ТаблицаДанных.Количество() / РазмерПорции) + 1;
Запрос = Новый Запрос;
ТекстЗапроса = "
|ВЫБРАТЬ Т.* ПОМЕСТИТЬ Т ИЗ &Т КАК Т;
|ВЫБРАТЬ Т.Объект, Т.Индекс" + СтрокаВыбора + "
|ИЗ Т КАК Т";
Запрос.Текст = ТекстЗапроса;
ИндексСтроки = 0;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоПорций, "Чтение дополнительных полей");
ДоступноеПолеОбъект = КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(Новый ПолеКомпоновкиДанных("Объект"));
Для СчетчикПорций = 1 По КоличествоПорций Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
ПорцияОбъектов.Очистить();
Для Счетчик = 1 По РазмерПорции Цикл
Если ИндексСтроки = ТаблицаДанных.Количество() Тогда
Прервать;
КонецЕсли;
СтрокаОбъекта = ТаблицаДанных[ИндексСтроки];
ИндексСтроки = ИндексСтроки + 1;
Если Ложь
Или ТипЗнч(СтрокаОбъекта[ИмяПоляСсылки]) = Тип("Строка")
Или СтрокаОбъекта[ИмяПоляСсылки] = Неопределено
Или ДоступноеПолеОбъект = Неопределено
Или Не ДоступноеПолеОбъект.ТипЗначения.СодержитТип(ТипЗнч(СтрокаОбъекта[ИмяПоляСсылки]))
Тогда
СтрокаОбъекта.ИндексКартинки = 12; // Регистр сведений
Продолжить;
КонецЕсли;
СтрокаПорции = ПорцияОбъектов.Добавить();
СтрокаПорции.Объект = СтрокаОбъекта[ИмяПоляСсылки];
СтрокаПорции.Индекс = ИндексСтроки - 1;
КонецЦикла;
Запрос.УстановитьПараметр("Т", ПорцияОбъектов);
РезультатЗапроса = Запрос.Выполнить();
РеквизитыПорции = РезультатЗапроса.Выгрузить();
Для Каждого СтрокаПорции Из РеквизитыПорции Цикл
СтрокаОбъекта = ТаблицаДанных[СтрокаПорции.Индекс];
СтрокаОбъекта.ИндексКартинки = ирОбщий.ПолучитьИндексКартинкиСсылкиЛкс(СтрокаПорции.Объект, Истина, СтрокаПорции);
ЗаполнитьЗначенияСвойств(СтрокаОбъекта, СтрокаПорции);
КонецЦикла;
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
СтрокаПорядка = "Метаданные," + СтрокаПорядка;
Возврат СтрокаПорядка;
КонецФункции
Процедура ОбновитьДоступныеПоляДляДополнительныхПолейЛкс(Знач ТаблицаДанных, Знач КомпоновщикДопПолей, Знач ТабличноеПолеДоступныхПолей) Экспорт
//Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы.Количество() = 0 Тогда
Если ТипЗнч(ТаблицаДанных) = Тип("ТаблицаЗначений") Тогда
ПолныеИменаМД = ТаблицаДанных.Скопировать(, "Метаданные");
Иначе
ПолныеИменаМД = ТаблицаДанных.Выгрузить(, "Метаданные");
КонецЕсли;
ПолныеИменаМД.Свернуть("Метаданные");
ПолныеИменаМД = ПолныеИменаМД.ВыгрузитьКолонку(0);
МассивТипов = Новый Массив();
Для Каждого ПолноеИмяМД Из ПолныеИменаМД Цикл
Если ТипЗнч(ПолноеИмяМД) = Тип("ОбъектМетаданных") Тогда
ПолноеИмяМД = ПолноеИмяМД.ПолноеИмя();
КонецЕсли;
Попытка
Тип = Тип(ирОбщий.ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяМД));
Исключение
Продолжить;
КонецПопытки;
МассивТипов.Добавить(Тип);
КонецЦикла;
Если МассивТипов.Количество() > 0 Тогда
КоллекцияПолей = Новый Массив();
КоллекцияПолей.Добавить(Новый Структура("Имя, ТипЗначения", "Объект", Новый ОписаниеТипов(МассивТипов)));
ТекстЗапроса = ирОбщий.ПолучитьЗапросИмитаторКоллекцииПолейЛкс(КоллекцияПолей);
СхемаКомпоновки = ирОбщий.ПолучитьСхемуКомпоновкиПоЗапросуЛкс(ТекстЗапроса);
Иначе
СхемаКомпоновки = Новый СхемаКомпоновкиДанных;
КонецЕсли;
КомпоновщикДопПолей.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки));
Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы.Количество() > 0 Тогда
ТабличноеПолеДоступныхПолей.Развернуть(КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы[0]);
КонецЕсли;
//КонецЕсли;
КонецПроцедуры
// ИменаКолонок - Строка - имена колонок через запятую
Процедура ТабличноеПоле_ОтобразитьПиктограммыТиповЛкс(ОформлениеСтроки, ИменаКолонок) Экспорт
Если ТипЗнч(ИменаКолонок) = Тип("Строка") Тогда
ИменаКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаКолонок, ",", Истина);
КонецЕсли;
Для Каждого ИмяКолонки Из ИменаКолонок Цикл
Ячейка = ОформлениеСтроки.Ячейки.Найти(ИмяКолонки);
//:Ячейка=Новый("ОформлениеЯчейки")
Если Ячейка <> Неопределено Тогда
ДанныеКартинки = Ячейка.Значение;
Если ТипЗнч(ДанныеКартинки) = Тип("ПолеКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
СсылкаКартинка = Неопределено;
ТипЗначения = ТипЗнч(ДанныеКартинки);
Если Истина
И ТипЗначения = Тип("Булево")
И Ячейка.ОтображатьФлажок
Тогда
Продолжить;
КонецЕсли;
КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения);
Если КартинкаТипа <> Неопределено Тогда
Ячейка.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ТабличноеПоле_СколькоСтрокЛкс(ТабличноеПоле) Экспорт
ЗначениеЭУ = ТабличноеПоле.Значение;
//ТипЗначенияТабличногоПоля = ТипЗнч(ИсточникДействий.Значение);
//ИмяОбщегоТипа = ПолучитьИмяОбщегоТипаИзКонкретногоТипа, ТипЗначенияТабличногоПоля);
Попытка
Количество = ЗначениеЭУ.Количество();
Попытка
Отбор = ТабличноеПоле.ОтборСтрок;
Исключение
КонецПопытки;
Исключение
Попытка
//Коллекция компоновки
Количество = ЗначениеЭУ.Элементы.Количество();
//Суффикс = "*";
Исключение
Попытка
//Или ИмяОбщегоТипа = "ДеревоЗначений"
Количество = ЗначениеЭУ.Строки.Количество();
Суффикс = "*";
Исключение
// ДинамическийСписок
ОбъектМД = Метаданные.НайтиПоТипу(ТабличноеПоле.ТипЗначения.Типы()[0]);
Если ОбъектМД = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(ОбъектМД);
ТекстЗапроса = " ИЗ " + ОбъектМД.ПолноеИмя();
Если КорневойТип = "РегистрБухгалтерии" Тогда
ТекстЗапроса = ТекстЗапроса + ".ДвиженияССубконто";
КонецЕсли;
ПостроительПростой = Новый ПостроительЗапроса("ВЫБРАТЬ * " + ТекстЗапроса);
ПостроительПростой.ЗаполнитьНастройки();
ТекстОтбор = "";
Для Каждого ДоступноеПоле Из ПостроительПростой.ДоступныеПоля Цикл
Если Не ДоступноеПоле.Отбор Тогда
Продолжить;
КонецЕсли;
Если ТекстОтбор <> "" Тогда
ТекстОтбор = ТекстОтбор + ", ";
КонецЕсли;
ТекстОтбор = ТекстОтбор + "Т." + ДоступноеПоле.ПутьКДанным;
КонецЦикла;
ТекстЗапроса = "ВЫБРАТЬ РАЗРЕШЕННЫЕ КОЛИЧЕСТВО(*) " + ТекстЗапроса + " КАК Т {ГДЕ " + ТекстОтбор + "}";
ПостроительЗапроса = Новый ПостроительЗапроса(ТекстЗапроса);
ПостроительЗапроса.ЗаполнитьНастройки();
СкопироватьОтборЛкс(ПостроительЗапроса.Отбор, ТабличноеПоле.Значение.Отбор, Истина, Истина);
Отбор = ТабличноеПоле.Значение.Отбор;
Количество = ПостроительЗапроса.Результат.Выгрузить()[0][0];
КонецПопытки;
КонецПопытки;
КонецПопытки;
Текст = "Количество строк ";
Если Отбор <> Неопределено Тогда
Текст = Текст + "с отбором """ + Отбор + """ ";
КонецЕсли;
Сообщить(Текст + "- " + Формат(Количество, "ЧН=") + "(" + Формат(Количество, "ЧН=; ЧГ=") + ")" + Суффикс);
Результат = Количество;
Возврат Результат;
КонецФункции
// Получает картинку для корневого типа конфигурации.
//
// Параметры:
// пКорневойТип – Строка – корневой тип конфигурации.
//
// Возвращаемое значение:
// – Картинка – корневого типа конфигурации.
//
Функция ПолучитьКартинкуКорневогоТипаЛкс(пКорневойТип) Экспорт
Если СтрокиРавныЛкс("Изменения", пКорневойТип) Тогда
Возврат ПолучитьОбщуюКартинкуЛкс("ирТаблицаИзменений");
КонецЕсли;
Попытка
Возврат ПолучитьОбщуюКартинкуЛкс("ир" + пКорневойТип);
Исключение
Попытка
Возврат БиблиотекаКартинок[пКорневойТип];
Исключение
КонецПопытки;
КонецПопытки;
Возврат Новый Картинка();
КонецФункции // ПолучитьКартинкуКорневогоТипа()
Функция ОткрытьТекущуюСтрокуТабличногоПоляТаблицыБДВРедактореОбъектаБДЛкс(ТабличноеПоле, ПолноеИмяМД = Неопределено, ДоступныеПоляВыбора = Неопределено, Связанный = Ложь,
ФормаРедактора = Неопределено) Экспорт
ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
Если ТекущаяСтрока = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если ПолноеИмяМД = Неопределено Тогда
ПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение)).ПолноеИмя();
ПолноеИмяМД = ирОбщий.имяме;
КонецЕсли;
ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка;
Если Истина
И ТекущаяКолонка <> Неопределено
И (Ложь
Или ДоступныеПоляВыбора = Неопределено
Или ДоступныеПоляВыбора.НайтиПоле(Новый ПолеКомпоновкиДанных(ТекущаяКолонка.Данные)) <> Неопределено)
Тогда
ИмяКолонки = ТекущаяКолонка.Данные;
Иначе
ИмяКолонки = "";
КонецЕсли;
СтруктураКлючаСтроки = Неопределено;
ПолноеИмяТаблицы = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
Если ТабличноеПоле.ТекущиеДанные <> Неопределено Тогда
КлючОбъекта = ПолучитьКлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, ТабличноеПоле.ТекущиеДанные, Истина, СтруктураКлючаСтроки);
КонецЕсли;
Если КлючОбъекта = Неопределено Тогда
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмяТаблицы);
Если Ложь
Или ЛиКорневойТипСсылкиЛкс(КорневойТип)
Или ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип)
Тогда
//КлючОбъекта = Новый (СтрЗаменить(ПолноеИмяТаблицы, ".", "Ссылка."));
ТипКлюча = ТипЗнч(ТекущаяСтрока.Ссылка);
КлючОбъекта = Новый (ТипКлюча);
ПолноеИмяТаблицы = Метаданные.НайтиПоТипу(ТипКлюча).ПолноеИмя();
Иначе
КлючОбъекта = Новый (СтрЗаменить(ПолноеИмяТаблицы, ".", "НаборЗаписей."));
КонецЕсли;
КонецЕсли;
Если ФормаРедактора = Неопределено Тогда
КлючУникальности = ТекущаяСтрока;
Если Связанный Тогда
КлючУникальности = "Связанный";
КонецЕсли;
ФормаРедактора = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", , , КлючУникальности);
КонецЕсли;
Если Не ФормаРедактора.Открыта() Тогда
ФормаРедактора.мПараметрКлючИлиОбъект = КлючОбъекта;
Иначе
ФормаРедактора.ЗагрузитьОбъектПоКлючу(КлючОбъекта);
КонецЕсли;
ФормаРедактора.Открыть();
ФормаРедактора.ПоказатьЯчейкуДанныхОбъекта(ПолноеИмяТаблицы, ИмяКолонки, СтруктураКлючаСтроки);
Возврат ФормаРедактора;
КонецФункции
// Если в текущей строке не достаточно полей для заполнения ключа записи регистра, то всегда возвращается набор записей, не смотря на параметр ДляРегистровСоздатьНаборЗаписей.
Функция ПолучитьКлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, Знач ТекущаяСтрока, ДляРегистровСоздатьНаборЗаписей = Ложь, выхСтруктураКлючаСтроки = Неопределено) Экспорт
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицы);
СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолноеИмяТаблицы,,, ДляРегистровСоздатьНаборЗаписей);
Если СтруктураКлюча.Свойство("НомерСтроки") Тогда
выхСтруктураКлючаСтроки = Новый Структура("НомерСтроки");
ИначеЕсли СтруктураКлюча.Свойство("Период") Тогда
выхСтруктураКлючаСтроки = Новый Структура("Период");
Иначе
выхСтруктураКлючаСтроки = Неопределено;
КонецЕсли;
Если выхСтруктураКлючаСтроки <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(выхСтруктураКлючаСтроки, ТекущаяСтрока);
КонецЕсли;
Если Ложь
Или ЛиКорневойТипСсылкиЛкс(ТипТаблицы)
Или ЛиКорневойТипЖурналаДокументовЛкс(ТипТаблицы)
Тогда
Если ирОбщий.ЛиТипСсылкиБДЛкс(ТипЗнч(ТекущаяСтрока), Ложь) Тогда
КлючОбъекта = ТекущаяСтрока;
Иначе
КлючОбъекта = ТекущаяСтрока.Ссылка;
КонецЕсли;
ПолноеИмяТаблицы = Метаданные.НайтиПоТипу(ТипЗнч(КлючОбъекта)).ПолноеИмя();
ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
КлючОбъекта = ТекущаяСтрока.Ссылка;
ИначеЕсли Ложь
Или ЛиКорневойТипРегистраБДЛкс(ТипТаблицы)
//Или ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы)
Тогда
Если Не ДляРегистровСоздатьНаборЗаписей Тогда
НайденыВсеПоляКлючаЗаписи = Истина;
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
Попытка
Пустышка = ТекущаяСтрока[КлючИЗначение.Ключ];
Исключение
НайденыВсеПоляКлючаЗаписи = Ложь;
Прервать;
КонецПопытки;
КонецЦикла;
КонецЕсли;
Если Ложь
Или ДляРегистровСоздатьНаборЗаписей
Или Не НайденыВсеПоляКлючаЗаписи
Тогда
КлючОбъекта = ПолучитьНаборЗаписейПоКлючуЛкс(ПолноеИмяТаблицы, ТекущаяСтрока);
Иначе
ЗаполнитьЗначенияСвойств(СтруктураКлюча, ТекущаяСтрока);
ОбъектМД = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы);
МенеджерРегистра = Новый (СтрЗаменить(ОбъектМД.ПолноеИмя(), ".", "Менеджер."));
КлючОбъекта = МенеджерРегистра.СоздатьКлючЗаписи(СтруктураКлюча);
КонецЕсли;
Иначе
КлючОбъекта = Неопределено;
КонецЕсли;
Возврат КлючОбъекта;
КонецФункции
Функция _КонтрольРазмераВыборкиПользователемЛкс(ЗапросИлиПостроитель, МаксимальноеЧислоСтрок = 500000) Экспорт
КоличествоСтрокРезультата = ирКэш.Получить().ПолучитьГрубоКоличествоСтрокВРезультатеЗапроса(ЗапросИлиПостроитель);
Если Истина
И ТипЗнч(КоличествоСтрокРезультата) = Тип("Число")
И КоличествоСтрокРезультата > МаксимальноеЧислоСтрок
Тогда
Кнопки = Новый СписокЗначений;
Кнопки.Добавить("Все", "Все");
Кнопки.Добавить("Часть", "Первые " + Формат(МаксимальноеЧислоСтрок, "ЧГ="));
Ответ = Вопрос("Загружаемая таблица содержит " + КоличествоСтрокРезультата + " строк. Сколько строк загружать?", Кнопки, , "Часть");
//Если Ответ <> КодВозвратаДиалога.ОК Тогда
// Возврат;
//КонецЕсли;
Если Ответ = "Все" Тогда
МаксимальноеЧислоСтрок = 0;
КонецЕсли;
Иначе
МаксимальноеЧислоСтрок = 0;
КонецЕсли;
Возврат МаксимальноеЧислоСтрок;
КонецФункции
// Параметры:
// ИмяКлючевойКолонки - Строка - содержит имя таблицы
//
Функция ВычислитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных = Неопределено, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок",
ЛиТаблицыИзменений = Ложь, СтруктураОтбора = Неопределено, ТолькоРазрешенные = Ложь) Экспорт
МассивКлючей = Новый Массив;
Если ДеревоМетаданных <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ДеревоМетаданных = Новый ДеревоЗначений
#КонецЕсли
Для Каждого СтрокаДерева1 Из ДеревоМетаданных.Строки Цикл
Для Каждого СтрокаДерева2 Из СтрокаДерева1.Строки Цикл
КорневойТип = ПолучитьПервыйФрагментЛкс(СтрокаДерева2[ИмяКлючевойКолонки]);
Если Ложь
Или КорневойТип = "ВнешнийИсточникДанных"
Или КорневойТип = "РегламентноеЗадание"
Тогда
Продолжить;
КонецЕсли;
ИмяТаблицы = СтрокаДерева2[ИмяКлючевойКолонки];
Если ИмяТаблицы = Неопределено Тогда
Продолжить;
КонецЕсли;
Если НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ИмяТаблицы) = Неопределено Тогда
Продолжить;
КонецЕсли;
МассивКлючей.Добавить(ИмяТаблицы);
Для Каждого СтрокаДерева3 Из СтрокаДерева2.Строки Цикл
МассивКлючей.Добавить(СтрокаДерева3[ИмяКлючевойКолонки]);
КонецЦикла;
КонецЦикла;
КонецЦикла;
КлючамиЗаданыИменаТаблиц = Ложь;
Иначе
ЛокальныеТаблицы = ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс().Скопировать(Новый Структура("Схема", ""), "ПолноеИмя, Тип");
НачальноеКоличество = ЛокальныеТаблицы.Количество();
Для СчетчикЛокальныеТаблицы = 1 По НачальноеКоличество Цикл
ОписаниеТаблицы = ЛокальныеТаблицы[НачальноеКоличество - СчетчикЛокальныеТаблицы];
Если ОписаниеТаблицы.Тип = "ВиртуальнаяТаблица" Тогда
ЛокальныеТаблицы.Удалить(ОписаниеТаблицы);
КонецЕсли;
КонецЦикла;
МассивКлючей = ЛокальныеТаблицы.ВыгрузитьКолонку("ПолноеИмя");
КлючамиЗаданыИменаТаблиц = Истина;
КонецЕсли;
ТекстПакета = "";
ТекстЗапроса = "";
СчетчикТаблиц = 0;
Для Каждого ПолноеИмяМД Из МассивКлючей Цикл
ТекстЧастиОбъединения = ПолучитьТекстЗапросаСтатистикиПоТаблицеЛкс(ПолноеИмяМД, ИмяКлючевойКолонки, ИмяКолонкиКоличества, ЛиТаблицыИзменений, СтруктураОтбора, ТолькоРазрешенные,
КлючамиЗаданыИменаТаблиц);
Если ТекстЧастиОбъединения = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ТекстЗапроса <> "" Тогда
ТекстЗапроса = ТекстЗапроса + "
|ОБЪЕДИНИТЬ ВСЕ";
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + ТекстЧастиОбъединения;
СчетчикТаблиц = СчетчикТаблиц + 1;
Если СчетчикТаблиц = 255 Тогда
СчетчикТаблиц = 0;
Если ТекстПакета <> "" Тогда
ТекстПакета = ТекстПакета + "
|;";
КонецЕсли;
ТекстПакета = ТекстПакета + ТекстЗапроса;
ТекстЗапроса = "";
КонецЕсли;
КонецЦикла;
Если ТекстПакета <> "" Тогда
ТекстПакета = ТекстПакета + "
|;";
КонецЕсли;
ТекстПакета = ТекстПакета + ТекстЗапроса;
Если ЗначениеЗаполнено(ТекстПакета) Тогда
Запрос = Новый Запрос;
Если СтруктураОтбора <> Неопределено Тогда
СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураОтбора, Запрос.Параметры);
КонецЕсли;
Запрос.Текст = ТекстПакета;
Состояние("Сбор статистики таблиц...");
РезультатПакета = Запрос.ВыполнитьПакет();
Состояние("");
Результат = Новый Массив();
Для Каждого РезультатЗапроса Из РезультатПакета Цикл
Результат.Добавить(РезультатЗапроса.Выгрузить());
КонецЦикла;
Иначе
Результат = Новый Массив();
КонецЕсли;
Если СтруктураОтбора = Неопределено Тогда
СписокТаблиц = ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс();
Для Каждого ТаблицаРезультата Из Результат Цикл
Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл
ОписаниеТаблицы = СписокТаблиц.Найти(НРег(СтрокаРезультата.ИмяТаблицы), "НПолноеИмя");
ОписаниеТаблицы.КоличествоСтрок = СтрокаРезультата[ИмяКолонкиКоличества];
КонецЦикла;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьКоличествоИзмененийПоУзлуЛкс(Узел, МассивМетаданных = Неопределено) Экспорт
#Если Клиент Тогда
Состояние("Вычисление количества изменений на узле...");
#КонецЕсли
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Узел", Узел);
МетаПланОбмена = Узел.Метаданные();
ТекстЗапроса = "";
Для Каждого ЭлементСОстава Из МетаПланОбмена.Состав Цикл
МетаОбъект = ЭлементСОстава.Метаданные;
Если Ложь
Или МетаОбъект = Неопределено
Или (Истина
И МассивМетаданных <> Неопределено
И МассивМетаданных.Найти(МетаОбъект) = Неопределено)
Тогда
Продолжить;
КонецЕсли;
Если ТекстЗапроса <> "" Тогда
ТекстЗапроса = ТекстЗапроса + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС;
КонецЕсли;
ИмяТаблицыДляПоискаЗарегистрированных = СтрЗаменить(МетаОбъект.ПолноеИмя(), ".Перерасчет.", ".") + ".Изменения";
ТекстЗапроса = ТекстЗапроса + "ВЫБРАТЬ Количество(*) КАК Количество
|ИЗ
| " + ИмяТаблицыДляПоискаЗарегистрированных + " КАК РегистрацияИзменений
|ГДЕ
| РегистрацияИзменений.Узел = &Узел
|";
КонецЦикла;
Если ТекстЗапроса <> "" Тогда
Запрос.Текст = ТекстЗапроса;
ТаблицаКоличестваИзменений = Запрос.Выполнить().Выгрузить();
КоличествоИзменений = ТаблицаКоличестваИзменений.Итог("Количество");
Иначе
КоличествоИзменений = 0;
КонецЕсли;
#Если Клиент Тогда
Состояние("");
#КонецЕсли
Возврат КоличествоИзменений;
КонецФункции
Процедура ОбновитьСтатистикуПоТаблицеОбъектаМДВРезультатеПакетаЛкс(РезультатПакета, ПолноеИмяМД, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок", ЛиТаблицыИзменений = Ложь,
СтруктураОтбора = Неопределено, ТолькоРазрешенные = Истина) Экспорт
ТекстЗапроса = ПолучитьТекстЗапросаСтатистикиПоТаблицеЛкс(ПолноеИмяМД, ИмяКлючевойКолонки, ИмяКолонкиКоличества, ЛиТаблицыИзменений, СтруктураОтбора, ТолькоРазрешенные);
Запрос = Новый Запрос(ТекстЗапроса);
Если СтруктураОтбора <> Неопределено Тогда
СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураОтбора, Запрос.Параметры);
КонецЕсли;
СтруктураКлюча = Новый Структура(ИмяКлючевойКолонки);
КолонкиКоличества = Новый Массив();
КолонкиКоличества.Добавить(ИмяКолонкиКоличества);
Если ЛиТаблицыИзменений Тогда
СтруктураКлюча.Вставить("Узел");
КолонкиКоличества.Добавить("КоличествоВыгруженных");
КолонкиКоличества.Добавить("КоличествоНевыгруженных");
КонецЕсли;
СтатистикаПоТаблице = Запрос.Выполнить().Выгрузить();
СтатистикаПоТаблице.Колонки.Добавить("Найдена", Новый ОписаниеТипов("булево"));
Для Каждого ЭлементПакета Из РезультатПакета Цикл
СтрокиРезультата = ЭлементПакета.НайтиСтроки(Новый Структура(ИмяКлючевойКолонки, ПолноеИмяМД));
Если СтрокиРезультата.Количество() > 0 Тогда
Для Каждого СтрокаРезультата Из СтрокиРезультата Цикл
ЗаполнитьЗначенияСвойств(СтруктураКлюча, СтрокаРезультата);
Для Каждого ИмяКолонкиКоличества Из КолонкиКоличества Цикл
СтрокаРезультата[ИмяКолонкиКоличества] = 0;
КонецЦикла;
Для Каждого СтрокаСтатистики Из СтатистикаПоТаблице.НайтиСтроки(СтруктураКлюча) Цикл
СтрокаСтатистики.Найдена = Истина;
Для Каждого ИмяКолонкиКоличества Из КолонкиКоличества Цикл
СтрокаРезультата[ИмяКолонкиКоличества] = СтрокаСтатистики[ИмяКолонкиКоличества];
КонецЦикла;
КонецЦикла;
КонецЦикла;
Прервать;
КонецЕсли;
КонецЦикла;
Для Каждого СтрокаСтатистики Из СтатистикаПоТаблице.НайтиСтроки(Новый Структура("Найдена", Ложь)) Цикл
СтрокаРезультата = ЭлементПакета.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаРезультата, СтрокаСтатистики);
КонецЦикла;
КонецПроцедуры
Функция ПолучитьТекстЗапросаСтатистикиПоТаблицеЛкс(ПолноеИмяМДИлиТаблицы, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок", ЛиТаблицыИзменений = Ложь,
СтруктураОтбора = Неопределено, ТолькоРазрешенные = Ложь, ЭтоПолноеИмяТаблицы = Ложь) Экспорт
ТекстЧастиОбъединения = "
|ВЫБРАТЬ";
Если Не ЭтоПолноеИмяТаблицы Тогда
ИмяТаблицы = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМДИлиТаблицы, ЛиТаблицыИзменений, Ложь, ТолькоРазрешенные);
Если ИмяТаблицы = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| """ + ПолноеИмяМДИлиТаблицы + """ КАК " + ИмяКлючевойКолонки + ",";
Иначе
ИмяТаблицы = ПолноеИмяМДИлиТаблицы;
КонецЕсли;
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| """ + ИмяТаблицы + """ КАК ИмяТаблицы,
| Количество(*) КАК " + ИмяКолонкиКоличества + ",";
Если ЛиТаблицыИзменений Тогда
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| Узел,
| СУММА(ВЫБОР КОГДА Т.НомерСообщения ЕСТЬ NULL ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) КАК КоличествоНевыгруженных,
| СУММА(ВЫБОР КОГДА Т.НомерСообщения ЕСТЬ NULL ТОГДА 0 ИНАЧЕ 1 КОНЕЦ) КАК КоличествоВыгруженных,";
КонецЕсли;
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| 1
|ИЗ " + ИмяТаблицы + " КАК Т
|ГДЕ 1 = 1";
Если СтруктураОтбора <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
Если ирОбщий.СтрокиРавныЛкс("_ТипУзла_", КлючИЗначение.Ключ) Тогда
ОпределениеПоля = "ТИПЗНАЧЕНИЯ(Т.Узел)";
Иначе
ОпределениеПоля = "Т." + КлючИЗначение.Ключ;
КонецЕсли;
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| И " + ОпределениеПоля + " В (&" + КлючИЗначение.Ключ + ")";
КонецЦикла;
КонецЕсли;
Если ЛиТаблицыИзменений Тогда
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
|СГРУППИРОВАТЬ ПО Узел";
КонецЕсли;
Возврат ТекстЧастиОбъединения;
КонецФункции
Процедура ЗаполнитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, РезультатПакета = Неопределено, ИмяКлючевойКолонки = "ПолноеИмяОбъекта",
СуммируемыеКолонки = "КоличествоСтрок", СтруктураОтбора = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ДеревоМетаданных = Новый ДеревоЗначений
#КонецЕсли
ВсеСтрокиДерева = ПолучитьВсеСтрокиДереваЗначенийЛкс(ДеревоМетаданных);
СтруктураСуммируемыхКолонок = Новый Структура(СуммируемыеКолонки);
МассивСуммируемыхКолонок = Новый Массив();
Для Каждого КлючИЗначение Из СтруктураСуммируемыхКолонок Цикл
МассивСуммируемыхКолонок.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
Для Каждого СтрокаДерева Из ВсеСтрокиДерева Цикл
Для Каждого ИмяСуммируемойКолонки Из МассивСуммируемыхКолонок Цикл
СтрокаДерева[ИмяСуммируемойКолонки] = Неопределено;
КонецЦикла;
КонецЦикла;
Если РезультатПакета = Неопределено Тогда
ТаблицаКоличества = ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс();
ИмяКлючевойКолонкиИсточника = "ПолноеИмяМД";
Иначе
ИмяКлючевойКолонкиИсточника = ИмяКлючевойКолонки;
Для Каждого ТаблицаРезультата Из РезультатПакета Цикл
Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл
Если ТаблицаКоличества = Неопределено Тогда
ТаблицаКоличества = ТаблицаРезультата.СкопироватьКолонки();
ТаблицаКоличества.Колонки.Удалить(ИмяКлючевойКолонкиИсточника);
ТаблицаКоличества.Колонки.Добавить(ИмяКлючевойКолонкиИсточника); // Чтобы убрать ограничение на длину строки, которое может быть разным в результатах запросов пакета
КонецЕсли;
Если СтруктураОтбора <> Неопределено Тогда
ПодходитФильтру = Истина;
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
ЗначениеРезультата = СтрокаРезультата[КлючИЗначение.Ключ];
Если ТипЗнч(КлючИЗначение.Значение) = Тип("Массив") Тогда
Если КлючИЗначение.Значение.Найти(ЗначениеРезультата) = Неопределено Тогда
ПодходитФильтру = Ложь;
Прервать;
КонецЕсли;
Иначе
Если КлючИЗначение.Значение <> ЗначениеРезультата Тогда
ПодходитФильтру = Ложь;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Не ПодходитФильтру Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
ЗаполнитьЗначенияСвойств(ТаблицаКоличества.Добавить(), СтрокаРезультата);
КонецЦикла;
КонецЦикла;
КонецЕсли;
Если ТаблицаКоличества <> Неопределено Тогда
Для Каждого СтрокаКоличества Из ТаблицаКоличества Цикл
Если СтрокаКоличества[ИмяСуммируемойКолонки] = Неопределено Тогда
Продолжить;
КонецЕсли;
СтрокаДерева = ДеревоМетаданных.Строки.Найти(СтрокаКоличества[ИмяКлючевойКолонкиИсточника], ИмяКлючевойКолонки, Истина);
Если СтрокаДерева <> Неопределено Тогда
Для Каждого ИмяСуммируемойКолонки Из МассивСуммируемыхКолонок Цикл
ДобавитьКоличествоСтрокРодителюЛкс(СтрокаДерева, СтрокаКоличества[ИмяСуммируемойКолонки], ИмяСуммируемойКолонки);
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьКоличествоСтрокРодителюЛкс(Знач СтрокаДерева, Знач ДобавкаККоличеству, Знач ИмяСуммируемойКолонки= "КоличествоСтрок") Экспорт
СтароеКоличество = СтрокаДерева[ИмяСуммируемойКолонки];
Если СтароеКоличество = Неопределено Тогда
СтароеКоличество = 0;
КонецЕсли;
НовоеКоличество = ?(СтрокаДерева[ИмяСуммируемойКолонки] = Неопределено, 0, СтрокаДерева[ИмяСуммируемойКолонки]) + ДобавкаККоличеству;
СтрокаДерева[ИмяСуммируемойКолонки] = НовоеКоличество;
Если СтрокаДерева.Уровень() > 1 Тогда
Возврат;
КонецЕсли;
Родитель = СтрокаДерева.Родитель;
Пока Родитель <> Неопределено Цикл
Если ТипЗнч(НовоеКоличество) <> Тип("Число") Тогда
Родитель[ИмяСуммируемойКолонки] = "?";
КонецЕсли;
КоличествоРодителя = Родитель[ИмяСуммируемойКолонки];
Если КоличествоРодителя = "?" Тогда
Прервать;
КонецЕсли;
Если ТипЗнч(КоличествоРодителя) <> Тип("Число") Тогда
КоличествоРодителя = 0;
КонецЕсли;
Родитель[ИмяСуммируемойКолонки] = КоличествоРодителя - СтароеКоличество + НовоеКоличество;
Родитель = Родитель.Родитель;
КонецЦикла;
КонецПроцедуры // ЗаполнитьДеревоИсточников()
Процедура ОбновитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок",
ЛиТаблицыИзменений = Ложь, СтруктураОтбора = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ДеревоМетаданных = Новый ДеревоЗначений
#КонецЕсли
РезультатПакета = ВычислитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, ИмяКлючевойКолонки, ИмяКолонкиКоличества, ЛиТаблицыИзменений, СтруктураОтбора);
ЗаполнитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, РезультатПакета, ИмяКлючевойКолонки, ИмяКолонкиКоличества);
КонецПроцедуры
Процедура УстановитьЗначениеКолонкиДереваЛкс(ДеревоЗначений, ИмяКолонки = "Пометка", НовоеЗначение = Истина) Экспорт
ВсеСтроки = ПолучитьВсеСтрокиДереваЗначенийЛкс(ДеревоЗначений);
Для Каждого СтрокаДерева Из ВсеСтроки Цикл
СтрокаДерева.Пометка = НовоеЗначение;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(мдОбъекта, ВключаяПоследовательности = Ложь, ВключаяПерерасчеты = Ложь) Экспорт
ОбъектыМД = Новый Массив();
Для Каждого МетаРегистр из мдОбъекта.Движения Цикл
ОбъектыМД.Добавить(МетаРегистр);
Если ВключаяПерерасчеты Тогда
Если ЛиКорневойТипРегистраРасчетаЛкс(ПолучитьПервыйФрагментЛкс(МетаРегистр.ПолноеИмя())) Тогда
Для Каждого ПерерасчетМД Из МетаРегистр.Перерасчеты Цикл
ОбъектыМД.Добавить(ПерерасчетМД);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ВключаяПоследовательности Тогда
Для Каждого МетаПоследовательность Из Метаданные.Последовательности Цикл
Если МетаПоследовательность.Документы.Содержит(мдОбъекта) Тогда
ОбъектыМД.Добавить(МетаПоследовательность);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ОбъектыМД;
КонецФункции
// НовыйРежим - Булево - Имя/Синоним
Процедура ТабличноеПоле_ОбновитьКолонкиИмяСинонимЛкс(ТабличноеПоле, НовыйРежим, ИмяКолонкиИмя = "Имя", ИмяКолонкиСиноним = "Представление") Экспорт
КолонкиТП = ТабличноеПоле.Колонки;
КолонкаИмя = КолонкиТП[ИмяКолонкиИмя];
КолонкаСиноним = КолонкиТП[ИмяКолонкиСиноним];
КолонкаИмя.Видимость = НовыйРежим;
КолонкаСиноним.Видимость = Не НовыйРежим;
Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда
КолонкаИмя.ОтображатьИерархию = НовыйРежим;
КолонкаСиноним.ОтображатьИерархию = Не НовыйРежим;
КонецЕсли;
ИндексКолонкиИмя = КолонкиТП.Индекс(КолонкаИмя);
ИндексКолонкиСиноним = КолонкиТП.Индекс(КолонкаСиноним);
Если НовыйРежим = (ИндексКолонкиИмя > ИндексКолонкиСиноним) Тогда
КолонкиТП.Сдвинуть(КолонкаИмя, ИндексКолонкиСиноним - ИндексКолонкиИмя);
КонецЕсли;
Если НовыйРежим Тогда
ТабличноеПоле.ТекущаяКолонка = ТабличноеПоле.Колонки.Имя;
Иначе
ТабличноеПоле.ТекущаяКолонка = ТабличноеПоле.Колонки.Представление;
КонецЕсли;
КонецПроцедуры
Процедура ТабличноеПоле_ОформитьЯчейкиИмяСинонимЛкс(ТабличноеПоле, ОформлениеСтроки,
ИмяКолонкиИмя = "Имя", ИмяКолонкиСиноним = "Представление", ИмяКолонкиИндексКартинки = "ИндексКартинки", ДанныеФлажка = "") Экспорт
ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
Если ТабличноеПоле.Колонки[ИмяКолонкиИмя].Видимость Тогда
ВедущаяКолонка = ТабличноеПоле.Колонки[ИмяКолонкиИмя];
ВедущийИндекс = ТабличноеПоле.Колонки.Индекс(ВедущаяКолонка);
КонецЕсли;
Если ТабличноеПоле.Колонки[ИмяКолонкиСиноним].Видимость Тогда
Если Ложь
Или ВедущаяКолонка = Неопределено
Или ТабличноеПоле.Колонки.Индекс(ТабличноеПоле.Колонки[ИмяКолонкиСиноним]) < ВедущийИндекс
Тогда
ВедущаяКолонка = ТабличноеПоле.Колонки[ИмяКолонкиСиноним];
КонецЕсли;
КонецЕсли;
Если ВедущаяКолонка <> Неопределено Тогда
Ячейка = ОформлениеСтроки.Ячейки[ВедущаяКолонка.Имя];
ИндексКартинки = ДанныеСтроки[ИмяКолонкиИндексКартинки];
Если ИндексКартинки >= 0 Тогда
Ячейка.ОтображатьКартинку = Истина;
Ячейка.ИндексКартинки = ИндексКартинки;
КонецЕсли;
Если ДанныеФлажка <> "" Тогда
Ячейка.ОтображатьФлажок = Истина;
Ячейка.Флажок = ДанныеСтроки[ДанныеФлажка];
КонецЕсли;
КоличествоДочерних = ДанныеСтроки.Строки.Количество();
Если КоличествоДочерних > 0 Тогда
Ячейка.УстановитьТекст(Ячейка.Текст + " (" + КоличествоДочерних + ")");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ОпределитьВедущуюСтроковуюКолонкуТабличногоПоляЛкс(ТабличноеПолеДерева) Экспорт
Если Истина
И ТабличноеПолеДерева.ТекущаяКолонка <> Неопределено
И ЗначениеЗаполнено(ТабличноеПолеДерева.ТекущаяКолонка.Данные)
И ТабличноеПолеДерева.Значение.Колонки[ТабличноеПолеДерева.ТекущаяКолонка.Данные].ТипЗначения.СодержитТип(Тип("Строка"))
Тогда
ТекущаяКолонкаТП = ТабличноеПолеДерева.ТекущаяКолонка;
Иначе
Для Каждого КолонкаТП Из ТабличноеПолеДерева.Колонки Цикл
Если Не КолонкаТП.Видимость Тогда
Продолжить;
КонецЕсли;
КолонкаДерева = ТабличноеПолеДерева.Значение.Колонки[КолонкаТП.Данные];
Если КолонкаДерева.ТипЗначения.СодержитТип(Тип("Строка")) Тогда
ТекущаяКолонкаТП = КолонкаТП;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ТекущаяКолонкаТП;
КонецФункции
Функция НайтиСтрокуТабличногоПоляДереваЗначенийСоСложнымФильтромЛкс(ТабличноеПолеДерева, ПолеВводаФильтра, Подстроки = "") Экспорт
ТекущаяКолонкаТП = ОпределитьВедущуюСтроковуюКолонкуТабличногоПоляЛкс(ТабличноеПолеДерева);
Если ТекущаяКолонкаТП = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ИмяТекущейКолонки = ТекущаяКолонкаТП.Данные;
Если Не ЗначениеЗаполнено(ИмяТекущейКолонки) Тогда
Возврат Неопределено;
КонецЕсли;
ВсеСтроки = ПолучитьВсеСтрокиДереваЗначенийЛкс(ТабличноеПолеДерева.Значение);
ТекущаяСтрока = ТабличноеПолеДерева.ТекущаяСтрока;
Если Подстроки = "" Тогда
Подстроки = ПолеВводаФильтра.Значение;
КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(НРег(Подстроки), " ", Истина);
ИндексСтроки = 0;
Если ТекущаяСтрока <> Неопределено Тогда
Если ЛиСтрокаСодержитВсеПодстрокиЛкс(ТекущаяСтрока[ИмяТекущейКолонки], Фрагменты) Тогда
ИндексСтроки = ВсеСтроки.Найти(ТекущаяСтрока) + 1;
КонецЕсли;
КонецЕсли;
Успех = Ложь;
Для ИндексСтроки = ИндексСтроки По ВсеСтроки.Количество() - 1 Цикл
ТекущаяСтрока = ВсеСтроки[ИндексСтроки];
Если ЛиСтрокаСодержитВсеПодстрокиЛкс(ТекущаяСтрока[ИмяТекущейКолонки], Фрагменты) Тогда
ТабличноеПолеДерева.ТекущаяСтрока = ТекущаяСтрока;
ТабличноеПолеДерева.ТекущаяКолонка = ТекущаяКолонкаТП;
Успех = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Успех Тогда
ПолеВводаФильтра.ЦветФонаПоля = Новый Цвет();
Иначе
ТекущаяСтрока = Неопределено;
ПолеВводаФильтра.ЦветФонаПоля = ПолучитьЦветСтиляЛкс("ирЦветФонаОшибки");
КонецЕсли;
Возврат ТекущаяСтрока;
КонецФункции
Процедура ТабличноеПолеДеревоЗначений_РазвернутьВсеСтрокиЛкс(ТабличноеПоле, ЧислоПервыхИгнорируемыхСтрок = 0) Экспорт
Счетчик = 0;
Для Каждого Строка Из ТабличноеПоле.Значение.Строки Цикл
Счетчик = Счетчик + 1;
Если Счетчик > ЧислоПервыхИгнорируемыхСтрок Тогда
ТабличноеПоле.Развернуть(Строка, Истина);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ТабличноеПолеДеревоЗначений_СвернутьВсеСтрокиЛкс(ТабличноеПоле, ВосстановитьТекущуюСтроку = Ложь) Экспорт
МассивТекущихУзлов = Новый Массив;
Если ВосстановитьТекущуюСтроку Тогда
ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
Пока ТекущаяСтрока <> Неопределено Цикл
МассивТекущихУзлов.Добавить(ТекущаяСтрока);
ТекущаяСтрока = ТекущаяСтрока.Родитель;
КонецЦикла;
КонецЕсли;
ВсеСтрокиДерева = ПолучитьВсеСтрокиДереваЗначенийЛкс(ТабличноеПоле.Значение);
Индикатор = ПолучитьИндикаторПроцессаЛкс(ВсеСтрокиДерева.Количество());
Для Каждого СтрокаДерева Из ВсеСтрокиДерева Цикл
ОбработатьИндикаторЛкс(Индикатор);
Если Истина
И ТабличноеПоле.Развернут(СтрокаДерева)
И СтрокаДерева.Строки.Количество() > 0
И МассивТекущихУзлов.Найти(СтрокаДерева) = Неопределено
Тогда
ТабличноеПоле.Свернуть(СтрокаДерева);
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
КонецПроцедуры
Процедура ТабличноеПолеДеревоЗначений_АвтоРазвернутьВсеСтрокиЛкс(ТабличноеПоле, МаксимальноеЧислоСтрок = 30, ТекущаяСтрокаУстановлена = Ложь) Экспорт
ВсеСтроки = ПолучитьВсеСтрокиДереваЗначенийЛкс(ТабличноеПоле.Значение);
ЧислоДинамическихСтрок = ВсеСтроки.Количество();
Если ЧислоДинамическихСтрок > 0 Тогда
Если ЧислоДинамическихСтрок <= МаксимальноеЧислоСтрок Тогда
ТабличноеПолеДеревоЗначений_РазвернутьВсеСтрокиЛкс(ТабличноеПоле);
Если Не ТекущаяСтрокаУстановлена Тогда
ТабличноеПоле.ТекущаяСтрока = ТабличноеПоле.Значение.Строки[0].Строки[0];
КонецЕсли;
Иначе
Если Не ТекущаяСтрокаУстановлена Тогда
ТабличноеПоле.ТекущаяСтрока = ТабличноеПоле.Значение.Строки[0];
Если ТабличноеПоле.Значение.Строки.Количество() = 1 Тогда
ТабличноеПоле.Развернуть(ТабличноеПоле.ТекущаяСтрока);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ПрименитьСтрокуПоискаКТабличномуПолюДереваЛкс(ТабличноеПолеДерева, СтрокаПоиска, ИменаКолонокДанныхДляПоиска, выхСтруктураПоиска, АктивизироватьПервуюСтроку = Истина) Экспорт
СтруктураКолонок = Новый Структура(ИменаКолонокДанныхДляПоиска);
НайденныеСтрокиДерева = Новый Массив();
Если ЗначениеЗаполнено(СтрокаПоиска) Тогда
ВсеСтроки = ПолучитьВсеСтрокиДереваЗначенийЛкс(ТабличноеПолеДерева.Значение);
Для Каждого СтрокаДерева Из ВсеСтроки Цикл
Для Каждого КлючИЗначение Из СтруктураКолонок Цикл
ИнтереснаяКолонка = КлючИЗначение.Ключ;
Значение = СтрокаДерева[ИнтереснаяКолонка];
Если ТипЗнч(Значение) = Тип("Строка") Тогда
Значение = НРег(Значение);
Если Найти(Значение, НРег(СтрокаПоиска)) > 0 Тогда
НайденныеСтрокиДерева.Добавить(СтрокаДерева);
Родитель = СтрокаДерева;
Пока Родитель <> Неопределено Цикл
Если Не ТабличноеПолеДерева.Развернут(Родитель) Тогда
ТабличноеПолеДерева.Развернуть(Родитель);
КонецЕсли;
Родитель = Родитель.Родитель;
КонецЦикла;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если АктивизироватьПервуюСтроку И НайденныеСтрокиДерева.Количество() > 0 Тогда
ТабличноеПолеДерева.ТекущаяСтрока = НайденныеСтрокиДерева[0];
КонецЕсли;
КонецЕсли;
ТекущийИндексНайденнойСтроки = 0;
выхСтруктураПоиска = Новый Структура("ТекущийИндексНайденнойСтроки, НайденныеСтрокиДерева", ТекущийИндексНайденнойСтроки, НайденныеСтрокиДерева);
КонецПроцедуры
Процедура СледующееВхождениеСтрокиПоискаВТабличномПолеДереваЛкс(ТабличноеПолеДерева, СтруктураПоиска) Экспорт
Если СтруктураПоиска = Неопределено Тогда
Возврат;
КонецЕсли;
Если СтруктураПоиска.НайденныеСтрокиДерева.Количество() > 0 Тогда
СтруктураПоиска.ТекущийИндексНайденнойСтроки = СтруктураПоиска.ТекущийИндексНайденнойСтроки + 1;
Если СтруктураПоиска.ТекущийИндексНайденнойСтроки >= СтруктураПоиска.НайденныеСтрокиДерева.Количество() Тогда
СтруктураПоиска.ТекущийИндексНайденнойСтроки = 0;
КонецЕсли;
ТабличноеПолеДерева.ТекущаяСтрока = СтруктураПоиска.НайденныеСтрокиДерева[СтруктураПоиска.ТекущийИндексНайденнойСтроки];
КонецЕсли;
КонецПроцедуры
Процедура ПредыдущееВхождениеСтрокиПоискаВТабличномПолеДереваЛкс(ТабличноеПолеДерева, СтруктураПоиска) Экспорт
Если СтруктураПоиска = Неопределено Тогда
Возврат;
КонецЕсли;
Если СтруктураПоиска.НайденныеСтрокиДерева.Количество() > 0 Тогда
СтруктураПоиска.ТекущийИндексНайденнойСтроки = СтруктураПоиска.ТекущийИндексНайденнойСтроки - 1;
Если СтруктураПоиска.ТекущийИндексНайденнойСтроки < 0 Тогда
СтруктураПоиска.ТекущийИндексНайденнойСтроки = СтруктураПоиска.НайденныеСтрокиДерева.Количество() - 1;
КонецЕсли;
ТабличноеПолеДерева.ТекущаяСтрока = СтруктураПоиска.НайденныеСтрокиДерева[СтруктураПоиска.ТекущийИндексНайденнойСтроки];
КонецЕсли;
КонецПроцедуры
Процедура ОформитьСтрокуВТабличномПолеДереваСПоискомЛкс(ТабличноеПолеДерева, ОформлениеСтроки, ДанныеСтроки, СтруктураПоиска) Экспорт
Если СтруктураПоиска = Неопределено Тогда
Возврат;
КонецЕсли;
Если СтруктураПоиска.НайденныеСтрокиДерева.Найти(ДанныеСтроки) <> Неопределено Тогда
ОформлениеСтроки.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаРасширенногоПредставленияЗначения");
КонецЕсли;
КонецПроцедуры
Функция ДобавитьСсылкуВИзбранноеЛкс(Ссылка, ДобавлятьВИзбранноеРаботыПользователя = Истина, ДобавлятьВИзрабнноеИнтерфейснойПанели = Истина) Экспорт
Если ДобавлятьВИзбранноеРаботыПользователя Тогда
Избранное = ХранилищеСистемныхНастроек.Загрузить("Общее/ИзбранноеРаботыПользователя");
Если Избранное = Неопределено Тогда
Избранное = Новый ИзбранноеРаботыПользователя;
КонецЕсли;
ЭлементИзбранного = Новый ЭлементИзбранногоРаботыПользователя;
ЭлементИзбранного.НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(Ссылка);
Избранное.Добавить(ЭлементИзбранного);
ХранилищеСистемныхНастроек.Сохранить("Общее/ИзбранноеРаботыПользователя", "", Избранное);
КонецЕсли;
Если ДобавлятьВИзрабнноеИнтерфейснойПанели Тогда
ФормаИнтерфейснойПанели = ПолучитьФормуЛкс("Обработка.ирИнтерфейснаяПанель.Форма");
СтруктураЭлемента = Новый Структура();
СтруктураЭлемента.Вставить("Вид", Ссылка.Метаданные().ПолноеИмя());
СтруктураЭлемента.Вставить("Имя", Ссылка);
НоваяСтрока = ФормаИнтерфейснойПанели.ДобавитьСтрокуВСтатическуюВетку(СтруктураЭлемента, "Избранное");
Если ФормаИнтерфейснойПанели.Открыта() Тогда
ФормаИнтерфейснойПанели.ЗаполнитьСтатическиеВеткиДереваИнтерфейса(ФормаИнтерфейснойПанели, НоваяСтрока);
Иначе
ФормаИнтерфейснойПанели.СохранитьНастройки(ФормаИнтерфейснойПанели);
КонецЕсли;
КонецЕсли;
КонецФункции
//
Функция ТрансформироватьОтборВОтборКомпоновкиЛкс(Знач ОтборКомпоновкиДанных, Знач ЭлементыОтбора, Знач СоответствиеИмен = Неопределено,
Знач ПроверятьДоступностьПолей = Истина, Знач ДоступныеПоляОтбора = Неопределено, ПропускатьВыключенные = Ложь) Экспорт
Если СоответствиеИмен = Неопределено Тогда
СоответствиеИмен = Новый ТаблицаЗначений();
СоответствиеИмен.Колонки.Добавить("Источник");
//СоответствиеИмен.Колонки.Добавить("Приемник");
КонецЕсли;
Если ДоступныеПоляОтбора = Неопределено Тогда
ДоступныеПоляОтбора = ОтборКомпоновкиДанных.ДоступныеПоляОтбора;
КонецЕсли;
ИндексГраницы = ЭлементыОтбора.Количество() - 1;
ИзмененныеЭлементыОтбора = Новый Массив;
Платформа = ирКэш.Получить();
Для Каждого ЭлементОтбора Из ЭлементыОтбора Цикл
Если Истина
И ПропускатьВыключенные
И Не ЭлементОтбора.Использование
Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
ПриемникОтбора = ОтборКомпоновкиДанных.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ЗаполнитьЗначенияСвойств(ПриемникОтбора, ЭлементОтбора);
ТрансформироватьОтборВОтборКомпоновкиЛкс(ПриемникОтбора, ЭлементОтбора.Элементы, СоответствиеИмен, , ДоступныеПоляОтбора);
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
Если ТипЗнч(ЭлементОтбора.ЛевоеЗначение) <> Тип("ПолеКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
//ПутьКДаннымЛевый = Неопределено;
//Если ТипЗнч(ЭлементОтбора.ЛевоеЗначение) = Тип("ПолеКомпоновкиДанных") Тогда
ПутьКДаннымЛевый = "" + ЭлементОтбора.ЛевоеЗначение;
//Иначе
// ЛевоеЗначение = ЭлементОтбора.ЛевоеЗначение;
//КонецЕсли;
ПутьКДаннымПравый = Неопределено;
Если ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("ПолеКомпоновкиДанных") Тогда
ПутьКДаннымПравый = "" + ЭлементОтбора.ПравоеЗначение;
Иначе
ПравоеЗначение = ЭлементОтбора.ПравоеЗначение;
КонецЕсли;
лВидСравнения = ЭлементОтбора.ВидСравнения;
Иначе
СтрокаВидаСравнения = Платформа.СоответствиеВидовСравнения.Найти(ЭлементОтбора.ВидСравнения, "Построитель");
Если СтрокаВидаСравнения = Неопределено Тогда
// %%%% Здесь можно добавить интеллекта
Продолжить;
КонецЕсли;
ПутьКДаннымЛевый = ЭлементОтбора.ПутьКДанным;
ПутьКДаннымПравый = Неопределено;
лВидСравнения = СтрокаВидаСравнения.Компоновка;
ПравоеЗначение = ЭлементОтбора.Значение;
КонецЕсли;
//Если ПутьКДаннымЛевый <> Неопределено Тогда
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПутьКДаннымЛевый);
СтрокаИсточника = СоответствиеИмен.Найти(НРег(МассивФрагментов[0]), "Источник");
Если СтрокаИсточника <> Неопределено Тогда
МассивФрагментов[0] = СтрокаИсточника.Приемник;
КонецЕсли;
ПутьКДанным = ПолучитьСтрокуСРазделителемИзМассиваЛкс(МассивФрагментов, ".");
ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ПутьКДанным);
ПолеОтбора = Неопределено;
Для Каждого лЭлементОтбора Из ОтборКомпоновкиДанных.Элементы Цикл
Если Истина
И ТипЗнч(лЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных")
И лЭлементОтбора.ЛевоеЗначение = ПолеКомпоновки
И ИзмененныеЭлементыОтбора.Найти(лЭлементОтбора) = Неопределено
Тогда
ПолеОтбора = лЭлементОтбора;
ИзмененныеЭлементыОтбора.Добавить(ПолеОтбора);
Прервать;
КонецЕсли;
КонецЦикла;
Если ПолеОтбора = Неопределено Тогда
ДоступноеПоле = ДоступныеПоляОтбора.НайтиПоле(ПолеКомпоновки);
Если Истина
И ПроверятьДоступностьПолей
И ДоступноеПоле = Неопределено
Тогда
Продолжить;
КонецЕсли;
ПолеОтбора = ОтборКомпоновкиДанных.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ПолеОтбора.ЛевоеЗначение = ПолеКомпоновки;
КонецЕсли;
//Иначе
// ПолеОтбора.ПравоеЗначение = ЛевоеЗначение;
//КонецЕсли;
Если ПутьКДаннымПравый <> Неопределено Тогда
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПутьКДаннымПравый);
СтрокаИсточника = СоответствиеИмен.Найти(НРег(МассивФрагментов[0]), "Источник");
Если СтрокаИсточника <> Неопределено Тогда
МассивФрагментов[0] = СтрокаИсточника.Приемник;
КонецЕсли;
ПутьКДанным = ПолучитьСтрокуСРазделителемИзМассиваЛкс(МассивФрагментов, ".");
ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ПутьКДанным);
ПолеОтбора.ПравоеЗначение = ПолеКомпоновки;
Иначе
ПолеОтбора.ПравоеЗначение = ПравоеЗначение;
КонецЕсли;
ПолеОтбора.ВидСравнения = лВидСравнения;
ПолеОтбора.Использование = ЭлементОтбора.Использование;
КонецЦикла;
КонецФункции
Процедура ОткрытьОбъектыИзВыделенныхЯчеекВПодбореИОбработкеОбъектовЛкс(ТабличноеПоле, ИмяКолонки = "") Экспорт
Если ирКэш.Получить().Это2iS Тогда
ДУЛкс("УФ(П1, П2)", "ОткрытьКоллекциюВКонсолиОбработкиДанных", ТабличноеПоле.Значение);
Иначе
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
Если ВыделенныеСтроки.Количество() = 0 Тогда
Возврат ;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ИмяКолонки = ТабличноеПоле.ТекущаяКолонка.Данные;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Возврат;
КонецЕсли;
МассивСсылок = Новый Массив;
Для Каждого Строка Из ВыделенныеСтроки Цикл
ЗначениеСтроки = Строка[ИмяКолонки];
ТипЗначения = ТипЗнч(ЗначениеСтроки);
Если Метаданные.НайтиПоТипу(ТипЗначения) = Неопределено Тогда
Продолжить;
КонецЕсли;
МассивСсылок.Добавить(ЗначениеСтроки);
КонецЦикла;
ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(МассивСсылок);
КонецЕсли;
КонецПроцедуры // ОткрытьОбъектыИзВыделенныхЯчеекВПодбореИОбработкеОбъектовЛкс()
Процедура ОткрытьОбъектыИзВыделенныхСтрокВПодбореИОбработкеОбъектовЛкс(ТабличноеПоле, ПолноеИмяТаблицы = "") Экспорт
ПараметрКоманды = Новый Массив();
Для Каждого ВыделеннаяСтрока Из ТабличноеПоле.ВыделенныеСтроки Цикл
КлючОбъекта = ПолучитьКлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, ВыделеннаяСтрока);
ПараметрКоманды.Добавить(КлючОбъекта);
КонецЦикла;
Форма = ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(ПараметрКоманды);
КонецПроцедуры // ОткрытьОбъектыИзВыделенныхЯчеекВПодбореИОбработкеОбъектовЛкс()
Функция ОткрытьПодборИОбработкуОбъектовИзТабличногоПоляДинамическогоСпискаЛкс(ТабличноеПоле) Экспорт
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение));
Если ОбъектМД <> Неопределено Тогда
Ответ = Вопрос("Обработать только выделенные строки (Да) иначе будет использован текущий отбор (Нет)?", РежимДиалогаВопрос.ДаНет);
Иначе
Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если Ответ = КодВозвратаДиалога.Да Тогда
ПараметрКоманды = Новый Массив();
Для Каждого Строка Из ТабличноеПоле.ВыделенныеСтроки Цикл
Если ТипЗнч(Строка) = Тип("СтрокаТаблицыЗначений") Тогда
КлючСтроки = Строка.Ссылка;
Иначе
КлючСтроки = Строка;
КонецЕсли;
ПараметрКоманды.Добавить(КлючСтроки);
КонецЦикла;
Форма = ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(ПараметрКоманды);
Иначе
Форма = ПолучитьФормуЛкс("Обработка.ирПодборИОбработкаОбъектов.Форма",,, ОбъектМД.ПолноеИмя());
Форма.Открыть();
Форма.УстановитьОбластьПоиска();
Форма.СтрокаПоиска = "";
//СкопироватьОтборЛкс(Форма.ПостроительОтчета.Отбор, ИсточникДействий.Значение.Отбор, Истина, Истина);
Форма.Компоновщик.Настройки.Отбор.Элементы.Очистить();
ТрансформироватьОтборВОтборКомпоновкиЛкс(Форма.Компоновщик.Настройки.Отбор, ТабличноеПоле.Значение.Отбор,,,, Истина);
КонецЕсли;
Возврат Форма;
КонецФункции
Функция ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(МассивСсылок) Экспорт
Если МассивСсылок.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
Форма = ПолучитьФормуЛкс("Обработка.ирПодборИОбработкаОбъектов.Форма");
Форма.Открыть();
Форма.ЗагрузитьОбъектыДляОбработки(ПолучитьУникальныеЗначенияМассиваЛкс(МассивСсылок));
Возврат Форма;
КонецФункции // ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс()
Функция ПолучитьУникальныеЗначенияМассиваЛкс(Массив) Экспорт
НовыйМассив = Новый Массив;
Соответствие = Новый Соответствие;
Для Каждого Элемент Из Массив Цикл
Если Соответствие[Элемент] = 1 Тогда
Продолжить;
КонецЕсли;
Соответствие.Вставить(Элемент, 1);
НовыйМассив.Добавить(Элемент);
КонецЦикла;
Возврат НовыйМассив;
КонецФункции
Функция ПолучитьСтруктуруВосстановленияКонсолиЛкс(ИмяИлиОбъектКонсоли) Экспорт
Если ТипЗнч(ИмяИлиОбъектКонсоли) = Тип("Строка") Тогда
ИмяКонсоли = ИмяИлиОбъектКонсоли;
Иначе
ИмяКонсоли = ИмяИлиОбъектКонсоли.Метаданные().Имя;
КонецЕсли;
Структура = Новый Структура();
Структура.Вставить("БлокировкаВосстановления", Неопределено);
ПрефиксИмениФайлаВосстановления = ИмяКонсоли + "_" + ИмяПользователя() + "_";
Структура.Вставить("ПрефиксИмениФайлаВосстановления", ПрефиксИмениФайлаВосстановления);
ИмяФайлаВосстановления = ирКэш.Получить().КаталогФайловогоКэша + "\" + ПрефиксИмениФайлаВосстановления
+ Формат(НомерСеансаИнформационнойБазы(), "ЧЦ=8; ЧВН=; ЧГ=") + ".tmp";
Структура.Вставить("ФайлВосстановления", Новый Файл(ИмяФайлаВосстановления));
Возврат Структура;
КонецФункции
Функция СохранитьФайлВКонсолиСВосстановлениемЛкс(ДиалогВыбораФайла, Знач ИмяСохраняемогоФайла, ИмяОткрытогоФайла = "", ДанныеДляФайла,
СтруктураВосстановления, ЗапрашиватьИмяФайла = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ДиалогВыбораФайла = Новый ДиалогВыбораФайла();
#КонецЕсли
ФайлВосстановления = СтруктураВосстановления.ФайлВосстановления;
ПрефиксИмениФайлаВосстановления = СтруктураВосстановления.ПрефиксИмениФайлаВосстановления;
БлокировкаВосстановления = СтруктураВосстановления.БлокировкаВосстановления;
СохранитьФайл = Истина;
Если НРег(ИмяСохраняемогоФайла) <> НРег(ФайлВосстановления.ПолноеИмя) Тогда
// Здесь можно вставить проверочную сериализацию+десериализацию
ФайлВыбран = Истина;
лФайл = Новый Файл(ИмяОткрытогоФайла);
ДиалогВыбораФайла.ПолноеИмяФайла = ИмяСохраняемогоФайла;
Если Ложь
Или ПустаяСтрока(ИмяСохраняемогоФайла)
Или ЗапрашиватьИмяФайла
Или Найти(Нрег(лФайл.Имя), НРег(ПрефиксИмениФайлаВосстановления)) = 1
Тогда
Пока Истина Цикл
Если ДиалогВыбораФайла.Выбрать() Тогда
лФайл = Новый Файл(ДиалогВыбораФайла.ПолноеИмяФайла);
Если Найти(Нрег(лФайл.Имя), НРег(ПрефиксИмениФайлаВосстановления)) = 1 Тогда
КодОтвета = Вопрос("Это имя файла зарезервировано. Хотите выбрать другое?", РежимДиалогаВопрос.ОКОтмена);
Если КодОтвета = КодВозвратаДиалога.ОК Тогда
Продолжить;
Иначе
ФайлВыбран = Ложь;
Прервать;
КонецЕсли;
КонецЕсли;
ИмяСохраняемогоФайла = ДиалогВыбораФайла.ПолноеИмяФайла;
ФайлВыбран = Истина;
Прервать;
Иначе
ФайлВыбран = Ложь;
СохранитьФайл = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Иначе
ФайлВыбран = Ложь;
КонецЕсли;
Если СохранитьФайл Тогда
Если Истина
И НРег(ИмяСохраняемогоФайла) = НРег(ФайлВосстановления.ПолноеИмя)
И БлокировкаВосстановления <> Неопределено
Тогда
БлокировкаВосстановления = Неопределено;
КонецЕсли;
Если Не ЗначениеВФайл(ИмяСохраняемогоФайла, ДанныеДляФайла) Тогда
Сообщить("Ошибка записи файла """ + ИмяСохраняемогоФайла + """", СтатусСообщения.Внимание);
ФайлВыбран = Ложь;
КонецЕсли;
Если НРег(ИмяСохраняемогоФайла) = НРег(ФайлВосстановления.ПолноеИмя) Тогда
БлокировкаВосстановления = Новый ЗаписьТекста(ИмяСохраняемогоФайла,,,Истина);
КонецЕсли;
КонецЕсли;
Возврат ФайлВыбран;
КонецФункции
Функция ПроверитьВыбратьФайлВосстановленияКонсолиЛкс(СтруктураВосстановления) Экспорт
ПрефиксИмениФайлаВосстановления = СтруктураВосстановления.ПрефиксИмениФайлаВосстановления;
СписокВосстановления = Новый СписокЗначений;
ФайлыВосстановления = НайтиФайлы(ирКэш.Получить().КаталогФайловогоКэша, ПрефиксИмениФайлаВосстановления + "*.tmp");
Для Каждого ФайлВосстановления Из ФайлыВосстановления Цикл
#Если Сервер И Не Сервер Тогда
ФайлВосстановления = Новый Файл();
#КонецЕсли
Попытка
ФайлВосстановления.УстановитьВремяИзменения(ФайлВосстановления.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс());
//Пустышка = Новый ЗаписьТекста(ФайлВосстановления.ПолноеИмя, , , Истина);
Исключение
// Файла заблокирован и значит сессия продолжается.
Продолжить;
КонецПопытки;
СписокВосстановления.Добавить(ФайлВосстановления.ПолноеИмя, "" + (ФайлВосстановления.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс()) + " - "
+ ФайлВосстановления.ИмяБезРасширения);
КонецЦикла;
ИмяФайлаВосстановления = "";
Если СписокВосстановления.Количество() > 0 Тогда
СписокВосстановления.СортироватьПоПредставлению(НаправлениеСортировки.Убыв);
СписокВосстановления.Добавить("<Удалить все файлы восстановления>");
ВыбранныйЭлемент = СписокВосстановления.ВыбратьЭлемент("Вы можете открыть файл восстановления прерванной сессии");
Если ВыбранныйЭлемент <> Неопределено Тогда
Если ВыбранныйЭлемент.Значение = "<Удалить все файлы восстановления>" Тогда
Для Каждого ЭлементСписка Из СписокВосстановления Цикл
Если ВыбранныйЭлемент = ЭлементСписка Тогда
Продолжить;
КонецЕсли;
УдалитьФайлы(ЭлементСписка.Значение);
КонецЦикла;
Иначе
ИмяФайлаВосстановления = ВыбранныйЭлемент.Значение;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ИмяФайлаВосстановления;
КонецФункции
Процедура УдалитьФайлВосстановленияКонсолиСБлокировкойЛкс(СтруктураВосстановления) Экспорт
СтруктураВосстановления.БлокировкаВосстановления = Неопределено;
Попытка
УдалитьФайлы(СтруктураВосстановления.ФайлВосстановления.ПолноеИмя);
Исключение
КонецПопытки;
КонецПроцедуры
Процедура СчитатьПорциюВыборкиВТаблицуЛкс(Выборка, ТаблицаПриемник, Знач РазмерПорции = 9999, СчитыватьЧерезКопиюТаблицы = Истина,
СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый Запрос;
Выборка = Пустышка.Выполнить();
#КонецЕсли
Если СчитыватьЧерезКопиюТаблицы Тогда
// Иначе добавление и заполнение строк при связи с табличным полем будет дольше выполняться
КопияТаблицыПриемника = ТаблицаПриемник.Скопировать();
Если СсылкаНаБуфернуюТаблицу <> Неопределено Тогда
СсылкаНаБуфернуюТаблицу.Вставить("Таблица", КопияТаблицыПриемника);
КонецЕсли;
Иначе
КопияТаблицыПриемника = ТаблицаПриемник;
КонецЕсли;
КоличествоРезультата = Выборка.Количество();
Несчитано = КоличествоРезультата - КопияТаблицыПриемника.Количество();
Если Ложь
Или РазмерПорции > Несчитано
Или РазмерПорции = 0
Тогда
РазмерПорции = Несчитано;
КонецЕсли;
Если Несчитано = РазмерПорции Тогда
ПредставлениеПроцесса = "Загрузка выборки";
Иначе
ПредставлениеПроцесса = "Загрузка порции выборки";
КонецЕсли;
#Если Клиент Тогда
Индикатор = ПолучитьИндикаторПроцессаЛкс(РазмерПорции, ПредставлениеПроцесса);
#КонецЕсли
КолонкиВложенныхТаблиц = Новый Массив();
Для Каждого Колонка Из Выборка.Владелец().Колонки Цикл
Если Колонка.ТипЗначения.СодержитТип(Тип("РезультатЗапроса")) Тогда
КолонкиВложенныхТаблиц.Добавить(Колонка.Имя);
КонецЕсли;
КонецЦикла;
ЕстьКолонкиВложенныхТаблиц = КолонкиВложенныхТаблиц.Количество() > 0;
РазмерПорцииОсталось = РазмерПорции;
Пока Выборка.Следующий() Цикл
НоваяСтрока = КопияТаблицыПриемника.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
Если ЕстьКолонкиВложенныхТаблиц Тогда
Для Каждого КолонкаВложеннойТаблицы Из КолонкиВложенныхТаблиц Цикл
НоваяСтрока[КолонкаВложеннойТаблицы] = Выборка[КолонкаВложеннойТаблицы].Выгрузить();
КонецЦикла;
КонецЕсли;
Если РазмерПорцииОсталось > 0 Тогда
РазмерПорцииОсталось = РазмерПорцииОсталось - 1;
Если РазмерПорцииОсталось = 0 Тогда
Прервать;
КонецЕсли;
КонецЕсли;
#Если Клиент Тогда
ОбработатьИндикаторЛкс(Индикатор);
#КонецЕсли
КонецЦикла;
Если РазмерПорции = Несчитано Тогда
Выборка = Неопределено;
КонецЕсли;
#Если Клиент Тогда
ОсвободитьИндикаторПроцессаЛкс();
#КонецЕсли
ТаблицаПриемник = КопияТаблицыПриемника;
КонецПроцедуры // СчитатьПорциюРезультата()
// ТабличноеПоле определяется как источник действий командной панели.
// Параметру ВыборкаРезультата внутри присваивается значение!
Процедура ЗагрузитьВыборкуВТабличноеПолеПервуюПорциюЛкс(ЭтаФорма, РезультатЗапроса, ВыборкаРезультата, КоманднаяПанель,
ИмяОбработчикаОбновления = "ОбновитьРазмерДинамическойТаблицы", БезопасныйПорогКоличестваСтрок = 100000, СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
лЗапрос = Новый Запрос;
РезультатЗапроса = лЗапрос.Выполнить();
#КонецЕсли
//БезопасныйПорогКоличестваСтрок = 1; // Для отладки
ВыборкаРезультата = РезультатЗапроса.Выбрать();
ТабличноеПоле = КоманднаяПанель.ИсточникДействий;
Если Ложь
Или БезопасныйПорогКоличестваСтрок = 0
Или ВыборкаРезультата.Количество() < БезопасныйПорогКоличестваСтрок
Тогда
ВыборкаРезультата = Неопределено;
КоманднаяПанель.Кнопки.ЗагрузитьПолностью.Доступность = Ложь;
ТабличноеПоле.Значение = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.Прямой);
Попытка
Выполнить("ЭтаФорма." + ИмяОбработчикаОбновления + "()");
Исключение
ВызватьИсключение ОписаниеОшибки();
КонецПопытки;
Иначе
ТабличноеПоле.Значение = Новый ТаблицаЗначений;
Для Каждого Колонка Из РезультатЗапроса.Колонки Цикл
ТипЗначения = Колонка.ТипЗначения;
Если ТипЗначения.СодержитТип(Тип("РезультатЗапроса")) Тогда
ТипЗначения = Новый ОписаниеТипов("ТаблицаЗначений");
КонецЕсли;
ТабличноеПоле.Значение.Колонки.Добавить(Колонка.Имя, ТипЗначения, Колонка.Имя, Колонка.Ширина);
КонецЦикла;
ЭтаФорма.ПодключитьОбработчикОжидания(ИмяОбработчикаОбновления, 0.1, Истина);
СчитатьПорциюВыборкиВТаблицуЛкс(ВыборкаРезультата, ТабличноеПоле.Значение, БезопасныйПорогКоличестваСтрок, , СсылкаНаБуфернуюТаблицу);
КонецЕсли;
КонецПроцедуры
// ТабличноеПоле определяется как источник действий командной панели.
Процедура ЗагрузитьВыборкуВТабличноеПолеПолностьюЛкс(ЭтаФорма, мВыборкаРезультата, КоманднаяПанель,
ИмяОбработчикаОбновления = "ОбновитьРазмерДинамическойТаблицы", СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
ЭтаФорма.ПодключитьОбработчикОжидания(ИмяОбработчикаОбновления, 0.1, Истина);
ТабличноеПоле = КоманднаяПанель.ИсточникДействий;
СчитатьПорциюВыборкиВТаблицуЛкс(мВыборкаРезультата, ТабличноеПоле.Значение, 0, , СсылкаНаБуфернуюТаблицу);
КонецПроцедуры
// Параметру КоличествоРезультата внутри присваивается значение!
Процедура ПослеЗагрузкиВыборкиВТабличноеПолеЛкс(ЭтаФорма, мВыборкаРезультата, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
ТабличноеПоле = КоманднаяПанель.ИсточникДействий;
Если ТипЗнч(мВыборкаРезультата) = Тип("COMОбъект") Тогда
КоличествоРезультата = 0;
Попытка
КоличествоРезультата = мВыборкаРезультата.Count;
Исключение
Если мВыборкаРезультата.State <> 0 Тогда
КоличествоРезультата = мВыборкаРезультата.RecordCount;
КонецЕсли;
КонецПопытки;
ВсеСчитано = КоличествоРезультата = ТабличноеПоле.Значение.Количество();
ИначеЕсли ТипЗнч(мВыборкаРезультата) = Тип("ВыборкаИзРезультатаЗапроса") Тогда
КоличествоРезультата = мВыборкаРезультата.Количество();
Если СсылкаНаБуфернуюТаблицу <> Неопределено И СсылкаНаБуфернуюТаблицу.Свойство("Таблица") Тогда
ТабличноеПоле.Значение = СсылкаНаБуфернуюТаблицу.Таблица;
КонецЕсли;
ВсеСчитано = Ложь;
Иначе
КоличествоРезультата = ТабличноеПоле.Значение.Количество();
ВсеСчитано = Истина;
КонецЕсли;
ОбновитьЧислоЗагруженныхЭлементовВыборкиЛкс(ТабличноеПоле, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, ТабличноеПоле.Значение.Количество(),
КоличествоРезультата, ВсеСчитано);
КонецПроцедуры
Функция ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(ПолноеИмяТаблицы, ИмяКолонки, ЗначениеОтбора, МаксимальнаяПорция = 0) Экспорт
ПоляТаблицыБД = ирКэш.ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицы);
#Если Сервер И Не Сервер Тогда
ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки;
#КонецЕсли
ТекстПоля = "";
ПсевдонимТаблицы = "Т";
Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл
Если Ложь
Или ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения"))
Или ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений"))
Тогда
Продолжить;
КонецЕсли;
Если ЗначениеЗаполнено(ТекстПоля) Тогда
ТекстПоля = ТекстПоля + ", ";
КонецЕсли;
ТекстПоля = ТекстПоля + ПсевдонимТаблицы + "." + ПолеТаблицыБД.Имя;
КонецЦикла;
ТекстПервые = "";
Если МаксимальнаяПорция > 0 Тогда
ТекстПервые = " ПЕРВЫЕ " + Формат(МаксимальнаяПорция, "ЧГ=") + " ";
КонецЕсли;
ТекстЗапроса = "
|ВЫБРАТЬ " + ТекстПервые + " " + ТекстПоля + "
|ИЗ " + ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяТаблицы) + " КАК " + ПсевдонимТаблицы + "
|{ГДЕ " + ПсевдонимТаблицы + "." + ИмяКолонки + "}";
Построитель = Новый ПостроительЗапроса(ТекстЗапроса);
Если ТипЗнч(ЗначениеОтбора) = Тип("СписокЗначений") Тогда
ЭлементОтбора = Построитель.Отбор.Добавить(ИмяКолонки);
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке;
ЭлементОтбора.Значение = ЗначениеОтбора;
ЭлементОтбора.Использование = Истина;
Иначе
Построитель.Отбор.Добавить(ИмяКолонки).Установить(ЗначениеОтбора);
КонецЕсли;
Возврат Построитель;
КонецФункции
Функция ЗагрузитьСвязанныеСтрокиТаблицыБДЛкс(ЭтаФорма, ТабличноеПолеСвязанныхКолонок, ТабличноеПолеСвязанныхСтрок, КоманднаяПанельСвязанныхСтрок, мВыборкаРезультатаСтрокиТаблицы,
ЗначениеОтбора) Экспорт
СтрокаСвязаннойКолонки = ТабличноеПолеСвязанныхКолонок.ТекущаяСтрока;
Если СтрокаСвязаннойКолонки = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ЭтаФорма.СтрокиТаблицыБД = Новый ТаблицаЗначений;
ТабличноеПолеСвязанныхСтрок.СоздатьКолонки();
//Если ЗначениеОтбора = Неопределено Тогда
// ЗначениеОтбора = СтрокаСвязаннойКолонки.Ссылка;
//КонецЕсли;
Построитель = ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки, ЗначениеОтбора);
//ЧислоСтрокДляЗагрузки = ирОбщий.КонтрольРазмераВыборкиПользователемЛкс(Построитель);
//Если ЧислоСтрокДляЗагрузки > 0 Тогда
// Построитель = ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки, ЗначениеОтбора, ЧислоСтрокДляЗагрузки);
//КонецЕсли;
//// http://partners.v8.1c.ru/forum/thread.jsp?id=1034151#1034151
////МаксимальныйРазмер = 500000;
////Построитель = ПолучитьПостроительВыборкиСвязанныхСтрок(, МаксимальныйРазмер);
// Антибаг 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=1017264#1017264
Если ирКэш.Получить().ВерсияПлатформы >= 802014 Тогда
Если Истина
И СтрокаСвязаннойКолонки.ТипТаблицы = "Изменения"
И Найти(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, "РегистрСведений.") = 1
Тогда
Если Метаданные.ОбщиеРеквизиты.Количество() > 0 Тогда
Возврат Неопределено;
КонецЕсли;
//Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл
// ВыбранноеПоле = Построитель.ВыбранныеПоля.Найти(ОбщийРеквизит.Имя);
// Если Истина
// И ВыбранноеПоле <> Неопределено
// И ОбъектМетаданных.Измерения.Найти(ОбщийРеквизит.Имя) = Неопределено
// Тогда
// Если ирОбщий.ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Тогда
// Построитель.ВыбранныеПоля.Удалить(ВыбранноеПоле);
// КонецЕсли;
// КонецЕсли;
//КонецЦикла;
КонецЕсли;
КонецЕсли;
Попытка
РезультатСтрокиТаблицы = Построитель.Результат;
Исключение
// Антибаг платформы 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=1031481#1031481
Сообщить(ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
ирОбщий.ЗагрузитьВыборкуВТабличноеПолеПервуюПорциюЛкс(ЭтаФорма, РезультатСтрокиТаблицы, мВыборкаРезультатаСтрокиТаблицы, КоманднаяПанельСвязанныхСтрок);
//Если СтрокиТаблицыБД.Количество() = МаксимальныйРазмер Тогда
// Сообщить("Были выбраны первые " + МаксимальныйРазмер + " строк таблицы");
//КонецЕсли;
СтруктураОтбора = Новый Структура("ПолноеИмяТаблицы, ИмяКолонки", СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки);
ЗаполнитьЗначенияСвойств(СтруктураОтбора, СтрокаСвязаннойКолонки);
ТабличноеПолеСвязанныхСтрок.СоздатьКолонки();
ТабличноеПолеСвязанныхСтрок.ТекущаяКолонка = ТабличноеПолеСвязанныхСтрок.Колонки[СтрокаСвязаннойКолонки.ИмяКолонки];
Для Каждого КолонкаТП Из ТабличноеПолеСвязанныхСтрок.Колонки Цикл
КолонкаТП.ТолькоПросмотр = Истина;
КонецЦикла;
Попытка
ИскомаяСсылка = СтрокаСвязаннойКолонки.Ссылка
Исключение
ИскомаяСсылка = Неопределено;
КонецПопытки;
Если ИскомаяСсылка <> Неопределено Тогда
ТекущаяСтрока = ТабличноеПолеСвязанныхСтрок.Значение.Найти(ИскомаяСсылка, СтрокаСвязаннойКолонки.ИмяКолонки);
Если ТекущаяСтрока <> Неопределено Тогда
ТабличноеПолеСвязанныхСтрок.ТекущаяСтрока = ТекущаяСтрока;
КонецЕсли;
КонецЕсли;
Возврат СтрокаСвязаннойКолонки.ПолноеИмяТаблицы;
КонецФункции
Процедура ОбновитьЧислоЗагруженныхЭлементовВыборкиЛкс(ТабличноеПоле, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, КоличествоЗагружено, КоличествоРезультата, ВсеСчитано) Экспорт
Если ВсеСчитано Тогда
СтрокаКоличествоРезультата = "" + КоличествоЗагружено;
ПолеСтрокиКоличестваРезультата.ЦветФона = Новый Цвет();
Иначе
СтрокаКоличествоРезультата = "" + КоличествоЗагружено + "/" + КоличествоРезультата;
ПолеСтрокиКоличестваРезультата.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаВычисляемогоЗначения");
КонецЕсли;
ПолеСтрокиКоличестваРезультата.Значение = СтрокаКоличествоРезультата;
КоманднаяПанель.Кнопки.ЗагрузитьПолностью.Доступность = Не ВсеСчитано;
КонецПроцедуры
// Формирует макет компоновки и извлекает из него запрос
// Параметры:
// Схема - СхемаКомпоновкиДанных
// НастройкаКомпоновкиДанных - НастройкиКомпоновкиДанных
// ДобавлятьУпорядочивание - Булево
// ПрефиксИменПараметров - Строка, *"" - используется для переименования параметров, полезно при смешивании нескольких запросов из компоновки в один
// выхСхемаКолонок - Структура, *Неопределено - если не равно Неопределено, то возвращается структура,
// где ключи - имена колонок, а значения - полные имена полей
//
// Результат - Запрос
//
Функция ПолучитьЗапросИзКомпоновкиЛкс(Знач Схема, Знач НастройкаКомпоновкиДанных, Знач ДобавлятьУпорядочивание = Ложь, ПрефиксИменПараметров = "",
ДобавитьВыбранноеПоле = "", выхСхемаКолонок = Неопределено, Автоупорядочивание = Истина, ПроверятьДоступностьПолей = Ложь, СПредставлениямиСсылок = Ложь) Экспорт
НастройкаКомпоновкиДанных = ПолучитьКопиюОбъектаЛкс(НастройкаКомпоновкиДанных);
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновкиДанных = Новый НастройкиКомпоновкиДанных
#КонецЕсли
Если НастройкаКомпоновкиДанных.Структура.Количество() = 0 Тогда
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновкиДанных.Структура);
КонецЕсли;
Если ЗначениеЗаполнено(ДобавитьВыбранноеПоле) Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновкиДанных.Выбор, ДобавитьВыбранноеПоле);
КонецЕсли;
Если Не СПредставлениямиСсылок Тогда
Для Каждого ВыбранноеПоле Из НастройкаКомпоновкиДанных.Выбор.Элементы Цикл
Если ТипЗнч(ВыбранноеПоле) <> Тип("ВыбранноеПолеКомпоновкиДанных") Тогда
ВызватьИсключение "Неподдерживаемый тип выбранного поля - " + ТипЗнч(ВыбранноеПоле);
КонецЕсли;
Если ВыбранноеПоле.Использование Тогда
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(НастройкаКомпоновкиДанных.Структура[0].Отбор, "" + ВыбранноеПоле.Поле); // Отбор здесь используется не для фильтрации
КонецЕсли;
КонецЦикла;
НастройкаКомпоновкиДанных.Выбор.Элементы.Очистить();
КонецЕсли;
СтрокаПорядка = ПолучитьСтрокуПорядкаКомпоновкиЛкс(НастройкаКомпоновкиДанных.Порядок);
НастройкаКомпоновкиДанных.Порядок.Элементы.Очистить();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, НастройкаКомпоновкиДанных, ,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"), ПроверятьДоступностьПолей);
Запрос = Новый Запрос;
Если МакетКомпоновки.НаборыДанных.Количество() > 2 Тогда
Сообщить("В макете компоновки обнаружено более одного запроса");
КонецЕсли;
ТекстЗапроса = МакетКомпоновки.НаборыДанных[0].Запрос;
Если ДобавлятьУпорядочивание Тогда
Если ЗначениеЗаполнено(СтрокаПорядка) Тогда
ТекстЗапроса = ТекстЗапроса + "
|//Секция_Упорядочить. Этот комментарий используется в коде
|УПОРЯДОЧИТЬ ПО
| " + СтрокаПорядка;
КонецЕсли;
Если Ложь
Или Автоупорядочивание
//Или ЗначениеЗаполнено(СтрокаПорядка)
Тогда
ТекстЗапроса = ТекстЗапроса + "
|//Секция_Упорядочить. Этот комментарий используется в коде
|АВТОУПОРЯДОЧИВАНИЕ";
КонецЕсли;
КонецЕсли;
Запрос.Текст = ТекстЗапроса;
Для Каждого ЗначениеПараметра Из МакетКомпоновки.ЗначенияПараметров Цикл
Запрос.Параметры.Вставить(ЗначениеПараметра.Имя, ЗначениеПараметра.Значение);
КонецЦикла;
Если ПрефиксИменПараметров <> "" Тогда
ДобавитьПрефиксВсемПараметрамЗапросаЛкс(Запрос, ПрефиксИменПараметров);
КонецЕсли;
Если выхСхемаКолонок <> Неопределено Тогда
//выхСхемаКолонок = ПолучитьСхемуКолонокМакетаКомпоновкиДанныхЛкс(МакетКомпоновки);
//
НаборДанныхМакета = МакетКомпоновки.НаборыДанных[0];
Для Каждого ПолеНабора Из НаборДанныхМакета.Поля Цикл
выхСхемаКолонок.Вставить(ПолеНабора.Имя, ПолеНабора.ПутьКДанным);
КонецЦикла;
Для Каждого ВложенныйНаборДанных Из НаборДанныхМакета.ВложенныеНаборыДанных Цикл
выхСхемаКолонок.Вставить(ВложенныйНаборДанных.Имя, ВложенныйНаборДанных.ПутьКДанным);
КонецЦикла;
КонецЕсли;
Возврат Запрос;
КонецФункции
Функция ПолучитьТекстОтбораЗапросаКомпоновкиЛкс(ЗапросСОтбором, ПсевдонимТаблицыПередГДЕ = "Т") Экспорт
ТекстОтбораДублей = ПолучитьПоследнийФрагментЛкс(ЗапросСОтбором.Текст, "КАК " + ПсевдонимТаблицыПередГДЕ + "
|ГДЕ", Ложь);
Если Не ЗначениеЗаполнено(ТекстОтбораДублей) Тогда
ТекстОтбораДублей = " ИСТИНА ";
КонецЕсли;
Возврат ТекстОтбораДублей;
КонецФункции
// Осуществляет вывод результата компоновки в коллекцию значений. По умолчанию в качестве коллекции используется новая таблица значений.
// Параметры:
// СхемаКомпоновки - СхемаКомпоновкиДанных
// НастройкаКомпоновки - НастройкиКомпоновкиДанных
// КоллекцияЗначений - ДеревоЗначений, Массив, СписокЗначений, ТаблицаЗначений - Если не указана, создается ТаблицаЗначений
// ВнешниеНаборыДанных - Структура
// ТолькоСоздатьКолонки - Булево
// СхемаКолонок - Структура - Если Неопределено, то не возвращается
// МаксимальноеЧислоСтрокРезультата - Число(15,2) - Для предотвращения получения слишком большого результата. Если порог превышен, то результат = Неопределено.
// ОтключитьОбщиеИтоги - Булево
// РежимОтладки - Булево
//
Функция СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(Знач СхемаКомпоновки, Знач НастройкаКомпоновки, КоллекцияЗначений = Неопределено, Знач ВнешниеНаборыДанных,
Знач ТолькоСоздатьКолонки = Ложь, СхемаКолонок = Неопределено, Знач МаксимальноеЧислоСтрокРезультата = 0, Знач ОтключитьОбщиеИтоги = Истина, Знач РежимОтладки = Ложь,
ПроверятьДоступностьПолей = Ложь) Экспорт
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
//ЭлементСтруктуры = НастройкаКомпоновки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
//ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура);
КонецЕсли;
Если ОтключитьОбщиеИтоги Тогда
НастройкаКомпоновки.ПараметрыВывода.УстановитьЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ВертикальноеРасположениеОбщихИтогов"),
РасположениеИтоговКомпоновкиДанных.Нет);
КонецЕсли;
Если Ложь
Или КоллекцияЗначений = Неопределено
Или ТипЗнч(КоллекцияЗначений) = Тип("СписокЗначений")
Или ТипЗнч(КоллекцияЗначений) = Тип("Массив")
Тогда
КоллекцияРезультата = Новый ТаблицаЗначений;
Иначе
КоллекцияРезультата = КоллекцияЗначений;
КонецЕсли;
Если РежимОтладки Тогда
ОтладитьЛкс(СхемаКомпоновки, Ложь, НастройкаКомпоновки, ВнешниеНаборыДанных);
//Возврат Неопределено;
КонецЕсли;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Попытка
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, НастройкаКомпоновки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"), ПроверятьДоступностьПолей);
Исключение
//ИнформацияОбОшибке = ИнформацияОбОшибке();
//Если глКэш.ЭтоВидимоеПриложение Тогда
// ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке);
//Иначе
// ВызватьИсключение ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
//КонецЕсли;
ВызватьИсключение;
Возврат Неопределено;
КонецПопытки;
//ИсследоватьЛкс(МакетКомпоновки, Ложь);
//ОтладитьЛкс(МакетКомпоновки, Ложь);
//Возврат Неопределено;
Если МаксимальноеЧислоСтрокРезультата > 0 Тогда
// Здесь тратится дополнительное ощутимое время на предварительный запрос.
ирПлатформа = ирКэш.Получить();
ГрубоеКоличествоСтрокРезультата = ирПлатформа.ПолучитьГрубоКоличествоСтрокВРезультатеКомпоновки(МакетКомпоновки);
Если ГрубоеКоличествоСтрокРезультата > МаксимальноеЧислоСтрокРезультата Тогда
Сообщить("Настройки компоновки приводят к слишком большой выборке данных. Попробуйте задать более сильные ограничения.");
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
//Антибаг платформы 1.14. Удаляем дубли ячеек по именам колонок в макете.
//ИсследоватьЛкс(МакетКомпоновки, Ложь);
ОписанияМакетовОбластей = МакетКомпоновки.Макеты;
Если ОписанияМакетовОбластей.Количество() > 0 Тогда
ЯчейкиЗаголовка = ОписанияМакетовОбластей[0].Макет.Ячейки;
КоличествоЯчеек = ЯчейкиЗаголовка.Количество();
СтруктураКолонок = Новый Структура;
ИндексЯчейки = 0;
Пока ИндексЯчейки < КоличествоЯчеек Цикл
ЯчейкаКолонки = ЯчейкиЗаголовка[ИндексЯчейки];
ИмяКолонки = ЯчейкаКолонки.Имя;
//ИмяКолонки = ирПлатформа.ПолучитьИдентификаторИзПредставления(ЯчейкаКолонки.Имя); // От этого варианта отказались из-за портативности
ИмяКолонки = СтрЗаменить(ИмяКолонки, ".", "_");
ИмяКолонки = СтрЗаменить(ИмяКолонки, "]", "");
ИмяКолонки = СтрЗаменить(ИмяКолонки, "[", "");
ИмяКолонки = СтрЗаменить(ИмяКолонки, " ", "_");
ЯчейкаКолонки.Имя = ИмяКолонки;
Если СтруктураКолонок.Свойство(ИмяКолонки) Тогда
Для ИндексМакета = 1 По ОписанияМакетовОбластей.Количество() - 1 Цикл
МакетСтроки = ОписанияМакетовОбластей[ИндексМакета];
МакетСтроки.Макет.Ячейки.Удалить(ИндексЯчейки);
КонецЦикла;
ЯчейкиЗаголовка.Удалить(ИндексЯчейки);
КоличествоЯчеек = КоличествоЯчеек - 1;
Иначе
ИндексЯчейки = ИндексЯчейки + 1;
СтруктураКолонок.Вставить(ИмяКолонки);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если СхемаКолонок <> Неопределено Тогда
// Схема колонок строится негарантировано, т.к. платформа не предоставляет нужных данных
СхемаКолонок.Очистить();
Если ЯчейкиЗаголовка <> Неопределено Тогда
КоличествоЯчеекЗаголовка = ЯчейкиЗаголовка.Количество();
Для Индекс = 0 По КоличествоЯчеекЗаголовка - 1 Цикл
Для Каждого ОписаниеМакетаОбласти Из ОписанияМакетовОбластей Цикл
// Здесь подсказка криво работает из-за кривого синтакс-помощника 8.2.13.205
// http://partners.v8.1c.ru/forum/thread.jsp?id=898023#898023
ЯчейкаМакетаОбласти = ОписаниеМакетаОбласти.Макет.Ячейки[Индекс];
Если ТипЗнч(ЯчейкаМакетаОбласти) <> Тип("ЯчейкаМакетаКоллекцииЗначенийОбластиКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
ПараметрЯчейки = ЯчейкаМакетаОбласти.Значение;
Если ПараметрЯчейки = Неопределено Тогда
Продолжить;
КонецЕсли;
Выражение = ОписаниеМакетаОбласти.Параметры["" + ПараметрЯчейки].Выражение;
ПозицияТочки = Найти(Выражение, ".");
Если Ложь
Или ПозицияТочки = 0
Или Найти(Выражение, " ") > 0
Или Найти(Выражение, "(") > 0
Тогда
//ИмяПоля = "";
Продолжить;
Иначе
ИмяПоля = Сред(Выражение, ПозицияТочки + 1);
КонецЕсли;
СхемаКолонок.Вставить(ЯчейкиЗаголовка[Индекс].Имя, ИмяПоля);
Прервать;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если ТолькоСоздатьКолонки Тогда
КоллекцияЗначений.Колонки.Очистить();
ЯчейкиЗаголовка = МакетКомпоновки.Макеты[0].Макет.Ячейки;
Для Каждого Ячейка Из ЯчейкиЗаголовка Цикл
//КолонкаКоллекции = КоллекцияЗначений.Колонки.Найти(Ячейка.Имя);
//Если КолонкаКоллекции = Неопределено Тогда
КоллекцияЗначений.Колонки.Добавить(Ячейка.Имя, Ячейка.ТипЗначения, Ячейка.Заголовок,);
//КонецЕсли;
КонецЦикла;
Иначе
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, , Истина);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(КоллекцияРезультата);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецЕсли;
//ИсследоватьЛкс(КоллекцияРезультата);
Если ТипЗнч(КоллекцияЗначений) = Тип("СписокЗначений") Тогда
Есть0 = КоллекцияРезультата.Колонки.Количество() > 0;
Есть1 = КоллекцияРезультата.Колонки.Количество() > 1;
Для Каждого СтрокаРезультата Из КоллекцияРезультата Цикл
НовыйЭлемент = КоллекцияЗначений.Добавить();
Если Есть0 Тогда
НовыйЭлемент.Значение = СтрокаРезультата[0];
КонецЕсли;
Если Есть1 Тогда
НовыйЭлемент.Представление = СтрокаРезультата[1];
КонецЕсли;
КонецЦикла;
ИначеЕсли ТипЗнч(КоллекцияЗначений) = Тип("Массив") Тогда
Если КоллекцияРезультата.Колонки.Количество() > 0 Тогда
Для Каждого СтрокаРезультата Из КоллекцияРезультата Цикл
КоллекцияЗначений.Добавить(СтрокаРезультата[0]);
КонецЦикла;
КонецЕсли;
Иначе
КоллекцияЗначений = КоллекцияРезультата;
КонецЕсли;
Результат = КоллекцияЗначений;
Возврат Результат;
КонецФункции
Функция НайтиПоказатьСтрокуВПолеТекстовогоДокументаЛкс(Форма, ПолеТекстовогоДокумента, СтрокаПоиска) Экспорт
Позиция = Найти(Нрег(ПолеТекстовогоДокумента.ПолучитьТекст()), Нрег(СтрокаПоиска));
Если Позиция > 0 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(Позиция, Позиция + СтрДлина(СтрокаПоиска));
Форма.ТекущийЭлемент = ПолеТекстовогоДокумента;
Результат = Истина;
Иначе
Если СтрДлина(ПолеТекстовогоДокумента.ВыделенныйТекст) > 0 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1);
КонецЕсли;
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// Элемент - ПолеТабличногоДокумента
//
Функция ПолеТабличногоДокумента_ПолучитьПредставлениеСуммыВыделенныхЯчеекЛкс(Знач Элемент) Экспорт
Сумма = 0;
СчетчикЯчеекСуммы = 0;
СчетчикЯчеекОбщий = 0;
ВыделенныеОбласти = Элемент.ВыделенныеОбласти;
ЕстьИгнорированныеОбласти = Ложь;
НачальноеКоличество = ВыделенныеОбласти.Количество();
Для СчетчикВыделенныеОбласти = 1 По НачальноеКоличество Цикл
Область = ВыделенныеОбласти[НачальноеКоличество - СчетчикВыделенныеОбласти];
Если ТипЗнч(Область) = Тип("РисунокТабличногоДокумента") Тогда
Продолжить;
КонецЕсли;
ПлощадьОбласти = (Область.Право - Область.Лево + 1) * (Область.Низ - Область.Верх + 1);
СчетчикЯчеекОбщий = СчетчикЯчеекОбщий + ПлощадьОбласти;
Если ПлощадьОбласти < 10000 Тогда
Для НомерКолонки = Область.Лево по Область.Право Цикл
Для НомерСтроки = Область.Верх по Область.Низ Цикл
ОбластьЯчейки = Элемент.Область(НомерСтроки, НомерКолонки);
Если ОбластьЯчейки.Лево <> НомерКолонки Или ОбластьЯчейки.Верх <> НомерСтроки Тогда
// Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой
Продолжить;
КонецЕсли;
Попытка
Число = Число(ОбластьЯчейки.Текст);
Исключение
Продолжить;
КонецПопытки;
Сумма = Сумма + Число;
СчетчикЯчеекСуммы = СчетчикЯчеекСуммы + 1;
КонецЦикла;
КонецЦикла;
Иначе
ЕстьИгнорированныеОбласти = Истина;
КонецЕсли;
КонецЦикла;
СчетчикЯчеекСуммы = "" + СчетчикЯчеекСуммы;
Сумма = "" + Сумма;
Если ЕстьИгнорированныеОбласти Тогда
СчетчикЯчеекСуммы = СчетчикЯчеекСуммы + "+?";
Сумма = Сумма + "+?";
КонецЕсли;
Текст = "" + СчетчикЯчеекСуммы + " из " + СчетчикЯчеекОбщий + " яч. = " + Сумма + "";
Возврат Текст;
КонецФункции
// Таблица - ТаблицаЗначений, ТабличнаяЧасть, РезультатЗапроса
Функция ВывестиТаблицуВТабличныйДокументЛкс(Таблица, Знач ТабличныйДокумент = Неопределено, ДанныеРасшифровки = Неопределено, ИтогиЧисловыхПолей = Истина,
АвтофиксацияШапки = Истина) Экспорт
ВнешниеНаборыДанных = Новый Структура("Основной", Таблица);
СхемаКомпоновки = СоздатьСхемуПоТаблицамЗначенийЛкс(ВнешниеНаборыДанных, , , ИтогиЧисловыхПолей);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
Для Каждого Колонка Из КолонкиИсточникаДанныхЛкс(Таблица) Цикл
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, Колонка.Имя);
КонецЦикла;
ТабличныйДокумент = СкомпоноватьВТабличныйДокументЛкс(СхемаКомпоновки, НастройкаКомпоновки, ТабличныйДокумент, ВнешниеНаборыДанных,
ДанныеРасшифровки, АвтофиксацияШапки,, Истина);
Возврат ТабличныйДокумент;
КонецФункции
Функция СкомпоноватьВТабличныйДокументЛкс(СхемаКомпоновки, НастройкаКомпоновки, Знач ТабличныйДокумент = Неопределено, ВнешниеНаборыДанных = Неопределено,
ДанныеРасшифровки = Неопределено, АвтофиксацияШапки = Истина, ПроверятьДоступностьПолей = Ложь, ВстроитьЗначенияПолейВРасшифровки = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура);
КонецЕсли;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Если ДанныеРасшифровки = Неопределено Тогда
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
КонецЕсли;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, НастройкаКомпоновки, ДанныеРасшифровки,,, ПроверятьДоступностьПолей);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки);
Если ТабличныйДокумент = Неопределено Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
КонецЕсли;
ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(ТабличныйДокумент, ПроцессорКомпоновки, ДанныеРасшифровки.Элементы,,, АвтофиксацияШапки);
Если ВстроитьЗначенияПолейВРасшифровки Тогда
Для НомерСтроки = 1 По ТабличныйДокумент.ВысотаТаблицы Цикл
Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Ячейка = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
ИдентификаторРасшифровки = Ячейка.Расшифровка;
Если ТипЗнч(ИдентификаторРасшифровки) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
ЗначенияПолей = ДанныеРасшифровки.Элементы[ИдентификаторРасшифровки].ПолучитьПоля();
Если ЗначенияПолей.Количество() > 0 Тогда
Ячейка.Расшифровка = ЗначенияПолей[0].Значение;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
Возврат ТабличныйДокумент;
КонецФункции
// мВнешниеНаборыДанных - Структура, Неопределено - не очищается
Функция ДополнитьСтруктуруВнешихНаборовДанныхПустышкамиЛкс(лСхемаКомпоновкиДанных, мВнешниеНаборыДанных = Неопределено) Экспорт
Если мВнешниеНаборыДанных = Неопределено Тогда
мВнешниеНаборыДанных = Новый Структура();
КонецЕсли;
// Создадим пустышки внешних наборов данных, если они не переданы
ОбъектТаблица = 0;
Для Каждого НаборДанных Из лСхемаКомпоновкиДанных.НаборыДанных Цикл
Если ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Тогда
Если НаборДанных.ИмяОбъекта = "" Тогда
Продолжить;
КонецЕсли;
Если Не мВнешниеНаборыДанных.Свойство(НаборДанных.ИмяОбъекта, ОбъектТаблица) Тогда
ОбъектТаблица = Новый ТаблицаЗначений;
КонецЕсли;
Попытка
КолонкиОбъектаТаблицы = ОбъектТаблица.Колонки;
Исключение
// Тогда это табличная часть, но возможно и тут будет исключение
КолонкиОбъектаТаблицы = ОбъектТаблица.ВыгрузитьКолонки().Колонки;
КонецПопытки;
Если КолонкиОбъектаТаблицы.Количество() > 0 Тогда
Продолжить;
КонецЕсли;
Для Каждого Поле Из НаборДанных.Поля Цикл
Если ТипЗнч(Поле) = Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда
Если КолонкиОбъектаТаблицы.Найти(Поле.Поле) = Неопределено Тогда
КолонкиОбъектаТаблицы.Добавить(Поле.Поле, Поле.ТипЗначения);
КонецЕсли;
КонецЕсли;
КонецЦикла;
мВнешниеНаборыДанных.Вставить(НаборДанных.ИмяОбъекта, ОбъектТаблица);
КонецЕсли;
КонецЦикла;
Возврат мВнешниеНаборыДанных;
КонецФункции
Функция ВыбратьТипСсылкиВПолеВводаЛкс(Элемент, СтандартнаяОбработка, ОткрытьФормуВыбораСсылкиПослеВыбораТипа = Истина) Экспорт
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", Элемент, Элемент);
ТекущееЗначение = Элемент.Значение;
Если ЛиСсылкаНаОбъектБДЛкс(ТекущееЗначение, Ложь) Тогда
НачальноеЗначениеВыбора = ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ТекущееЗначение));
КонецЕсли;
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина);
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
ЗначениеВыбора = Форма.ОткрытьМодально();
Если ТипЗнч(ЗначениеВыбора) = Тип("Структура") Тогда
лПолноеИмяОбъекта = Неопределено;
Если ЗначениеВыбора.Свойство("ПолноеИмяОбъекта", лПолноеИмяОбъекта) Тогда
ИмяТипаСсылки = ИмяТипаИзПолногоИмениМДЛкс(лПолноеИмяОбъекта, "Ссылка");
ОписаниеТипов = Новый ОписаниеТипов(ИмяТипаСсылки);
НовоеЗначение = ОписаниеТипов.ПривестиЗначение(Неопределено);
ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, НовоеЗначение);
Если ОткрытьФормуВыбораСсылкиПослеВыбораТипа Тогда
//Если ЛиСсылкаНаОбъектБДЛкс(НовоеЗначение, Ложь) Тогда
ОткрытьФормуСпискаЛкс(лПолноеИмяОбъекта,,, Элемент, Истина);
//КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтандартнаяОбработка = Ложь;
Возврат НовоеЗначение;
КонецФункции
// Результат - значение выбранного типа, но не обязательно выбранное (выбор типа выполняется синхронно, а значения - асинхронно)
Функция ПолеВвода_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка, ИгнорироватьОписаниеТипов = Ложь) Экспорт
РезультатВыбора = Элемент.Значение;
Если Истина
И ИгнорироватьОписаниеТипов
И (Ложь
Или ТипЗнч(Элемент.Значение) = Тип("Строка")
Или Элемент.Значение = Неопределено)
Тогда
РезультатВыбора = ВыбратьТипСсылкиВПолеВводаЛкс(Элемент, СтандартнаяОбработка);
ИначеЕсли ЛиСсылкаНаОбъектБДЛкс(Элемент.Значение, Ложь) Тогда
СтандартнаяОбработка = Ложь;
ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(Элемент.Значение)),,, Элемент, Истина,, Элемент.Значение);
Иначе
// Тут надо делать выбор из диалога плоского списка типов
КонецЕсли;
Возврат РезультатВыбора;
КонецФункции
// Для "Ссылка.Организация" вернет "Организация", для "Основание.Контрагент" вернет "ОснованиеКонтрагент"
// Параметры:
// ИмяПоля - Строка
Функция ПолучитьИмяКолонкиРезультатаПоИмениПоляЛкс(Знач ИмяПоля) Экспорт
Начало = "Ссылка.";
ДлинаНачала = СтрДлина(Начало);
Если СтрокиРавныЛкс(Лев(ИмяПоля, ДлинаНачала), Начало) Тогда
ИмяПоля = Сред(ИмяПоля, ДлинаНачала + 1);
КонецЕсли;
ИмяПоля = СтрЗаменить(ИмяПоля, ".", "");
Возврат ИмяПоля;
КонецФункции
Процедура ДобавитьМногострочнуюСтрокуВТекстЛкс(СобираемыйТекст, Выражение, Смещение, СНовойСтроки = Ложь) Экспорт
Если СНовойСтроки Тогда
СобираемыйТекст = СобираемыйТекст + Символы.ПС + Смещение;
КонецЕсли;
СобираемыйТекст = СобираемыйТекст + СтрПолучитьСтроку(Выражение, 1);
Для Счетчик = 2 По СтрЧислоСтрок(Выражение) Цикл
СобираемыйТекст = СобираемыйТекст + Символы.ПС + Смещение + СтрПолучитьСтроку(Выражение, Счетчик);
КонецЦикла;
КонецПроцедуры
Функция ПолучитьИндексКартинкиТипаЛкс(ОписаниеТипов) Экспорт
Если ОписаниеТипов = Неопределено Тогда
Возврат 14;
КонецЕсли;
Типы = ОписаниеТипов.Типы();
Если Типы.Количество() = 1 Тогда
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(Типы[0]);
Если Типы[0] = Тип("Число") Тогда
ИндексКартинки = 0;
ИначеЕсли Типы[0] = Тип("Строка") Тогда
ИндексКартинки = 1;
ИначеЕсли Типы[0] = Тип("Дата") Тогда
ИндексКартинки = 2;
ИначеЕсли Типы[0] = Тип("Булево") Тогда
ИндексКартинки = 3;
ИначеЕсли Типы[0] = Тип("ТаблицаЗначений") Тогда
ИндексКартинки = 19;
ИначеЕсли Типы[0] = Тип("Тип") Тогда
ИндексКартинки = 20;
ИначеЕсли КорневойТип = "Справочник" Тогда
ИндексКартинки = 7;
ИначеЕсли КорневойТип = "Документ" Тогда
ИндексКартинки = 8;
ИначеЕсли КорневойТип = "Перечисление" Тогда
ИндексКартинки = 9;
ИначеЕсли КорневойТип = "ПланВидовХарактеристик" Тогда
ИндексКартинки = 10;
ИначеЕсли КорневойТип = "ПланСчетов" Тогда
ИндексКартинки = 11;
ИначеЕсли КорневойТип = "ПланВидовРасчета" Тогда
ИндексКартинки = 12;
ИначеЕсли КорневойТип = "БизнесПроцесс" Тогда
ИндексКартинки = 13;
ИначеЕсли КорневойТип = "ТочкаМаршрута" Тогда
ИндексКартинки = 14;
ИначеЕсли КорневойТип = "Задача" Тогда
ИндексКартинки = 15;
Иначе
ИндексКартинки = 16;
КонецЕсли;
Иначе
ИндексКартинки = 16;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции
// Получает строку для установки порядка компоновки.
//
// Параметры:
// ПорядокКомпоновки – ПорядокКомпоновкиДанных.
//
// Возвращаемое значение:
// Строка - для установки порядка.
//
Функция ПолучитьВыражениеПорядкаКомпоновкиНаЯзыкеЛкс(ПорядокКомпоновки, ИсключаемоеПоле = "", СимволЗаменыТочки = Неопределено, ДиалектSQL = "1C") Экспорт
Строка = "";
Если СтрокиРавныЛкс(ДиалектSQL, "1С") Тогда
СтрокаВозр = "Возр";
СтрокаУбыв = "Убыв";
Иначе
СтрокаВозр = "Asc";
СтрокаУбыв = "Desc";
КонецЕсли;
Для Каждого ЭлементПорядка Из ПорядокКомпоновки.Элементы Цикл
Если Ложь
Или Не ЭлементПорядка.Использование
Или ТипЗнч(ЭлементПорядка) = Тип("АвтоЭлементПорядкаКомпоновкиДанных")
Или ИсключаемоеПоле = "" + ЭлементПорядка.Поле
Тогда
Продолжить;
КонецЕсли;
ИмяПоля = "" + ЭлементПорядка.Поле;
Если СимволЗаменыТочки <> Неопределено Тогда
ИмяПоля = СтрЗаменить(ИмяПоля, ".", СимволЗаменыТочки);
КонецЕсли;
Строка = Строка + ", " + ИмяПоля + " ";
Если ЭлементПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда
Строка = Строка + СтрокаВозр;
Иначе
Строка = Строка + СтрокаУбыв;
КонецЕсли;
КонецЦикла;
Возврат Сред(Строка, 3);
КонецФункции // ПолучитьСтрокуПорядкаКомпоновкиЛкс()
Функция ПолучитьПреставлениеСочетанияКлавишЛкс(СочетаниеКлавиш) Экспорт
Представление = "";
Если СочетаниеКлавиш.Alt Тогда
Представление = Представление + "Alt+";
КонецЕсли;
Если СочетаниеКлавиш.Ctrl Тогда
Представление = Представление + "Ctrl+";
КонецЕсли;
Если СочетаниеКлавиш.Shift Тогда
Представление = Представление + "Shift+";
КонецЕсли;
Представление = Представление + СочетаниеКлавиш.Клавиша;
Возврат Представление;
КонецФункции
////////////////////////////////
// ФОРМЫ
Процедура ИнициализироватьФормуЛкс(ЭтаФорма, ПолноеИмяФормы) Экспорт
// Проверяем режим модальности
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
// Проверка контроля модальности
СпрашиватьОПерезапуске = Истина;
Список = Новый СписокЗначений;
Попытка
Список.ВыбратьЭлемент();
Исключение
СпрашиватьОПерезапуске = Ложь;
КонецПопытки;
Если Ложь
Или мПлатформа.ИДВерсииПлатформы = "82"
Или мПлатформа.мВопросОтключенияПроверкиМодальностиЗадавался = Истина
Или Метаданные.РежимИспользованияМодальности = Метаданные.СвойстваОбъектов.РежимИспользованияМодальности.Использовать
Тогда
Если Не СпрашиватьОПерезапуске Тогда
ВызватьИсключение "При запуске приложения из конфигуратора автоматически включается контроль модальности.
|Запустите приложение другим способом, чтобы разрешить модальность.";
КонецЕсли;
Иначе
ИдентификаторПроцессаОС = мПлатформа.ПолучитьИдентификаторПроцессаОС();
ТекущийПроцесс = ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2:Win32_Process.Handle='" + XMLСтрока(ИдентификаторПроцессаОС) + "'");
КоманднаяСтрокаПроцесса = ТекущийПроцесс.CommandLine;
мПлатформа.мВопросОтключенияПроверкиМодальностиЗадавался = Истина;
Если Ложь
Или Найти(КоманднаяСтрокаПроцесса, "/EnableCheckModal") > 0
//Или Найти(КоманднаяСтрокаПроцесса, "/EnableCheckExtensionsAndAddInsSyncCalls") > 0
Тогда
Если СпрашиватьОПерезапуске Тогда
Ответ = Вопрос("Сеанс запущен с проверкой модальности. Хотите перезапустить его с отключением проверки?", РежимДиалогаВопрос.ДаНет, 10, КодВозвратаДиалога.Нет);
Иначе
Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если Ответ = КодВозвратаДиалога.Да Тогда
ПараметрыЗапуска = ирОбщий.ПолучитьПоследнийФрагментЛкс(КоманднаяСтрокаПроцесса, ".exe""");
ПараметрыЗапуска = СтрЗаменить(ПараметрыЗапуска, "/EnableCheckModal", "");
//ПараметрыЗапуска = СтрЗаменить(ПараметрыЗапуска, "/EnableCheckExtensionsAndAddInsSyncCalls", "");
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /Execute""" + ирПортативный.ИспользуемоеИмяФайла + """";
КонецЕсли;
ЗапуститьПриложение("1cv8.exe " + ПараметрыЗапуска, КаталогПрограммы());
Если СпрашиватьОПерезапуске Тогда
ЗавершитьРаботуСистемы();
Иначе
ТекстСообщения = "При запуске сеанса из конфигуратора автоматически включается контроль модальности. Запущен новый сеанс без контроля модальности.";
Выполнить("ПоказатьПредупреждение(, ТекстСообщения)");
КонецЕсли;
Возврат;
КонецЕсли;
КонецЕсли;
КонецЕсли;
#Если (ТолстыйКлиентОбычноеПриложение ИЛИ ТолстыйКлиентУправляемоеПриложение) И Не Сервер Тогда
// Проверка компиляции общих модулей с обработчиками событий
Если мПлатформа.мПроверкаКомпиляцииОбщихМодулейВыполнялась <> Истина Тогда
СписокМодулей = Новый Структура;
ОбщиеМодули = Метаданные.ОбщиеМодули;
#Если ТолстыйКлиентУправляемоеПриложение Тогда
ИмяКлиента = "Управляемое";
#Иначе
ИмяКлиента = "Обычное";
#КонецЕсли
ИмяСвойства = "Клиент" + ИмяКлиента + "Приложение";
Для Каждого Подписка Из Метаданные.ПодпискиНаСобытия Цикл
МетаМодуль = ОбщиеМодули.Найти(ирОбщий.ПолучитьПервыйФрагментЛкс(Подписка.Обработчик));
Если МетаМодуль = Неопределено Тогда
// Некорректная подписка
Продолжить;
КонецЕсли;
Если Не МетаМодуль[ИмяСвойства] И Не МетаМодуль.ВызовСервера Тогда
СписокМодулей.Вставить(МетаМодуль.Имя);
КонецЕсли;
КонецЦикла;
Если СписокМодулей.Количество() > 0 Тогда
Если ИмяКлиента = "Управляемое" Тогда
Сообщить("Для работы с инструментами в этой конфигурации рекомендуется использовать режим запуска ""Обычное приложение"".");
КонецЕсли;
Сообщить("В конфигурации обнаружены недоступные на клиенте (" + ИмяКлиента + " приложение) общие модули с обработчиками подписок на события.", СтатусСообщения.Внимание);
Сообщить("Поэтому при работе инструментов возможны ошибки ""При подписке * на событие * произошла ошибка. Обработчик события не найден.""");
Если ИмяКлиента = "Обычное" Тогда
Сообщить("Необходимо в конфигураторе установить ""Сервис""/""Параметры""/""Редактирование конфигурации для режимов запуска""=""Управляемое приложение и обычное приложение"".");
КонецЕсли;
Сообщить("Необходимо установить флажок ""Клиент (" + ИмяКлиента + " приложение)"" или ""Вызова сервера"" и обеспечить компиляцию у общих модулей:");
Для Каждого КлючИЗначение Из СписокМодулей Цикл
Сообщить("- " + КлючИЗначение.Ключ);
КонецЦикла;
КонецЕсли;
мПлатформа.мПроверкаКомпиляцииОбщихМодулейВыполнялась = Истина;
#Если ТолстыйКлиентОбычноеПриложение Тогда
Если Истина
И Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение
И Не Метаданные.ИспользоватьУправляемыеФормыВОбычномПриложении
Тогда
Сообщить("Рекомендуется включить в свойствах конфигурации флажок ""Использовать управляемые формы в обычном приложении""");
КонецЕсли;
#КонецЕсли
КонецЕсли;
#КонецЕсли
//// Проверяем защиту от опасных действий
//// Здесь это делать бесполезно, т.к. она срабатывает раньше
//Если Истина
// И ирКэш.ЛиПортативныйРежимЛкс()
// И мПлатформа.мПроверкаЗащитыОтОпасныхДействийВыполнялась <> Истина
// //И мПлатформа.ВерсияПлатформы < 803010 // Когда в платформе исправят проблему, тогда и отключим
//Тогда
// ТекущийПользовательБазы = ПользователиИнформационнойБазы.ТекущийПользователь();
// Попытка
// ЗащитаОтОпасныхДействий = ТекущийПользовательБазы.ЗащитаОтОпасныхДействий;
// Исключение
// ЗащитаОтОпасныхДействий = Неопределено;
// КонецПопытки;
// Если Истина
// И ЗначениеЗаполнено(ТекущийПользовательБазы.Имя)
// И ЗащитаОтОпасныхДействий <> Неопределено
// И ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Истина
// Тогда
// Ответ = Вопрос("У текущего пользователя базы включена защита от опасных действий.
// |Для корректной работы с инструментами ее рекомендуется отключить. Сделать это (сеанс будет перезапущен)?", РежимДиалогаВопрос.ДаНет, 10, РежимДиалогаВопрос.Нет);
// Если Ответ = КодВозвратаДиалога.Да Тогда
// ТекущийПользовательБазы.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Ложь;
// ТекущийПользовательБазы.Записать();
// ПараметрыЗапуска = "";
// Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
// ПараметрыЗапуска = ПараметрыЗапуска + " /Execute""" + ирПортативный.ИспользуемоеИмяФайла + """";
// КонецЕсли;
// ЗавершитьРаботуСистемы(, Истина, ПараметрыЗапуска);
// КонецЕсли;
// КонецЕсли;
// мПлатформа.мПроверкаЗащитыОтОпасныхДействийВыполнялась = Истина;
//КонецЕсли;
НастроитьЭлементыФормыЛкс(ЭтаФорма);
Форма_ВставитьСкрытуюКоманднуюПанельДляРаботыСБуферомОбменаЛкс(ЭтаФорма);
мСвойстваФормы = ПолучитьДопСвойстваФормыЛкс(ЭтаФорма);
мСвойстваФормы.Вставить("ИмяФормы", ПолноеИмяФормы);
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
Контейнер = Новый Структура();
Оповестить("ирПолучитьБазовуюФорму", Контейнер);
Если Не Контейнер.Свойство("ирПортативный") Тогда
БазоваяФорма = ирПортативный.ПолучитьФорму();
БазоваяФорма.Открыть();
КонецЕсли;
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтрокаВызова = "ирПортативный.ИнициализироватьФорму_" + мПлатформа.ПолучитьИдентификаторИзПредставления(ПолноеИмяФормы) + "(ЭтаФорма)";
Выполнить(СтрокаВызова);
Иначе
МетаФорма = Метаданные.НайтиПоПолномуИмени(ПолноеИмяФормы);
Если МетаФорма = Неопределено Тогда
Сообщить("Метаформа не найдена по полному имени """ + ПолноеИмяФормы + """", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьДопСвойстваФормыЛкс(ЭтаФорма)
СвойстваФормы = ЭтаФорма.Панель.Страницы[0].Значение;
Если СвойстваФормы = Неопределено Тогда
СвойстваФормы = Новый Структура();
ЭтаФорма.Панель.Страницы[0].Значение = СвойстваФормы;
КонецЕсли;
Возврат СвойстваФормы;
КонецФункции
Процедура НастроитьЭлементыФормыЛкс(ЭтаФорма) Экспорт
мСвойстваФормы = ПолучитьДопСвойстваФормыЛкс(ЭтаФорма);
КнопкиВсехДействийКомандныхПанелей = Новый Соответствие;
ИмяКнопки = "СтруктураКоманднойПанели";
Для Каждого ЭлементФормы Из ЭтаФорма.ЭлементыФормы Цикл
// Встраиваем кнопки структуры командной панели
КоманднаяПанель = Неопределено;
ВстроитьВНачало = Истина;
Если ТипЗнч(ЭлементФормы) = Тип("КоманднаяПанель") Тогда
КоманднаяПанель = ЭлементФормы;
Если Не КоманднаяПанель.Видимость Тогда
Продолжить;
КонецЕсли;
//ИначеЕсли ТипЗнч(ЭлементФормы) = Тип("ТабличноеПоле") Тогда
// КоманднаяПанель = ЭлементФормы.КонтекстноеМеню;
Иначе
Попытка
// В контекстных меню функция маловостребована, т.к. они имеют обычно более простую структуру и там сразу виден текст всех кнопок
КоманднаяПанель = ЭлементФормы.КонтекстноеМеню;
ВстроитьВНачало = Ложь;
Исключение
КонецПопытки;
КонецЕсли;
Если Истина
И КоманднаяПанель <> Неопределено
И КоманднаяПанель.Кнопки.Найти(ИмяКнопки) = Неопределено
Тогда
НужноВстроить = Ложь;
КоличествоКнопок = 0;
Для Каждого Кнопка Из КоманднаяПанель.Кнопки Цикл
Если Кнопка.ТипКнопки <> ТипКнопкиКоманднойПанели.Разделитель Тогда
КоличествоКнопок = КоличествоКнопок + 1;
Если КоличествоКнопок > 4 Тогда
НужноВстроить = Истина;
Прервать;
КонецЕсли;
КонецЕсли;
Если Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда
НужноВстроить = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НужноВстроить Тогда
Если ВстроитьВНачало Тогда
КнопкаСтруктураКоманднойПанели = КоманднаяПанель.Кнопки.Вставить(0);
Иначе
КнопкаСтруктураКоманднойПанели = КоманднаяПанель.Кнопки.Добавить();
КонецЕсли;
КнопкаСтруктураКоманднойПанели.Имя = ИмяКнопки;
КнопкаСтруктураКоманднойПанели.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
КнопкаСтруктураКоманднойПанели.Картинка = ПолучитьОбщуюКартинкуЛкс("ирКоманднаяПанель");
КнопкаСтруктураКоманднойПанели.Отображение = ОтображениеКнопкиКоманднойПанели.Авто;
КнопкаСтруктураКоманднойПанели.Текст = "Структура командной панели";
КнопкаСтруктураКоманднойПанели.Подсказка = "Открыть структуру командной панели";
Попытка
КнопкаСтруктураКоманднойПанели.Действие = Новый Действие("СтруктураКоманднойПанелиНажатие");
Исключение
// В этой форме нет обработчика
Возврат;
КонецПопытки;
КнопкиВсехДействийКомандныхПанелей.Вставить(КнопкаСтруктураКоманднойПанели, КоманднаяПанель);
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ЭлементФормы) = Тип("ТабличноеПоле") Тогда
НастроитьТабличноеПолеЛкс(ЭлементФормы);
КонецЕсли;
КонецЦикла;
мСвойстваФормы.Вставить("КнопкиВсехДействийКомандныхПанелей", КнопкиВсехДействийКомандныхПанелей);
КонецПроцедуры
Процедура НастроитьТабличноеПолеЛкс(Знач ЭлементФормы) Экспорт
// Возвращаем старый стиль шапок колонок, при котором видна текущая колонка
Если ЭлементФормы.Колонки.Количество() > 0 Тогда
// Антифича платформы 8.2 http://partners.v8.1c.ru/forum/thread.jsp?id=898034
Если ЭлементФормы.Колонки[0].ЦветФонаШапки <> ЦветаСтиля.ЦветФонаКнопки Тогда
ЭлементФормы.Колонки[0].ЦветФонаШапки = ЦветаСтиля.ЦветФонаКнопки;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьСтруктуруКоманднойПанелиЛкс(ЭтаФорма, Знач Кнопка = Неопределено) Экспорт
мСвойстваФормы = ПолучитьДопСвойстваФормыЛкс(ЭтаФорма);
КоманднаяПанель = мСвойстваФормы.КнопкиВсехДействийКомандныхПанелей[Кнопка];
Если Кнопка <> Неопределено Тогда
Если КоманднаяПанель.Кнопки.Индекс(Кнопка) = -1 Тогда
// Для контекстных меню
КоманднаяПанель = КоманднаяПанель.Кнопки[0];
КонецЕсли;
КонецЕсли;
ФормаСтруктуры = ирКэш.Получить().ПолучитьФорму("СтруктураФормы");
ФормаСтруктуры.ПараметрЭлементФормы = КоманднаяПанель;
ФормаСтруктуры.Форма = ЭтаФорма;
ФормаСтруктуры.ОткрытьМодально();
КонецПроцедуры
Процедура ОткрытьСтруктуруФормыЛкс(ЭтаФорма) Экспорт
ФормаСтруктуры = ирКэш.Получить().ПолучитьФорму("СтруктураФормы");
ФормаСтруктуры.Форма = ЭтаФорма;
ФормаСтруктуры.ОткрытьМодально();
КонецПроцедуры
Функция ОткрытьФормуСоединенияСУБДЛкс(Автоподключение = Ложь) Экспорт
ФормаПодключения = ирКэш.Получить().ПолучитьФорму("ПараметрыСоединенияСУБД");
ФормаПодключения.Автоподключение = Автоподключение;
ФормаПодключения.ЗаполнитьПараметры();
Если Автоподключение И Не ирКэш.ЭтоФайловаяБазаЛкс() Тогда
ФормаПодключения.ОткрытьМодально();
КонецЕсли;
Возврат ФормаПодключения;
КонецФункции
#КонецЕсли
Функция ЛиПустаяПодгруппаRegExpЛкс(Подгруппа) Экспорт
Результат = Ложь
Или Подгруппа = Неопределено
Или Подгруппа = "";
Возврат Результат;
КонецФункции
Процедура ОбновитьКопиюСвойстваВНижнемРегистреЛкс(Объект, ИмяСвойства = "Имя") Экспорт
Объект["Н" + ИмяСвойства] = НРег(Объект[ИмяСвойства]);
КонецПроцедуры
Функция ПолучитьСхемуКолонокМакетаКомпоновкиДанныхЛкс(МакетКомпоновки) Экспорт
#Если Сервер И Не Сервер Тогда
МакетКомпоновки = Новый МакетКомпоновкиДанных;
#КонецЕсли
СхемаКолонок = Новый Структура;
// Схема колонок строится негарантировано, т.к. платформа не предоставляет нужных данных
ОписанияМакетовОбластей = МакетКомпоновки.Макеты;
Если ОписанияМакетовОбластей.Количество() > 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;
Возврат Результат;
КонецФункции
// Разделяет 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);
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("Схема", Схема);
Результат.Вставить("Логин", Логин);
Результат.Вставить("Пароль", Пароль);
Результат.Вставить("ИмяСервера", ИмяСервера);
Результат.Вставить("Хост", Хост);
Результат.Вставить("Порт", ?(ПустаяСтрока(Порт), Неопределено, Число(Порт)));
Результат.Вставить("ПутьНаСервере", ПутьНаСервере);
Возврат Результат;
КонецФункции
// Поиск числа в строке
//
// Параметры:
// ИсходнаяСтрока - Строка, строка в которой ищется число
// ПозицияЧисла - Число, позиция начала числа
// КоличествоСимволов - Число, количество символов числа
//
// Возвращаемое значение:
// Булево - Истина, число найдено
//
Функция НайтиЧислоВСтрокеЛкс(ИсходнаяСтрока, ПозицияЧисла, КоличествоСимволов) Экспорт
ПозицияЧисла = 0;
КоличествоСимволов = 0;
ДлинаСтроки = СтрДлина(ИсходнаяСтрока);
Для Сч = 1 По ДлинаСтроки Цикл
ТекущийСимвол = КодСимвола(Сред(ИсходнаяСтрока, Сч, 1));
Если 48 <= ТекущийСимвол И ТекущийСимвол <= 57 Тогда
Если ПозицияЧисла = 0 Тогда
ПозицияЧисла = Сч;
КоличествоСимволов = 1;
Иначе
КоличествоСимволов = КоличествоСимволов + 1;
КонецЕсли;
Иначе
Если ПозицияЧисла <> 0 Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат ПозицияЧисла > 0;
КонецФункции // НайтиЧислоВСтроке()
Процедура ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, НаСервере = Ложь, ВыводитьПредупрежденияИСообщения = Истина) Экспорт
#Если Клиент Тогда
Если ВыводитьПредупрежденияИСообщения Тогда
Ответ = КодВозвратаДиалога.ОК;
Если НаСервере Тогда
ОбщийРазмер = ирСервер.ВычислитьРазмерКаталогаЛкс(КаталогЖурнала);
Иначе
ОбщийРазмер = ВычислитьРазмерКаталогаЛкс(КаталогЖурнала);
КонецЕсли;
Если ОбщийРазмер > 0 Тогда
Ответ = Вопрос("Действительно удалить рекурсивно все файлы (" + Формат(Цел(ОбщийРазмер/1000000), "ЧН=") + "МБ) в каталоге журнала?", РежимДиалогаВопрос.ОКОтмена);
КонецЕсли;
Если Ответ <> КодВозвратаДиалога.ОК Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Если НаСервере Тогда
ирСервер.ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, ВыводитьПредупрежденияИСообщения);
Возврат;
КонецЕсли;
#КонецЕсли
ФайлыЖурнала = НайтиФайлы(КаталогЖурнала, "*.*", Истина);
Если ФайлыЖурнала.Количество() > 0 Тогда
СчетчикНеудаленных = 0;
Для Каждого ФайлЖурнала Из ФайлыЖурнала Цикл
Попытка
УдалитьФайлы(ФайлЖурнала.ПолноеИмя);
Исключение
СчетчикНеудаленных = СчетчикНеудаленных + 1;
КонецПопытки;
КонецЦикла;
Если ВыводитьПредупрежденияИСообщения Тогда
Если СчетчикНеудаленных > 0 Тогда
Сообщить("" + СчетчикНеудаленных + " файлов техножурнала удалить не удалось");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры // ОчиститьКаталогТехножурналаЛкс()
Функция ВычислитьРазмерКаталогаЛкс(Каталог, ВключаяПодкаталоги = Истина) Экспорт
Файлы = НайтиФайлы(Каталог, "*.*", ВключаяПодкаталоги);
ОбщийРазмер = 0;
Для Каждого Файл Из Файлы Цикл
Если Файл.ЭтоКаталог() Тогда
Продолжить;
КонецЕсли;
ОбщийРазмер = ОбщийРазмер + Файл.Размер();
КонецЦикла;
Возврат ОбщийРазмер;
КонецФункции
// Выполняет копирование файлов рекурсивно
Процедура СкопироватьФайлыЛкс(КаталогИсточник, КаталогПриемник) Экспорт
Файлы = НайтиФайлы(КаталогИсточник, "*.*");
Для Каждого Файл Из Файлы Цикл
ФайлПриемник = Новый Файл(КаталогПриемник + "\" + Файл.Имя);
Если Файл.ЭтоКаталог() Тогда
СоздатьКаталог(ФайлПриемник.ПолноеИмя);
СкопироватьФайлыЛкс(Файл.ПолноеИмя, ФайлПриемник.ПолноеИмя);
Продолжить;
КонецЕсли;
КопироватьФайл(Файл.ПолноеИмя, ФайлПриемник.ПолноеИмя);
КонецЦикла;
КонецПроцедуры
Процедура УстановитьПометкиРодителейЛкс(Знач Родитель, Знач ИмяДанныхФлажка = "Пометка") Экспорт
Если Родитель = Неопределено Тогда
Возврат;
КонецЕсли;
ТекСостояние = Родитель[ИмяДанныхФлажка];
НайденыВключенные = Ложь;
НайденыВыключенные = Ложь;
Для каждого Строка из Родитель.Строки Цикл
ЗначениеФлажка = Строка[ИмяДанныхФлажка];
Если ЗначениеФлажка = 0 Тогда
НайденыВыключенные = Истина;
ИначеЕсли ЗначениеФлажка = 1 Тогда
НайденыВключенные = Истина;
ИначеЕсли ЗначениеФлажка = 2 Тогда
НайденыВключенные = Истина;
НайденыВыключенные = Истина;
Прервать;
КонецЕсли;
Если НайденыВключенные И НайденыВыключенные Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если НайденыВключенные И НайденыВыключенные Тогда
Включить = 2;
ИначеЕсли НайденыВключенные И (Не НайденыВыключенные) Тогда
Включить = 1;
ИначеЕсли (Не НайденыВключенные) И НайденыВыключенные Тогда
Включить = 0;
ИначеЕсли (Не НайденыВключенные) И (Не НайденыВыключенные) Тогда
Включить = 2;
КонецЕсли;
Если Включить = ТекСостояние Тогда
Возврат;
Иначе
Родитель[ИмяДанныхФлажка] = Включить;
УстановитьПометкиРодителейЛкс(Родитель.Родитель, ИмяДанныхФлажка);
КонецЕсли;
КонецПроцедуры
Процедура УстановитьПометкиПодчиненныхЛкс(Знач ТекСтрока, Знач ИмяДанныхФлажка = "Пометка") Экспорт
ТекСостояние = ТекСтрока[ИмяДанныхФлажка];
Подчиненные = ТекСтрока.Строки;
Если ТекСостояние = 2 Тогда
ТекСтрока[ИмяДанныхФлажка] = 0;
КонецЕсли;
Если Подчиненные.Количество() > 0 Тогда
Для каждого Строка из Подчиненные Цикл
Строка[ИмяДанныхФлажка] = ТекСостояние;
УстановитьПометкиПодчиненныхЛкс(Строка, ИмяДанныхФлажка);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
// Разбирает строку на две части: до подстроки разделителя и после
//
// Параметры:
// Стр - разбираемая строка
// Разделитель - подстрока-разделитель
// Режим - 0 - разделитель в возвращаемые подстроки не включается
// 1 - разделитель включается в левую подстроку
// 2 - разделитель включается в правую подстроку
//
// Возвращаемое значение:
// Правая часть строки - до символа-разделителя
//
Функция ОтделитьРазделителемЛкс(Знач Стр, Знач Разделитель = ".", Режим = 0) Экспорт
ПраваяЧасть = "";
ПозРазделителя = Найти(Стр, Разделитель);
ДлинаРазделителя = СтрДлина(Разделитель);
Если ПозРазделителя > 0 Тогда
ПраваяЧасть = Сред(Стр, ПозРазделителя + ?(Режим=2, 0, ДлинаРазделителя));
Стр = СокрЛП(Лев(Стр, ПозРазделителя - ?(Режим=1, -ДлинаРазделителя+1, 1)));
КонецЕсли;
Возврат(ПраваяЧасть);
КонецФункции // вОтделитьРазделителем()
// Проверяет попадание даты внутрь интервала всключая границы
Функция ЛиДатаВИнтервалеСГраницамиЛкс(ПроверяемаяДата, НачалоПериода, КонецПериода) Экспорт
ЛиДатаВНеИнтервале = Ложь
Или (Истина
И ЗначениеЗаполнено(НачалоПериода)
И ПроверяемаяДата < НачалоПериода)
Или (Истина
И ЗначениеЗаполнено(КонецПериода)
И ПроверяемаяДата > КонецПериода);
Возврат Не ЛиДатаВНеИнтервале;
КонецФункции
// Проверяет попадание даты внутрь интервала исключая границы
Функция ЛиДатаВИнтервалеБезГраницЛкс(ПроверяемаяДата, НачалоПериода, КонецПериода) Экспорт
ПустаяДата = Дата("00010101");
ЛиДатаВНеИнтервале = Ложь
Или (Истина
И НачалоПериода <> ПустаяДата
И ПроверяемаяДата <= НачалоПериода)
Или (Истина
И КонецПериода <> ПустаяДата
И ПроверяемаяДата >= КонецПериода);
Возврат Не ЛиДатаВНеИнтервале;
КонецФункции
Функция ЛиКаталогДоступенЛкс(Каталог, ВыводитьСообщения = Истина) Экспорт
ПроверочныйФайл = Новый Файл(Каталог);
Попытка
ЭтоКаталог = ПроверочныйФайл.ЭтоКаталог();
Исключение
Если ВыводитьСообщения Тогда
Сообщить("Указанный путь """ + Каталог + """ не доступен: " + ОписаниеОшибки());
КонецЕсли;
Возврат Ложь;
КонецПопытки;
Если Не ЭтоКаталог Тогда
Если ВыводитьСообщения Тогда
Сообщить("Указанный путь """ + Каталог + """ не является каталогом");
КонецЕсли;
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции // ЛиКаталогДоступен()
Функция ПолучитьСтрокуФильтраДляВыбораФайлаЛкс(СтрокаРасширений, ОписаниеФормата = "", РазрешитьВсеФайлы = Истина) Экспорт
Расширения = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(СтрокаРасширений, ",", Истина);
Результат = "";
Для Каждого Расширение Из Расширения Цикл
Если Результат <> "" Тогда
Результат = Результат + "|";
КонецЕсли;
ОписаниеРасширения = "(*." + Расширение + ")|*." + Расширение;
Если ЗначениеЗаполнено(ОписаниеФормата) Тогда
ОписаниеРасширения = ОписаниеФормата + " " + ОписаниеРасширения;
КонецЕсли;
Результат = Результат + ОписаниеРасширения;
КонецЦикла;
Если РазрешитьВсеФайлы Тогда
Результат = Результат + "|Все файлы (*.*)|*.*";
КонецЕсли;
Возврат Результат;
КонецФункции
// Копирует все элементы переданного массива, структуры, соответствия, списка значений или коллекции объектов метаданных
// в однотипную коллекцию приемник (для метаданных в массив). Если коллекция приемник не указана, она будет создана.
// Фиксированные коллекции превращаются в нефиксированные.
//
// Параметры:
// КоллекцияИсходная - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - исходная коллекция;
// КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных, *Неопределено - коллекция приемник.
//
// Возвращаемое значение:
// КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - коллекция приемник.
//
Функция СкопироватьУниверсальнуюКоллекциюЛкс(КоллекцияИсточник, КоллекцияПриемник = Неопределено) Экспорт
ТипКоллекции = ТипЗнч(КоллекцияИсточник);
Если Ложь
Или ТипКоллекции = Тип("Массив")
Или ТипКоллекции = Тип("ФиксированныйМассив")
#Если Не ТонкийКлиент И Не ВебКлиент Тогда
Или ТипКоллекции = Тип("КоллекцияОбъектовМетаданных")
#КонецЕсли
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Массив;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Добавить(Элемент);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли Ложь
Или ТипКоллекции = Тип("Структура")
Или ТипКоллекции = Тип("ФиксированнаяСтруктура")
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Структура;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли Ложь
Или ТипКоллекции = Тип("Соответствие")
Или ТипКоллекции = Тип("ФиксированноеСоответствие")
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Соответствие;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли ТипКоллекции = Тип("СписокЗначений") Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый СписокЗначений;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
ЗаполнитьЗначенияСвойств(КоллекцияПриемник.Добавить(), Элемент);
КонецЦикла;
Возврат КоллекцияПриемник;
#Если Не ТонкийКлиент И Не ВебКлиент Тогда
ИначеЕсли ТипКоллекции = Тип("ТаблицаЗначений") Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = КоллекцияИсточник.СкопироватьКолонки();
КонецЕсли;
ЗагрузитьВТаблицуЗначенийЛкс(КоллекцияИсточник, КоллекцияПриемник);
Возврат КоллекцияПриемник;
#КонецЕсли
Иначе
Сообщить("Неверный тип универсальной коллекции для копирования """ + ТипКоллекции + """");
Возврат Неопределено;
КонецЕсли;
КонецФункции // СкопироватьУниверсальнуюКоллекциюЛкс()
#Если Не ТонкийКлиент И Не ВебКлиент Тогда
Функция ИменаИспользуемыхВЗапросеВременныхТаблицЛкс(Знач ЗапросИлиМенеджерВременныхТаблиц, Знач ОбязательныеДляПроверкиИмена = """") Экспорт
Платформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
Платформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
МассивИмен = ПолучитьМассивИзСтрокиСРазделителемЛкс(ОбязательныеДляПроверкиИмена, ",", Истина, Ложь);
ИменаИспользуемыхВременныхТаблиц = Платформа.НайтиВозможныеИменаВременныхТаблиц(ЗапросИлиМенеджерВременныхТаблиц.Текст);
Для Каждого ИмяИспользуемойВременнойТаблицы Из ИменаИспользуемыхВременныхТаблиц Цикл
МассивИмен.Добавить(ИмяИспользуемойВременнойТаблицы);
КонецЦикла;
Возврат МассивИмен;
КонецФункции // ПолВТ()
Процедура СкопироватьДеревоЛкс(ИсходноеДерево, НовоеДерево, ОчиститьПередЗагрузкой = Истина) Экспорт
Если ОчиститьПередЗагрузкой Тогда
НовоеДерево.Строки.Очистить();
КонецЕсли;
Если ИсходноеДерево.Строки.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Для каждого СтрокаДерева из ИсходноеДерево.Строки Цикл
НоваяСтрока = НовоеДерево.Строки.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаДерева);
СкопироватьДеревоЛкс(СтрокаДерева, НоваяСтрока, ОчиститьПередЗагрузкой = Истина);
КонецЦикла;
КонецПроцедуры
Функция СоздатьСамоудаляющийсяКомандныйФайлЛкс(Знач ТекстКомандногоФайла = "", Знач КраткоеИмяФайла = "") Экспорт
Если ЗначениеЗаполнено(КраткоеИмяФайла) Тогда
ПолноеИмяФайла = КаталогВременныхФайлов() + КраткоеИмяФайла + ".bat";
Иначе
ПолноеИмяФайла = ПолучитьИмяВременногоФайла("bat");
КонецЕсли;
ТекстКомандногоФайла = ТекстКомандногоФайла + "
|del """ + ПолноеИмяФайла + """
|";
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ТекстКомандногоФайла);
ТекстовыйДокумент.Записать(ПолноеИмяФайла, КодировкаТекста.OEM);
Результат = ПолноеИмяФайла;
Возврат Результат;
КонецФункции
// Проверить уникальность строк ТЧ по колонке иис
//
// Параметры:
// Объект - <тип> -
// ИмяТаблицы - <тип> -
// ИмяКолонки - <тип>, "" -
//
// Возвращаемое значение:
//
Функция ПроверитьУникальностьСтрокТЧПоКолонкеЛкс(Объект, ИмяТаблицы, ИмяКолонки = "", ИгнорироватьРегистрДляПростогоСтрокогоТипа = Истина, ОтборСтрок = Неопределено,
МассивИсключений = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ИмяКолонки = Объект.Метаданные().ТабличныеЧасти[ИмяТаблицы].Реквизиты[0].Имя;
КонецЕсли;
Если Истина
И МассивИсключений <> Неопределено
И ИгнорироватьРегистрДляПростогоСтрокогоТипа
Тогда
НовыйМассивИсключений = Новый Массив;
Для Каждого ИсключаемоеЗначение Из МассивИсключений Цикл
Если ТипЗнч(ИсключаемоеЗначение) = Тип("Строка") Тогда
ИсключаемоеЗначение = НРег(ИсключаемоеЗначение);
КонецЕсли;
НовыйМассивИсключений.Добавить(ИсключаемоеЗначение);
КонецЦикла;
МассивИсключений = НовыйМассивИсключений;
КонецЕсли;
Успех = Истина;
НеуникальныеЗначения = ПолучитьНеуникальныеЗначенияКолонкиТаблицыЛкс(Объект[ИмяТаблицы], ИмяКолонки, ИгнорироватьРегистрДляПростогоСтрокогоТипа, ОтборСтрок);
Для Каждого НеуникальноеЗначение Из НеуникальныеЗначения Цикл
Если Истина
И МассивИсключений <> Неопределено
И МассивИсключений.Найти(НеуникальноеЗначение) <> Неопределено
Тогда
Продолжить;
КонецЕсли;
Сообщить("Значение """ + НеуникальноеЗначение + """ встречается в колонке """ + ИмяКолонки + """ более одного раза среди активных строк", СтатусСообщения.Внимание);
Успех = Ложь;
КонецЦикла;
Возврат Успех;
КонецФункции
Функция ПолучитьПроцессОСЛкс(Знач ИдентификаторПроцесса = Неопределено, Знач НачалоПроцесса = Неопределено, Знач Компьютер = Неопределено,
ВызватьИсключениеПриОшибкеПодключения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);
Для Каждого ПроцессОС Из ВыборкаПроцессовОС Цикл
Результат = ПроцессОС;
Прервать;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ЭтоЛокальныйКомпьютерЛкс(Компьютер) Экспорт
Результат = Ложь
Или Не ЗначениеЗаполнено(Компьютер)
Или Компьютер = "."
Или СтрокиРавныЛкс(Компьютер, "localhost")
Или Компьютер = "127.0.0.1"
#Если Не ВебКлиент Тогда
Или СтрокиРавныЛкс(Компьютер, ИмяКомпьютера())
#КонецЕсли
;
Возврат Результат;
КонецФункции
Функция ПолучитьЛитералДатыДляWQLЛкс(Знач Результат) Экспорт
Результат = Результат - СмещениеСтандартногоВремени();
Результат = "'" + Формат(Результат, "ДФ='yyyyMMdd HH:mm:ss'; ДП=") + "'";
Возврат Результат
КонецФункции
Функция ПолучитьФайлWMIЛкс(ПолноеИмяФайла, КомпьютерИлиИмя = Неопределено) Экспорт
СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс(КомпьютерИлиИмя);
ФайлыWMI = СлужбаWMI.ExecQuery("Select * from CIM_Datafile where name='" + ЗаменитьСлешиНаДвойныеЛкс(ПолноеИмяФайла) + "'");
Для каждого ФайлWMI Из Файлы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С" // русские буквы
И ПубликаторПродукта <> "1С-Софт" // русские буквы
Тогда
Продолжить;
КонецЕсли;
//НаименованиеПродукта = Инсталлер.ProductInfo(Продукт, "ProductName");
КаталогВерсии = Инсталлер.ProductInfo(Продукт, "InstallLocation");
//СтрокаРелиза = Инсталлер.ProductInfo(Продукт, "VersionString");
Иначе
КаталогВерсии = Продукт.InstallLocation;
КонецЕсли;
СтрокаТаблицыСборок = СборкиПлатформы.Добавить();
СтрокаТаблицыСборок.Каталог = КаталогВерсии;
ФайлПолученияВерсии = Неопределено;
Если ТипыComКлассов <> Неопределено Тогда
Для Каждого ТипКласса Из ТипыComКлассов Цикл
//Если Метаданные().ТабличныеЧасти.СборкиПлатформы.Реквизиты.Найти(ВыборкаКлассов.Имя) = Неопределено Тогда
// Продолжить;
//КонецЕсли;
ФайлКомпоненты = ПолучитьФайлWMIЛкс(СтрокаТаблицыСборок.Каталог + "bin\" + ТипКласса.КлючевойФайл, Компьютер);
СтрокаТаблицыСборок[ТипКласса.Имя] = ФайлКомпоненты <> Неопределено;
Если СтрокаТаблицыСборок[ТипКласса.Имя] Тогда
ФайлПолученияВерсии = ФайлКомпоненты;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ФайлСерверногоПриложения = ПолучитьФайлWMIЛкс(СтрокаТаблицыСборок.Каталог + "bin\ragent.exe", Компьютер);
СтрокаТаблицыСборок.Сервер = ФайлСерверногоПриложения <> Неопределено;
Если СтрокаТаблицыСборок.Сервер Тогда
ФайлПолученияВерсии = ФайлСерверногоПриложения;
КонецЕсли;
Если ФайлПолученияВерсии <> Неопределено Тогда
СтрокаТаблицыСборок.ФайлыСуществуют = Истина;
СтрокаТаблицыСборок.x64 = ирКэш.Это64битнаяОСЛкс() И Найти(СтрокаТаблицыСборок.Каталог, "(x86)") = 0;
СтрокаТаблицыСборок.СборкаПлатформы = ФайлПолученияВерсии.Version;
СтрокаВерсии = ФайлПолученияВерсии.Version;
Если ЗначениеЗаполнено(СтрокаВерсии) Тогда
СтрокаТаблицыСборок.СборкаПлатформы = СтрокаВерсии;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(СтрокаВерсии);
ИзданиеПлатформы = Фрагменты[0] + "." + Фрагменты[1];
СтрокаТаблицыСборок.ИзданиеПлатформы = ИзданиеПлатформы;
СтрокаТаблицыСборок.Порядок = Фрагменты[0] * 10000000 + Фрагменты[1] * 1000000 + Фрагменты[2] * 10000 + Фрагменты[3];
КонецЕсли;
КонецЕсли;
КонецЦикла;
СборкиПлатформы.Сортировать("Порядок Убыв, ФайлыСуществуют Убыв, СборкаПлатформы Убыв, x64");
КонецПроцедуры
Функция ЗаменитьСлешиНаДвойныеЛкс(Строка) Экспорт
Результат = СтрЗаменить(Строка, "\", "\\");
Возврат Результат;
КонецФункции
Функция ПолучитьТекстРезультатаКомандыОСЛкс(Знач СтрокаКоманды = "", ОжидатьЗавершения = Истина, Знач ИмяКомпьютера = "", Элевация = Ложь) Экспорт
Платформа = ирКэш.Получить();
Если Ложь Тогда
Платформа = Обработки.ирПлатформа.Создать();
КонецЕсли;
ФайлРезультата = Новый Файл(ПолучитьИмяВременногоФайла("txt"));
Платформа.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(СтрокаКоманды, ФайлРезультата.Путь,, ФайлРезультата.Имя, ОжидатьЗавершения, Элевация);
Если ОжидатьЗавершения Тогда
Если ФайлРезультата.Существует() Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ФайлРезультата.ПолноеИмя, КодировкаТекста.OEM);
УдалитьФайлы(ФайлРезультата.ПолноеИмя);
Результат = ТекстовыйДокумент.ПолучитьТекст();
Иначе
Результат = Неопределено;
КонецЕсли;
Иначе
Результат = ФайлРезультата.ПолноеИмя;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ЗаблокироватьНаборЗаписейПоОтборуЛкс(НаборЗаписей, НичегоНеДелатьБезТранзакции = Ложь) Экспорт
Если Ложь
Или Метаданные.РежимУправленияБлокировкойДанных = Метаданные.СвойстваОбъектов.РежимУправленияБлокировкойДанныхПоУмолчанию.Автоматический
Или (Истина
И НичегоНеДелатьБезТранзакции
И Не ТранзакцияАктивна())
Тогда
Возврат;
КонецЕсли;
Блокировка = Новый БлокировкаДанных;
ОбъектМД = НаборЗаписей.Метаданные();
ПространствоБлокировок = ОбъектМД.ПолноеИмя();
КорневойТип = ПолучитьПервыйФрагментЛкс(ПространствоБлокировок);
Если ирОбщий.ПолучитьТипТаблицыБДЛкс(ПространствоБлокировок) = "Перерасчет" Тогда
Возврат;
//ПространствоБлокировок = ОбъектМД.Родитель().ПолноеИмя();
КонецЕсли;
Если Ложь
Или Не ЛиКорневойТипРегистраСведенийЛкс(КорневойТип)
Или ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору
Тогда
ПространствоБлокировок = ПространствоБлокировок + ".НаборЗаписей";
КонецЕсли;
ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок);
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
Если ЭлементОтбора.Использование Тогда
ЭлементБлокировки.УстановитьЗначение(ЭлементОтбора.Имя, ЭлементОтбора.Значение);
КонецЕсли;
КонецЦикла;
Блокировка.Заблокировать();
КонецПроцедуры
Процедура ЗаблокироватьСсылкуВТранзакцииЛкс(СсылочныйОбъект, НичегоНеДелатьБезТранзакции = Ложь) Экспорт
Если Ложь
Или Метаданные.РежимУправленияБлокировкойДанных = Метаданные.СвойстваОбъектов.РежимУправленияБлокировкойДанныхПоУмолчанию.Автоматический
Или (Истина
И НичегоНеДелатьБезТранзакции
И Не ТранзакцияАктивна())
Тогда
Возврат;
КонецЕсли;
Блокировка = Новый БлокировкаДанных;
ОбъектМД = СсылочныйОбъект.Метаданные();
ПространствоБлокировок = ОбъектМД.ПолноеИмя();
ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок);
ЭлементБлокировки.УстановитьЗначение("Ссылка", СсылочныйОбъект.Ссылка);
Блокировка.Заблокировать();
КонецПроцедуры
Процедура ЗаблокироватьКонстантуЛкс(КонстантаМенеджерЗначения, НичегоНеДелатьБезТранзакции = Ложь) Экспорт
Если Ложь
Или Метаданные.РежимУправленияБлокировкойДанных = Метаданные.СвойстваОбъектов.РежимУправленияБлокировкойДанныхПоУмолчанию.Автоматический
Или (Истина
И НичегоНеДелатьБезТранзакции
И Не ТранзакцияАктивна())
Тогда
Возврат;
КонецЕсли;
Блокировка = Новый БлокировкаДанных;
ОбъектМД = КонстантаМенеджерЗначения.Метаданные();
ПространствоБлокировок = ОбъектМД.ПолноеИмя();
ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок);
Блокировка.Заблокировать();
КонецПроцедуры
Функция ПолучитьПредставлениеПоляБДЛкс(СтрокаПоля, ЛиИменаБД = Ложь, ЭтоТабличнаяЧасть = Ложь, ИспользоватьИмяПоляВместоПустогоПредставления = Ложь) Экспорт
ПредставлениеПоля = СтрокаПоля.ИмяПоля;
Если ПустаяСтрока(ПредставлениеПоля) Тогда
Если ЛиИменаБД Тогда
// Антибаг платформы. У некоторых полей почему то пустое имя, а должно быть непустое. https://partners.v8.1c.ru/forum/topic/1275356#m_1275356
Если ЭтоТабличнаяЧасть Тогда
Если ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_KeyField") Тогда
ПредставлениеПоля = "НомерСтроки";
ИначеЕсли Найти(СтрокаПоля.ИмяПоляХранения, "IDRRef") > 0 Тогда
ПредставлениеПоля = "Ссылка";
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(ПредставлениеПоля) Тогда
Если ЛиИменаБД Тогда
НИмяПоляХранения = НРег(СтрокаПоля.ИмяПоляХранения);
НМаркерПоляТипаЗначения = НРег("TYPE");
НМаркерПоляТипаСсылки = НРег("TRef");
//МаркерПоляЗначенияСсылки = НРег("RRef");
Если Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляТипаСсылки)) = НМаркерПоляТипаСсылки Тогда
ПредставлениеПоля = ПредставлениеПоля + "_ТипСсылки";
ИначеЕсли Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляТипаЗначения)) = НМаркерПоляТипаЗначения Тогда
ПредставлениеПоля = ПредставлениеПоля + "_ТипЗначения";
//ИначеЕсли Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляЗначенияСсылки)) = НМаркерПоляЗначенияСсылки Тогда
// ПредставлениеПоля = ПредставлениеПоля + "_Ссылка";
КонецЕсли;
КонецЕсли;
ИначеЕсли ИспользоватьИмяПоляВместоПустогоПредставления Тогда
ПредставлениеПоля = СтрокаПоля.ИмяПоляХранения;
КонецЕсли;
Возврат ПредставлениеПоля;
КонецФункции
Функция ПолучитьПредставлениеСтруктурыЛкс(Структура) Экспорт
#Если Сервер И Не Сервер Тогда
Структура = Новый Структура;
#КонецЕсли
ПредставлениеСтруктуры = "";
Для Каждого КлючИЗначение Из Структура Цикл
Если ПредставлениеСтруктуры <> "" Тогда
ПредставлениеСтруктуры = ПредставлениеСтруктуры + ", ";
КонецЕсли;
ПредставлениеСтруктуры = ПредставлениеСтруктуры + КлючИЗначение.Ключ + " = " + КлючИЗначение.Значение;
КонецЦикла;
Возврат ПредставлениеСтруктуры;
КонецФункции
Функция ПолучитьПредставлениеИндексаХраненияЛкс(СтрокаИндексаСтруктурыБД, ЛиСтруктураДанныхВИменахБД = Ложь, СтрокаТаблицыХранения, ЛиПредставлениеВИменахБД = Ложь) Экспорт
ЭтоТабличнаяЧасть = СтрокаТаблицыХранения.Назначение = "ТабличнаяЧасть";
ПредставлениеИндекса = "";
Разделитель = "";
Для каждого СтрокаПоля Из СтрокаИндексаСтруктурыБД.Поля Цикл
Если ЛиПредставлениеВИменахБД Тогда
ПредставлениеПоля = СтрокаПоля.ИмяПоляХранения;
Иначе
ПредставлениеПоля = ПолучитьПредставлениеПоляБДЛкс(СтрокаПоля, ЛиСтруктураДанныхВИменахБД, ЭтоТабличнаяЧасть, Истина);
КонецЕсли;
ПредставлениеИндекса = ПредставлениеИндекса + Разделитель + ПредставлениеПоля;
Разделитель = ", ";
КонецЦикла;
Возврат ПредставлениеИндекса;
КонецФункции
Процедура ОбработатьВыборкуСтруктурыХраненияБДЛкс(Знач Результат, ЛиИменаБД = Ложь, ВычислитьИменаИндексов = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
Результат = Новый ТаблицаЗначений;
#КонецЕсли
//Результат.Колонки.ИмяТаблицыХранения.Имя = "ИмяТаблицыХраненияСРегистромБукв";
Результат.Колонки.Добавить("КраткоеИмяТаблицыХранения", Новый ОписаниеТипов("Строка"));
//Результат.Колонки.Добавить("ИмяТаблицыХранения", Новый ОписаниеТипов("Строка"));
Для Каждого СтрокаТаблицыХранения Из Результат Цикл
// Антибаг платформы 8.2.16 У ряда назначений таблиц ИмяТаблицы пустое http://partners.v8.1c.ru/forum/thread.jsp?id=1090307#1090307
Если ПустаяСтрока(СтрокаТаблицыХранения.ИмяТаблицы) Тогда
МетаПолноеИмяТаблицы = "";
Если ЗначениеЗаполнено(СтрокаТаблицыХранения.Метаданные) Тогда
МетаПолноеИмяТаблицы = СтрокаТаблицыХранения.Метаданные + ".";
КонецЕсли;
Если СтрокаТаблицыХранения.Назначение = "РегистрацияИзменений" Тогда
СтрокаТаблицыХранения.ИмяТаблицы = МетаПолноеИмяТаблицы + "Изменения";
Иначе
СтрокаТаблицыХранения.ИмяТаблицы = МетаПолноеИмяТаблицы + СтрокаТаблицыХранения.Назначение;
КонецЕсли;
КонецЕсли;
//СтрокаТаблицыХранения.ИмяТаблицыХранения = НРег(ирОбщий.ПолучитьПоследнийФрагментЛкс(СтрокаТаблицыХранения.ИмяТаблицыХраненияСРегистромБукв));
// В режим ЛиИменаБД=Ложь Document209.VT2672->VT2672
СтрокаТаблицыХранения.КраткоеИмяТаблицыХранения = НРег(ирОбщий.ПолучитьПоследнийФрагментЛкс(СтрокаТаблицыХранения.ИмяТаблицыХранения));
Если ВычислитьИменаИндексов Тогда
СтрокаТаблицыХранения.Индексы.Колонки.Добавить("ИмяИндекса", Новый ОписаниеТипов("Строка"));
Для Каждого СтрокаИндексаХранения Из СтрокаТаблицыХранения.Индексы Цикл
ПредставлениеИндекса = ирОбщий.ПолучитьПредставлениеИндексаХраненияЛкс(СтрокаИндексаХранения, ЛиИменаБД, СтрокаТаблицыХранения);
СтрокаИндексаХранения.ИмяИндекса = "Индекс(" + ПредставлениеИндекса + ")";
КонецЦикла;
КонецЕсли;
КонецЦикла;
Результат.Индексы.Добавить("КраткоеИмяТаблицыХранения");
КонецПроцедуры
Функция ПолучитьСтруктуруХраненияБДЛкс(Знач ОтборПоМетаданным = Неопределено, ЛиИменаБД = Ложь, ВычислитьИменаИндексов = Истина, АдресЧужойСхемыБД = "") Экспорт
Если ОтборПоМетаданным = Неопределено Тогда
#Если Клиент Тогда
Состояние("Получение структуры БД");
#КонецЕсли
ИначеЕсли ТипЗнч(ОтборПоМетаданным) <> Тип("Массив") Тогда
Массив = Новый Массив;
Массив.Добавить(ОтборПоМетаданным);
ОтборПоМетаданным = Массив;
КонецЕсли;
Если ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда
СтруктураСхемы = ПолучитьЧужуюСхемуБДЛкс(АдресЧужойСхемыБД);
Если ЛиИменаБД Тогда
ГлавнаяТаблица = СтруктураСхемы.СУБД;
Иначе
ГлавнаяТаблица = СтруктураСхемы.SDBL;
КонецЕсли;
Если ОтборПоМетаданным <> Неопределено Тогда
Результат = ГлавнаяТаблица.СкопироватьКолонки();
Если ГлавнаяТаблица.Индексы.Количество() = 0 Тогда
ГлавнаяТаблица.Индексы.Добавить("Метаданные");
КонецЕсли;
Для Каждого ИмяМД Из ОтборПоМетаданным Цикл
Для Каждого СтрокаТаблицы Из ГлавнаяТаблица.НайтиСтроки("Метаданные", ИмяМД) Цикл
ЗаполнитьЗначенияСвойств(Результат.Добавить(), СтрокаТаблицы);
КонецЦикла;
КонецЦикла;
Иначе
Результат = ГлавнаяТаблица;
КонецЕсли;
Иначе
Результат = ПолучитьСтруктуруХраненияБазыДанных(ОтборПоМетаданным, ЛиИменаБД);
КонецЕсли;
ОбработатьВыборкуСтруктурыХраненияБДЛкс(Результат, ЛиИменаБД, ВычислитьИменаИндексов);
Если ОтборПоМетаданным = Неопределено Тогда
#Если Клиент Тогда
Состояние("");
#КонецЕсли
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьЧужуюСхемуБДЛкс(АдресЧужойСхемыБД) Экспорт
Если Не ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда
Возврат Неопределено;
Иначе
Результат = ПолучитьИзВременногоХранилища(АдресЧужойСхемыБД);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОбновитьПовторноИспользуемыеЗначенияЛкс() Экспорт
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ирПортативный.ОбновитьПовторноИспользуемыеЗначенияЛкс();
Иначе
ОбновитьПовторноИспользуемыеЗначения();
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСовместимоеЗначениеПараметраЛкс(Знач ЗначениеПараметра, ИмяПараметра, ОписаниеТиповЭлементаУправленияПараметра = Неопределено) Экспорт
Результат = ЗначениеПараметра;
ТипЗначенияПараметра = ТипЗнч(Результат);
Если Истина
И ТипЗначенияПараметра = Тип("Массив")
И ОписаниеТиповЭлементаУправленияПараметра <> Неопределено
Тогда
СписокЗначений = Новый СписокЗначений;
ПреобразованиеУспешно = Истина;
Для Каждого ЭлементМассива Из ЗначениеПараметра Цикл
Если ОписаниеТиповЭлементаУправленияПараметра.СодержитТип(ТипЗнч(ЭлементМассива)) Тогда
СписокЗначений.Добавить(ЭлементМассива);
Иначе
ПреобразованиеУспешно = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПреобразованиеУспешно Тогда
Результат = СписокЗначений;
Сообщить("Значение параметра """ + ИмяПараметра + """ было преобразовано из массива в список значений", СтатусСообщения.Внимание);
КонецЕсли;
Иначе
МетаданныеТипаЗначения = Метаданные.НайтиПоТипу(ТипЗначенияПараметра);
Если МетаданныеТипаЗначения <> Неопределено Тогда
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(МетаданныеТипаЗначения.ПолноеИмя());
Если ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
Результат = ЗначениеПараметра.Выгрузить();
Сообщить("Значение параметра """ + ИмяПараметра + """ было преобразовано из табличной части в таблицу значений", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
Если ОписаниеТиповЭлементаУправленияПараметра <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ОписаниеТиповЭлементаУправленияПараметра = Новый ОписаниеТипов;
#КонецЕсли
Результат = ОписаниеТиповЭлементаУправленияПараметра.ПривестиЗначение(ЗначениеПараметра);
Если Результат <> ЗначениеПараметра Тогда
Сообщить("Значение параметра """ + ИмяПараметра + """ было преобразовано """ + ЗначениеПараметра + """->""" + Результат + """", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПолучитьСхемуИНастройкиКомпоновкиДинамическогоСпискаЛкс(Знач ДинамическийСписок, выхНастройкаКомпоновки, выхСхема) Экспорт
ТекстЗапроса = ДинамическийСписок.ТекстЗапроса;
Если Не ЗначениеЗаполнено(ТекстЗапроса) Тогда
ТекстЗапроса = "ВЫБРАТЬ * ИЗ " + ДинамическийСписок.ОсновнаяТаблица;
КонецЕсли;
Запрос = Новый Запрос(ТекстЗапроса);
выхНастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
ТекущаяГруппировка = выхНастройкаКомпоновки;
Для Каждого ПолеГруппировки Из ДинамическийСписок.Группировка.Элементы Цикл
Если ПолеГруппировки.Использование Тогда
ТекущаяГруппировка = НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура, ПолеГруппировки.Поле);
КонецЕсли;
КонецЦикла;
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура);
Для Каждого ДоступноеПоле Из ДинамическийСписок.УсловноеОформление.ДоступныеПоляПолей.Элементы Цикл
Если ДоступноеПоле.Папка Тогда
Продолжить;
КонецЕсли;
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(выхНастройкаКомпоновки.Выбор, ДоступноеПоле.Поле);
КонецЦикла;
Настройка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.Filter = СериализаторXDTO.ЗаписатьXDTO(Отбор);
КонецЕсли;
Если КопироватьПараметры Тогда
НастройкаXDTO.DataParameters = СериализаторXDTO.ЗаписатьXDTO(Параметры);
КонецЕсли;
Если КопироватьПорядок Тогда
НастройкаXDTO.Order = СериализаторXDTO.ЗаписатьXDTO(УсловноеОформление);
КонецЕсли;
Если КопироватьУсловноеОформление Тогда
НастройкаXDTO.ConditionalAppearance = СериализаторXDTO.ЗаписатьXDTO(УсловноеОформление);
КонецЕсли;
НастройкаКомпоновкиПриемник = СериализаторXDTO.ПрочитатьXDTO(НастройкаXDTO);
Возврат НастройкаКомпоновкиПриемник;
КонецФункции // СкопироватьОтборКомпоновкиЛкс()
Функция ПолучитьРасширениеФайловДляОтладкиЛкс() Экспорт
Результат = "deb";
Возврат Результат;
КонецФункции
Функция ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки = Неопределено, Наименование = "")
Если Не ЗначениеЗаполнено(Наименование) Тогда
Наименование = "" + ТекущаяДата() + " " + СтруктураПараметров.ТипОперации + " " + СтруктураПараметров.Объект;
КонецЕсли;
Если Истина
И Не ирКэш.ЛиПортативныйРежимЛкс()
И Не ирКэш.ЛиЭтоРасширениеКонфигурацииЛкс()
И Не (Истина
И ТранзакцияАктивна()
И ирКэш.ЭтоФайловаяБазаЛкс())
Тогда
ХранимоеЗначение = СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров);
ОбъектДляОтладки = Справочники.ирОбъектыДляОтладки.СоздатьЭлемент();
ОбъектДляОтладки.Наименование = Наименование;
ОбъектДляОтладки.XML = ХранимоеЗначение;
выхОбъектДляОтладки = ЗаписатьОбъектДляОтладкиЛкс(ОбъектДляОтладки);
Результат = "Данные помещены в справочник ""Объекты для отладки"". Скопируйте эту строку и используйте команду ""Отладить отложенный объект""."
+ " Объект """ + ОбъектДляОтладки + """(" + выхОбъектДляОтладки.УникальныйИдентификатор() + ")";
Иначе
//выхОбъектДляОтладки = ПоместитьВоВременноеХранилище(ХранимоеЗначение, Новый УникальныйИдентификатор);
//Результат = "Данные помещены в хранилище ДО КОНЦА СЕАНСА. Скопируйте эту строку и используйте команду ""Отладить отложенный объект""."
//+ " Адрес """ + выхОбъектДляОтладки + """";
РасширениеФайловДляОтладки = ПолучитьРасширениеФайловДляОтладкиЛкс();
Платформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
Платформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Наименование = Платформа.ПолучитьИдентификаторИзПредставления(Наименование);
КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс();
Если Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
Результат = "В общих настройках инструментов не задан каталог объектов для отладки! Сохранение объекта для отладки не выполнено.";
Возврат Результат;
КонецЕсли;
ИмяФайла = КаталогОбъектовДляОтладки + Наименование + "." + РасширениеФайловДляОтладки;
ФайлОбъектаДляОтладки = Новый Файл(ИмяФайла);
СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров, , ФайлОбъектаДляОтладки.ПолноеИмя);
выхОбъектДляОтладки = ФайлОбъектаДляОтладки.ПолноеИмя;
Результат = "Данные помещены в файл. Скопируйте эту строку и используйте команду ""Отладить отложенный объект""."
+ " Файл """ + выхОбъектДляОтладки + """";
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьКаталогОбъектовДляОтладкиЛкс() Экспорт
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
КаталогОбъектовДляОтладки = ирПортативный.ПолучитьКаталогОбъектовДляОтладкиЛкс();
Иначе
//ИмяФайла = ПолучитьИмяВременногоФайла(РасширениеФайловДляОтладки);
КаталогОбъектовДляОтладки = ХранилищеОбщихНастроек.Загрузить("ИнструментыРазработчикаTormozit", "КаталогОбъектовДляОтладки");
КонецЕсли;
Возврат КаталогОбъектовДляОтладки;
КонецФункции
Функция ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(Параметры) Экспорт
// Антибаг платформы 8.2.18. Некорректная серилизация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СтруктураЗапроса.Параметры = ПолучитьКопиюОбъектаЛкс(Объект.Параметры);
Структура = Новый Структура();
Для Каждого КлючИЗначение Из Параметры Цикл
ЗначениеПараметра = ПолучитьСовместимоеЗначениеПараметраЛкс(КлючИЗначение.Значение, КлючИЗначение.Ключ);
Структура.Вставить(КлючИЗначение.Ключ, ЗначениеВСтрокуВнутр(ЗначениеПараметра));
КонецЦикла;
Возврат Структура;
КонецФункции
Функция СкопироватьЗапросЛкс(ЗапросИсточник, ЗапросПриемник = Неопределено) Экспорт
Если ЗапросПриемник = Неопределено Тогда
ЗапросПриемник = Новый Запрос;
КонецЕсли;
ЗапросПриемник.Текст = ЗапросИсточник.Текст;
ирОбщий.СкопироватьУниверсальнуюКоллекциюЛкс(ЗапросИсточник.Параметры, ЗапросПриемник.Параметры);
Возврат ЗапросПриемник;
КонецФункции // СкопироватьЗапросЛкс()
Функция ПолучитьТекстЗапросаВсехТиповСсылокЛкс(ИмяВременнойТаблицы = "ВсеТипыСсылок", Знач ОписаниеТипов = Неопределено) Экспорт
Если ОписаниеТипов = Неопределено Тогда
ОписаниеТипов = ПолучитьОписаниеТиповВсеСсылкиЛкс();
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОписаниеВсехТипов = Новый ОписаниеТипов;
#КонецЕсли
ТекстТаблицыТипов = "";
Для Каждого Тип Из ОписаниеТипов.Типы() Цикл
ПолноеИмя = Метаданные.НайтиПоТипу(Тип).ПолноеИмя();
НоваяСтрока = "ВЫБРАТЬ ТИП(" + ПолноеИмя + ") КАК Тип, """ + ПолноеИмя + """ КАК Имя" + Символы.ПС;
Если ТекстТаблицыТипов <> "" Тогда
ТекстТаблицыТипов = ТекстТаблицыТипов + "ОБЪЕДИНИТЬ ВСЕ " + Символы.ПС;
Иначе
Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
НоваяСтрока = НоваяСтрока + "ПОМЕСТИТЬ " + ИмяВременнойТаблицы + Символы.ПС;
КонецЕсли;
КонецЕсли;
ТекстТаблицыТипов = ТекстТаблицыТипов + НоваяСтрока;
КонецЦикла;
//ТекстТаблицыТипов = ТекстТаблицыТипов + " ИНДЕКСИРОВАТЬ ПО Тип"; // По такому типу поля нельзя индексировать
Возврат ТекстТаблицыТипов;
КонецФункции
Функция ПолучитьТекстЗапросаДатВДиапазонеЛкс(ИмяВременнойТаблицы = "ДатыДиапазона") Экспорт
Текст = "ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, aa.a * 1000 + bb.b * 100 + cc.c * 10 + dd.d) КАК Период
|";
Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
Текст = Текст + "ПОМЕСТИТЬ " + ИмяВременнойТаблицы + Символы.ПС;
КонецЕсли;
Текст = Текст +
"ИЗ
| (ВЫБРАТЬ 0 КАК a
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 1
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 2
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 3
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 4
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 5
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 6
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 7
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 8
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 9) КАК aa
| ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ 0 КАК b
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 1
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 2
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 3
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 4
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 5
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 6
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 7
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 8
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 9) КАК bb
| ПО (ИСТИНА)
| ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ 0 КАК c
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 1
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 2
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 3
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 4
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 5
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 6
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 7
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 8
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 9) КАК cc
| ПО (ИСТИНА)
| ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| 0 КАК d
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 1
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 2
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 3
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 4
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 5
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 6
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 7
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 8
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 9) КАК dd
| ПО (ИСТИНА)
|ГДЕ
| aa.a * 1000 + bb.b * 100 + cc.c * 10 + dd.d <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ)";
Возврат Текст;
КонецФункции
Функция ПолучитьСобственноеВнешнееСоединениеЛкс(ИнициализироватьИнтерфейсИР = Ложь, выхИнтерфейсИР = Неопределено) Экспорт
ИмяПользователяВнешнегоСоединения = "";
ПарольПользователяВнешнегоСоединения = "";
Если ПользователиИнформационнойБазы.ПолучитьПользователей().Количество() > 0 Тогда
ИмяПользователяВнешнегоСоединения = ИмяПользователя() + "_ВнешнееСоединение";
Попытка
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователяВнешнегоСоединения);
Исключение
Сообщить("Не удалось выполнить поиск служебного пользователя: " + ОписаниеОшибки());
// Разделенная база в неразделенном сеансе
Возврат Неопределено;
КонецПопытки;
Если ПользовательИБ = Неопределено Тогда
ПользовательИБ = ПользователиИнформационнойБазы.СоздатьПользователя();
ПользовательИБ.Имя = ИмяПользователяВнешнегоСоединения;
ПользовательИБ.ПолноеИмя = ИмяПользователяВнешнегоСоединения;
Сообщить("Создан служебный пользователь ИБ с именем """ + ИмяПользователяВнешнегоСоединения + """");
КонецЕсли;
ТекущийПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
ЗаполнитьЗначенияСвойств(ПользовательИБ, ТекущийПользовательИБ,, "Имя, ПолноеИмя");
ПользовательИБ.Роли.Очистить();
Для Каждого Роль Из ТекущийПользовательИБ.Роли Цикл
ПользовательИБ.Роли.Добавить(Роль);
КонецЦикла;
ПарольПользователяВнешнегоСоединения = "" + Новый УникальныйИдентификатор;
ПользовательИБ.ПоказыватьВСпискеВыбора = Ложь;
ПользовательИБ.АутентификацияОС = Ложь;
ПользовательИБ.АутентификацияСтандартная = Истина;
ПользовательИБ.Пароль = ПарольПользователяВнешнегоСоединения;
ПользовательИБ.Записать();
КонецЕсли;
Результат = ЗапуститьСеансПодПользователемЛкс(ИмяПользователяВнешнегоСоединения, ПарольПользователяВнешнегоСоединения, "ComConnector");
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
выхИнтерфейсИР = Результат.ВнешниеОбработки.Создать(ирПортативный.ИспользуемоеИмяФайла, Ложь);
Иначе
выхИнтерфейсИР = Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ТабличныйДокумент - ТабличныйДокумент
// ДанныеРасшифровки - ДанныеРасшифровкиКомпоновкиДанных
// Поля - Строка(0,П), Массив - Если строка, то через запятую перечисленные имена полей.
// Область - ВыделенныеОбластиТабличногоДокумента, Массив, ОбластьЯчеекТабличногоДокумента - Если не указано, используются выделенные области
//
Функция ПолучитьТаблицуКлючейИзТабличногоДокументаЛкс(Знач ТабличныйДокумент, Знач ДанныеРасшифровки = Неопределено, Знач Поля = "", Знач Область = Неопределено) Экспорт
Перем ЭтотОбъект, Результат;
//НАЧАЛО.СЕРВИС
Если Истина
И ТипЗнч(Поля) = Тип("Строка")
И Не ПустаяСтрока(Поля)
Тогда
МассивИменПолей = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(Поля, ",", Истина);
ИначеЕсли ТипЗнч(Поля) = Тип("Массив") Тогда
МассивИменПолей = Поля;
Иначе
МассивИменПолей = Новый Массив;
КонецЕсли;
ТаблицаРезультата = Неопределено;
МассивСсылок = Новый Массив;
АвтоПоля = МассивИменПолей.Количество() = 0;
Если ТипЗнч(Область) = Тип("Неопределено") Тогда
КоллекцияОбластей = ТабличныйДокумент.ВыделенныеОбласти;
ИначеЕсли ТипЗнч(Область) = Тип("Массив") Тогда
КоллекцияОбластей = Область;
ИначеЕсли ТипЗнч(Область) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда
КоллекцияОбластей = Новый Массив;
КоллекцияОбластей.Добавить(Область);
КонецЕсли;
Если ДанныеРасшифровки <> Неопределено Тогда
ЭлементыРасшифровки = ДанныеРасшифровки.Элементы;
КонецЕсли;
НачальноеКоличество = КоллекцияОбластей.Количество();
Для СчетчикВыделенныеОбласти = 1 По НачальноеКоличество Цикл
Область = КоллекцияОбластей[НачальноеКоличество - СчетчикВыделенныеОбласти];
Если Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Колонки Тогда
Лево = Область.Лево;
Право = Область.Право;
Верх = 1;
Низ = ТабличныйДокумент.ВысотаТаблицы;
ИначеЕсли Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Строки Тогда
Лево = 1;
Право = ТабличныйДокумент.ШиринаТаблицы;
Верх = Область.Верх;
Низ = Область.Низ;
ИначеЕсли Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Прямоугольник Тогда
Лево = Область.Лево;
Право = Область.Право;
Верх = Область.Верх;
Низ = Область.Низ;
Иначе
Продолжить;
КонецЕсли;
Для НомерСтроки = Верх по Низ Цикл
КлючПолучен = Ложь;
СтруктураПолей = Новый Структура;
Для НомерКолонки = Лево по Право Цикл
ОбластьЯчейки = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
Если ОбластьЯчейки.Лево <> НомерКолонки Или ОбластьЯчейки.Верх <> НомерСтроки Тогда
// Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой
Продолжить;
КонецЕсли;
Расшифровка = ОбластьЯчейки.Расшифровка;
Если ТипЗнч(Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
Если ЭлементыРасшифровки = Неопределено Тогда
ВызватьИсключение "В табличном документа найден идентификатор расшифровки, но не переданы данные расшифровки";
КонецЕсли;
ЭлементРасшифровкиПоля = ЭлементыРасшифровки[Расшифровка];
Если НомерСтроки = Верх Тогда
Если ТаблицаРезультата = Неопределено Тогда
ТаблицаРезультата = Новый ТаблицаЗначений;
Для Каждого ИмяПоля Из МассивИменПолей Цикл
ТаблицаРезультата.Колонки.Добавить(ИмяПоля);
КонецЦикла;
КонецЕсли;
Если АвтоПоля Тогда
ИмяПоля = ЭлементРасшифровкиПоля.ПолучитьПоля()[0].Поле;
МассивИменПолей.Добавить(ИмяПоля);
ИмяКолонки = СтрЗаменить(ИмяПоля, ".", "");
Если ТаблицаРезультата.Колонки.Найти(ИмяКолонки) = Неопределено Тогда
ТаблицаРезультата.Колонки.Добавить(ИмяКолонки);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КлючПолучен = ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(ЭлементРасшифровкиПоля, МассивИменПолей, СтруктураПолей);
Если Истина
И КлючПолучен
И (Ложь
Или НомерКолонки = Право
Или Не АвтоПоля)
Тогда
Прервать;
КонецЕсли;
ИначеЕсли ирОбщий.ЛиСсылкаНаОбъектБДЛкс(Расшифровка, Ложь) Тогда
ИмяКолонки = "Ссылка";
СтруктураПолей = Новый Структура(ИмяКолонки, Расшифровка);
КлючПолучен = Истина;
Если ТаблицаРезультата = Неопределено Тогда
ТаблицаРезультата = Новый ТаблицаЗначений;
КонецЕсли;
Если ТаблицаРезультата.Колонки.Найти(ИмяКолонки) = Неопределено Тогда
ТаблицаРезультата.Колонки.Добавить(ИмяКолонки);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если КлючПолучен Тогда
Если ТаблицаРезультата.НайтиСтроки(СтруктураПолей).Количество() = 0 Тогда
ЗаполнитьЗначенияСвойств(ТаблицаРезультата.Добавить(), СтруктураПолей);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если ТаблицаРезультата = Неопределено Тогда
ТаблицаРезультата = Новый ТаблицаЗначений;
КонецЕсли;
Результат = ТаблицаРезультата;
Возврат Результат;
КонецФункции
// Извлекаемые значения помещаются в структуру
// Параметры:
// ЭлементРасшифровкиПоля - ЭлементРасшифровкиКомпоновкиДанныхГруппировка, ЭлементРасшифровкиКомпоновкиДанныхПоля
// Поля - Строка(0,П), Массив
// СтруктураПолей - Структура
//
Функция ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(Знач ЭлементРасшифровкиПоля, Знач Поля = "", Знач СтруктураПолей = Неопределено) Экспорт
Если СтруктураПолей = Неопределено Тогда
СтруктураПолей = Новый Структура;
КонецЕсли;
Если Истина
И ТипЗнч(Поля) = Тип("Строка")
И Не ПустаяСтрока(Поля)
Тогда
МассивИменПолей = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(Поля, ",", Истина);
ИначеЕсли ТипЗнч(Поля) = Тип("Массив") Тогда
МассивИменПолей = Поля;
Иначе
МассивИменПолей = Новый Массив;
КонецЕсли;
Результат = Ложь;
Если ТипЗнч(ЭлементРасшифровкиПоля) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
ТекущиеЗначенияПолей = ЭлементРасшифровкиПоля.ПолучитьПоля();
Если ТекущиеЗначенияПолей.Количество() > 0 Тогда
//ЗначениеПоля = ТекущиеЗначенияПолей[0];
Для Каждого ИмяПоля Из МассивИменПолей Цикл
ЗначениеПоля = ТекущиеЗначенияПолей.Найти(ИмяПоля);
ИмяСвойства = СтрЗаменить(ИмяПоля, ".", "");
Если Истина
И ЗначениеПоля <> Неопределено
И Не СтруктураПолей.Свойство(ИмяСвойства)
Тогда
СтруктураПолей.Вставить(ИмяСвойства, ЗначениеПоля.Значение);
Если СтруктураПолей.Количество() = МассивИменПолей.Количество() Тогда
Результат = Истина;
Прервать
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если Не Результат Тогда
РодительскиеЭлементыРасшифровки = ЭлементРасшифровкиПоля.ПолучитьРодителей();
Для Каждого РодительскийЭлементРасшифровки Из РодительскиеЭлементыРасшифровки Цикл
Результат = ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(РодительскийЭлементРасшифровки, МассивИменПолей, СтруктураПолей);
Если Результат Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьСоединениеСУБД(ИмяСервера = "", ИмяБД = "", ИмяПользователя = "", Пароль = "") Экспорт
#Если Клиент Тогда
Если Не ЗначениеЗаполнено(ИмяСервера) Тогда
ФормаПодключения = ОткрытьФормуСоединенияСУБДЛкс(Истина);
Возврат ФормаПодключения.Соединение;
КонецЕсли;
#КонецЕсли
КонсольЗапросов = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
ИсточникДанных = КонсольЗапросов.ПолучитьСтруктуруИсточникаДанныхADO();
ИсточникДанных.Платформа = 11; // ADO-SQLOLEDB
ИсточникДанных.БазаСервер = ИмяСервера;
ИсточникДанных.БазаИмя = ИмяБД;
ИсточникДанных.АутентификацияОС = Не ЗначениеЗаполнено(ИмяПользователя);
ИсточникДанных.Пользователь = ИмяПользователя;
ИсточникДанных.Пароль = Пароль;
СоединениеADO = Неопределено;
ОшибкиПодключения = Неопределено;
Если Не КонсольЗапросов.ConnectADO(ИсточникДанных, СоединениеADO,, ОшибкиПодключения) Тогда
СообщениеОбОшибке = "Ошибки подключения к серверу MSSQL:";
Для каждого ОшибкаПодключения Из ОшибкиПодключения Цикл
СообщениеОбОшибке = СообщениеОбОшибке + Символы.ПС + ОшибкаПодключения;
КонецЦикла;
Сообщить(СообщениеОбОшибке);
СоединениеADO = Неопределено;
КонецЕсли;
Возврат СоединениеADO;
КонецФункции
Функция ОткрытьЗапросСУБДЛкс(ТекстЗапроса, ИмяЗапроса = "Запрос для отладки", Параметры = Неопределено, Автоподключение = Ложь) Экспорт
КонсольЗапросов = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
КонсольЗапросов.ОткрытьЗапросБД(ТекстЗапроса, ИмяЗапроса, Параметры, Автоподключение);
КонецФункции
Функция HTTPСоединение(ИмяСервера) Экспорт
Попытка
Результат = Новый HTTPСоединение(ИмяСервера);
Исключение
// Антибаг платформы https://bugboard.v8.1c.ru/error/000013833.html
Результат = Новый HTTPСоединение(ИмяСервера,,,, Новый ИнтернетПрокси(Ложь));
КонецПопытки;
Возврат Результат;
КонецФункции
Процедура ОбновитьМодульВнешнейОбработкиДляОтладкиЛкс(ИмяФайлаВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля, ТекстМодуляТекущейВнешнейОбработки, ДатаИзмененияВнешнейОбработки, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
ирСервер.ОбновитьМодульВнешнейОбработкиДляОтладкиЛкс(ИмяФайлаВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля, ТекстМодуляТекущейВнешнейОбработки, ДатаИзмененияВнешнейОбработки);
Иначе
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс();
ИмяФайлаВнешнейОбработки = КаталогОбъектовДляОтладки + "\" + ИмяВнешнейОбработки + ".epf";
Если Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
Сообщить("В общих настройках инструментов не задан каталог объектов для отладки! Сохранение внешней обработки не выполнено.", СтатусСообщения.Внимание);
Возврат;
КонецЕсли;
ФайлВнешнейОбработки = Новый Файл(ИмяФайлаВнешнейОбработки);
Если Ложь
Или (Истина
И ФайлВнешнейОбработки.Существует()
И ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс() > ДатаИзмененияВнешнейОбработки
И мПлатформа.ФайловыйКэшАлгоритмовДопускаетРедактирование)
Или (Истина
И ФайлВнешнейОбработки.Существует()
И ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс() = ДатаИзмененияВнешнейОбработки
И ТекстМодуляТекущейВнешнейОбработки = ТекстМодуля)
Тогда
Возврат;
КонецЕсли;
мПлатформа.СформироватьВнешнююОбработку(ИмяВнешнейОбработки, ФайлВнешнейОбработки, ТекстМодуля);
ДатаИзмененияВнешнейОбработки = ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс();
КонецЕсли;
КонецПроцедуры
Процедура ЗаписатьДокументDOMВФайлЛкс(Знач ДокументДом, Знач ИмяФайла) Экспорт
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяФайла);
ЗаписьДом = Новый ЗаписьDOM;
ЗаписьДом.Записать(ДокументДом, ЗаписьXML);
ЗаписьXML.Закрыть();
КонецПроцедуры
Функция ПрочитатьФайлВДокументDOMЛкс(Знач ИмяФайла) Экспорт
ЧтениеXML = Новый ЧтениеXML;
ПараметрыЧтения = Новый ПараметрыЧтенияXML(,,,,,,,, Ложь);
ЧтениеXML.ОткрытьФайл(ИмяФайла, ПараметрыЧтения);
ПостроительДом = Новый ПостроительDOM();
ДокументДОМ = ПостроительДом.Прочитать(ЧтениеXML);
ЧтениеXML.Закрыть();
Возврат ДокументДОМ;
КонецФункции
Функция АдаптироватьРасширениеЛкс(ТолькоПриНаличииПодключенныхКоманд = Ложь) Экспорт
#Если ТонкийКлиент Или ВебКлиент Тогда
Результат = ирСервер.АдаптироватьРасширениеЛкс();
Возврат Результат;
#КонецЕсли
ПометкиКоманд = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.ПометкиКоманд",, "ИнструментыРазработчикаTormozit");
Если ТолькоПриНаличииПодключенныхКоманд Тогда
ЕстьПодключенныеКоманды = Ложь;
Если ПометкиКоманд <> Неопределено Тогда
Для Каждого КлючИЗначение Из ПометкиКоманд Цикл
Если КлючИЗначение.Значение = Истина Тогда
ЕстьПодключенныеКоманды = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Не ЕстьПодключенныеКоманды Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
ЭтотРасширение = ирКэш.ЭтотРасширениеКонфигурацииЛкс();
#Если Сервер И Не Сервер Тогда
ЭтотРасширение = РасширенияКонфигурации.Создать();
#КонецЕсли
ИмяРасширения = ЭтотРасширение.Имя;
ТипВсеСсылки = ирОбщий.ПолучитьОписаниеТиповВсеСсылкиЛкс();
ТипВсеПланыОбмена = ПланыОбмена.ТипВсеСсылки();
ТекстовыйДокумент = Новый ТекстовыйДокумент;
КаталогВыгрузкиРасширения = ПолучитьИмяВременногоФайла();
ИмяФайлаСпискаВыгрузкиРасширения = ПолучитьИмяВременногоФайла("txt");
// Сначала выгружаем из конфигурации все ссылочные метаданные
//ТекстСпискаОбъектовКонфигурации = Метаданные.ПолноеИмя();
ТекстСпискаОбъектовКонфигурации = "";
СписокДобавляемыхТипов = Новый Массив;
Для Каждого Тип Из ТипВсеСсылки.Типы() Цикл
ОбъектМД = Метаданные.НайтиПоТипу(Тип);
ТекстСпискаОбъектовКонфигурации = ТекстСпискаОбъектовКонфигурации + Символы.ПС + ОбъектМД.ПолноеИмя();
КонецЦикла;
ТекстСпискаОбъектовКонфигурации = Сред(ТекстСпискаОбъектовКонфигурации, 2); // !
ИмяФайлаСпискаВыгрузкиКонфигурации = ПолучитьИмяВременногоФайла("txt");
ТекстовыйДокумент.УстановитьТекст(ТекстСпискаОбъектовКонфигурации);
ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиКонфигурации);
КаталогВыгрузкиКонфигурации = ПолучитьИмяВременногоФайла();
СоздатьКаталог(КаталогВыгрузкиКонфигурации);
ТекстЛога = "";
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиКонфигурации + """ -listFile """ + ИмяФайлаСпискаВыгрузкиКонфигурации + """ -Format Plain",
СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка конфигурации в файлы");
УдалитьФайлы(ИмяФайлаСпискаВыгрузкиРасширения);
Если Не Успех Тогда
УдалитьФайлы(КаталогВыгрузкиКонфигурации);
Сообщить(ТекстЛога);
Возврат Ложь;
КонецЕсли;
// Выгружаем объекты из расширения
ТекстЛога = "";
СоздатьКаталог(КаталогВыгрузкиРасширения);
ТекстСпискаОбъектовРасширения = "Конфигурация." + ИмяРасширения;
Для Каждого КлючИЗначение Из ПометкиКоманд Цикл
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + "ОбщаяКоманда." + КлючИЗначение.Ключ;
КонецЦикла;
ТекстовыйДокумент.УстановитьТекст(ТекстСпискаОбъектовРасширения);
ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиРасширения);
// Пришлось отказаться от частичной загрузки из-за непонятной ошибки
// Файл - Configuration.xml: ошибка частичной загрузки - идентификатор 15dc941a-fd9f-4d00-bc7e-3ef077518def загружаемой конфигурации отличается от идентификатора b9c0a797-9739-4c3f-a665-796b3bf92d6a сохраненной конфигурации
//Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -listFile """ + ИмяФайлаСпискаВыгрузкиРасширения + """ -Format Plain",
// СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка расширения в файлы");
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -Format Plain",
СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка расширения в файлы");
Если Не Успех Тогда
УдалитьФайлы(КаталогВыгрузкиРасширения);
Сообщить(ТекстЛога);
Возврат Ложь;
КонецЕсли;
// Добавим ссылочные объекты в расширение
ИмяФайла = КаталогВыгрузкиРасширения + "\Configuration.xml";
ОписаниеРасширения = Новый ТекстовыйДокумент;
ОписаниеРасширения.Прочитать(ИмяФайла);
ОписаниеРасширения = ОписаниеРасширения.ПолучитьТекст();
ДокументДОМ = ирОбщий.ПрочитатьФайлВДокументDOMЛкс(ИмяФайла);
//ЧтениеXML = Новый ЧтениеXML;
//ПараметрыЧтения = Новый ПараметрыЧтенияXML(,,,,,,,, Ложь);
//ЧтениеXML.ОткрытьФайл(ИмяФайла, ПараметрыЧтения);
//ПостроительДом = Новый ПостроительDOM();
//ДокументДОМ = ПостроительДом.Прочитать(ЧтениеXML);
//ЧтениеXML.Закрыть();
УзелТиповСпискаОбъектов = ДокументДом.ПолучитьЭлементыПоИмени("ChildObjects");
УзелТиповСпискаОбъектов = УзелТиповСпискаОбъектов[0];
СписокДобавляемыхТипов = Новый Массив;
Для Каждого Тип Из ТипВсеСсылки.Типы() Цикл
XMLИмяТипа = XMLТип(Тип).ИмяТипа;
Если Найти(XMLИмяТипа, "RoutePointRef.") > 0 Тогда
Продолжить;
КонецЕсли;
XMLТипМетаданного = ирОбщий.ПолучитьПервыйФрагментЛкс(XMLИмяТипа, "Ref.");
ОбъектМД = Метаданные.НайтиПоТипу(Тип);
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + ОбъектМД.ПолноеИмя();
Если Найти(ОписаниеРасширения, "<" + XMLТипМетаданного + ">" + ОбъектМД.Имя + "<") > 0 Тогда
Продолжить;
КонецЕсли;
СписокДобавляемыхТипов.Добавить(Тип);
УзелОбъекта = ДокументДом.СоздатьЭлемент(XMLТипМетаданного);
УзелОбъекта.ТекстовоеСодержимое = ОбъектМД.Имя;
УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта);
КонецЦикла;
ирОбщий.ЗаписатьДокументDOMВФайлЛкс(ДокументДом, ИмяФайла);
//ЗаписьXML = Новый ЗаписьXML;
//ЗаписьXML.ОткрытьФайл(ИмяФайла);
//ЗаписьДом = Новый ЗаписьDOM;
//ЗаписьДом.Записать(ДокументДом, ЗаписьXML);
//ЗаписьXML.Закрыть();
// Перенесем объекты метаданных из конфигурации в расширение
Для Каждого Тип Из СписокДобавляемыхТипов Цикл
XMLИмяТипа = XMLТип(Тип).ИмяТипа;
Если Найти(XMLИмяТипа, "RoutePointRef.") > 0 Тогда
Продолжить;
КонецЕсли;
ПолноеИмяМДXML = СтрЗаменить(XMLИмяТипа, "Ref.", ".");
ИмяКлассаМДXML = ПолучитьПервыйФрагментЛкс(ПолноеИмяМДXML);
ФайлИсточник = Новый Файл(КаталогВыгрузкиКонфигурации + "\" + ПолноеИмяМДXML + ".xml");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ФайлИсточник.Имя);
//ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя);
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
ЧтоЗаменять = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ТекстФайла, "", "" + ИмяКлассаМДXML + ">",, Истина);
НаЧтоЗаменять =
"
| " + ирОбщий.ПолучитьПоследнийФрагментЛкс(ФайлИсточник.ИмяБезРасширения) + "
| Adopted
|
|
| " + ИмяКлассаМДXML + ">";
ТекстФайла = СтрЗаменить(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ЧтоЗаменять = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМДXML + " uuid=", ">",, Истина);
НаЧтоЗаменять = "<" + ИмяКлассаМДXML + " uuid=""" + Новый УникальныйИдентификатор + """>";
ТекстФайла = СтрЗаменить(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ТекстовыйДокумент.УстановитьТекст(ТекстФайла);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
КонецЦикла;
// Добавим типы ссылочных объектов в общие команды
#Если Сервер И Не Сервер Тогда
ТипВсеСсылки = Новый ОписаниеТипов;
#КонецЕсли
Для Каждого КлючИЗначение Из ПометкиКоманд Цикл
ИмяКоманды = КлючИЗначение.Ключ;
ИмяФайла = КаталогВыгрузкиРасширения + "\CommonCommand." + ИмяКоманды + ".xml";
ДокументДОМ = ирОбщий.ПрочитатьФайлВДокументDOMЛкс(ИмяФайла);
//ЧтениеXML = Новый ЧтениеXML;
//ПараметрыЧтения = Новый ПараметрыЧтенияXML(,,,,,,,, Ложь);
//ЧтениеXML.ОткрытьФайл(ИмяФайла, ПараметрыЧтения);
//ПостроительДом = Новый ПостроительDOM();
//ДокументДОМ = ПостроительДом.Прочитать(ЧтениеXML);
//ЧтениеXML.Закрыть();
УзелТиповПараметра = ДокументДом.ПолучитьЭлементыПоИмени("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ВФайлЛкс(ДокументДом, ИмяФайла);
//ЗаписьXML = Новый ЗаписьXML;
//ЗаписьXML.ОткрытьФайл(ИмяФайла);
//ЗаписьДом = Новый ЗаписьDOM;
//ЗаписьДом.Записать(ДокументДом, ЗаписьXML);
//ЗаписьXML.Закрыть();
КонецЦикла;
ТекстЛога = "";
// Пришлось отказаться от частичной загрузки из-за непонятной ошибки
// Файл - Configuration.xml: ошибка частичной загрузки - идентификатор 15dc941a-fd9f-4d00-bc7e-3ef077518def загружаемой конфигурации отличается от идентификатора b9c0a797-9739-4c3f-a665-796b3bf92d6a сохраненной конфигурации
//ФайлыДляЗагрузки = НайтиФайлы(КаталогВыгрузкиРасширения, "*");
//ТекстовыйДокумент.Очистить();
//Для Каждого Файл Из ФайлыДляЗагрузки Цикл
// ТекстовыйДокумент.ДобавитьСтроку(Файл.ПолноеИмя);
//КонецЦикла;
//ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиРасширения);
//Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadConfigFromFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -listFile """ + ИмяФайлаСпискаВыгрузкиРасширения + """ -Format Plain",
// СтрокаСоединенияИнформационнойБазы(), ТекстЛога,,, "Загрузка расширения из файлов");
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadConfigFromFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -Format Plain",
СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Загрузка расширения из файлов");
УдалитьФайлы(КаталогВыгрузкиРасширения);
Если Не Успех Тогда
Сообщить(ТекстЛога);
КонецЕсли;
КонечныйФайл = ПолучитьИмяВременногоФайла();
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpCfg """ + КонечныйФайл + """ -Extension """ + ИмяРасширения + """", , ТекстЛога);
Если Не Успех Тогда
Сообщить(ТекстЛога);
Возврат Ложь;
КонецЕсли;
ЭтотРасширение.Записать(Новый ДвоичныеДанные(КонечныйФайл));
Возврат Истина;
КонецФункции
#КонецЕсли
#Если Клиент И Не ТонкийКлиент И Не ВебКлиент Тогда
Процедура ОткрытьОднократноАдаптациюРасширенияЛкс() Экспорт
ПометкиКоманд = ХранилищеОбщихНастроек.Загрузить("ИнструментыРазработчикаTormozit", "ирАдаптацияРасширения.ПометкиКоманд");
Если ПометкиКоманд = Неопределено Тогда
ПометкиКоманд = Новый Структура;
ХранилищеОбщихНастроек.Сохранить("ИнструментыРазработчикаTormozit", "ирАдаптацияРасширения.ПометкиКоманд", ПометкиКоманд);
ОткрытьФормуМодально("ОбщаяФорма.ирАдаптацияРасширения", Новый Структура("Автооткрытие", Истина));
КонецЕсли;
КонецПроцедуры
Функция ПодтверждениеОперацииСУБДЛкс() Экспорт
Возврат Вопрос("Вы осознаете риски и ответственность за использование прямого доступа к данным базы и нарушение лицензионного соглашения 1С?", РежимДиалогаВопрос.ДаНет) = КодВозвратаДиалога.Да;
КонецФункции
// РежимИмяСиноним - Булево - Истина - Имя
Процедура НастроитьАвтоТабличноеПолеДинамическогоСпискаЛкс(ОсновнойЭУ, РежимИмяСиноним = Ложь) Экспорт
// Антибаг платформы 8.2-8.3 для регистра бухгалтерии https://partners.v8.1c.ru/forum/t/1372055/m/1372055
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ОсновнойЭУ.Значение));
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
КорневойТип = ирОбщий.ПолучитьПервыйФрагментЛкс(ПолноеИмяМД);
Если КорневойТип <> "РегистрБухгалтерии" Тогда
ОсновнойЭУ.СоздатьКолонки();
КонецЕсли;
ВерсияПлатформы = ирКэш.Получить().ВерсияПлатформы;
//СтруктураХраненияПолей = ирКэш.ПолучитьСтруктуруХраненияБДЛкс().НайтиСтроки(Новый Структура("Назначение, Метаданные", "Основная", ПолноеИмяМД))[0].Поля;
ФильтрМетаданных = Новый Массив;
ФильтрМетаданных.Добавить(ПолноеИмяМД);
СтруктураХраненияТаблицы = ПолучитьСтруктуруХраненияБазыДанных(ФильтрМетаданных).НайтиСтроки(Новый Структура("Назначение, Метаданные", "Основная", ПолноеИмяМД))[0];
СтруктураХраненияПолей = СтруктураХраненияТаблицы.Поля;
Попытка
КолонкиСписка = ОсновнойЭУ.Значение.Колонки;
Исключение
// Перечисление
КонецПопытки;
КолонкиТП = ОсновнойЭУ.Колонки;
Колонка = КолонкиТП.Найти("Картинка");
Если Колонка = Неопределено Тогда
КолонкаКартинки = КолонкиТП.Добавить("Картинка");
КолонкаКартинки.ОтображатьСтандартнуюКартинку = Истина;
КолонкаКартинки.Ширина = 3;
КолонкаКартинки.ИзменениеРазмера = ИзменениеРазмераКолонки.НеИзменять;
КолонкаКартинки.ТекстШапки = "";
КонецЕсли;
Для Каждого ЭлементОтбора Из ОсновнойЭУ.Значение.Отбор Цикл
Колонка = ОсновнойЭУ.Колонки.Найти(ЭлементОтбора.Имя);
Если Колонка = Неопределено Тогда
// Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1002521#1002521
Если Ложь
Или Найти(ЭлементОтбора.Имя, "ВидСубконтоДт") = 1
Или Найти(ЭлементОтбора.Имя, "ВидСубконтоКт") = 1
Тогда
Продолжить;
КонецЕсли;
Попытка
КолонкиСписка.Добавить(ЭлементОтбора.Имя, Ложь);
Исключение
// Сюда попадает например элемент отбора от критерия отбора
Продолжить;
КонецПопытки;
Колонка = ОсновнойЭУ.Колонки.Добавить();
КонецЕсли;
//Колонка.ТекстШапки = ЭлементОтбора.Представление;
Если КорневойТип <> "Перечисление" Тогда
ДанныеПодключены = Ложь;
Если Истина
И ЭлементОтбора.ТипЗначения.СодержитТип(Тип("Булево"))
И ЭлементОтбора.ТипЗначения.Типы().Количество() = 1
Тогда
Колонка.УстановитьЭлементУправления(Тип("Флажок"));
Попытка
Колонка.ДанныеФлажка = ЭлементОтбора.Имя;
ДанныеПодключены = Истина;
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
КонецПопытки;
Иначе
Колонка.УстановитьЭлементУправления(Тип("ПолеВвода"));
Попытка
Колонка.Данные = ЭлементОтбора.Имя;
ДанныеПодключены = Истина;
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
КонецПопытки;
КонецЕсли;
Если Не ДанныеПодключены Тогда
Колонка.Видимость = Ложь;
КонецЕсли;
КонецЕсли;
// Закомментировал 13.02.2011
//Если ЗначениеЗаполнено(Колонка.Данные) Тогда
// Колонка.Имя = Колонка.Данные;
//КонецЕсли;
Колонка.Имя = ЭлементОтбора.Имя;
СтрокаСтрукутрыПоля = СтруктураХраненияПолей.Найти(ЭлементОтбора.Имя, "ИмяПоля");
Если СтрокаСтрукутрыПоля <> Неопределено Тогда
МетаданныеПоля = СтрокаСтрукутрыПоля.Метаданные;
Если ЗначениеЗаполнено(МетаданныеПоля) Тогда
МетаданныеПоля = Метаданные.НайтиПоПолномуИмени(МетаданныеПоля);
КонецЕсли;
Попытка
Колонка.ПодсказкаВШапке = МетаданныеПоля.Подсказка;
Исключение
// У графы журнала нет подсказки
КонецПопытки;
КонецЕсли;
// Антибаг платформы 8.2-8.3.6 https://partners.v8.1c.ru/forum/t/1337995/m/1337995
Если Истина
И ВерсияПлатформы < 803008
И ЭлементОтбора.ТипЗначения.СодержитТип(Тип("УникальныйИдентификатор"))
Тогда
Сообщить("Колонка """ + ЭлементОтбора.Имя + """ типа УникальныйИдентификатор не будет отображаться из-за ошибки платформы");
ОсновнойЭУ.Колонки.Удалить(Колонка);
Продолжить;
КонецЕсли;
КонецЦикла;
Если КолонкиСписка <> Неопределено Тогда
Для Каждого ЭлементНастройкиОтбора Из ОсновнойЭУ.НастройкаОтбора Цикл
ЭлементНастройкиОтбора.Доступность = Истина;
КонецЦикла;
ОбъектМД = Метаданные.НайтиПоТипу(ОсновнойЭУ.ТипЗначения.Типы()[0]);
НовыйПорядок = ирОбщий.ПолучитьСтрокуПорядкаЛкс(ОсновнойЭУ.Значение.Порядок);
Если Не ЗначениеЗаполнено(НовыйПорядок) Тогда
НастройкаПорядка = ОсновнойЭУ.НастройкаПорядка;
ПредопределенныеПоля = Новый Массив();
Если КорневойТип = "ПланСчетов" Тогда
ПредопределенныеПоля.Добавить("Код");
КонецЕсли;
ПредопределенныеПоля.Добавить("Наименование");
ПредопределенныеПоля.Добавить("Дата");
ПредопределенныеПоля.Добавить("Период");
ПредопределенныеПоля.Добавить("ДатаИзменения");
ПредопределенныеПоля.Добавить("ДатаСоздания");
ПредопределенныеПоля.Добавить("Номер");
ПредопределенныеПоля.Добавить("Код");
Для Каждого ПредопределенноеПоле Из ПредопределенныеПоля Цикл
ЭлементПорядка = НастройкаПорядка.Найти(ПредопределенноеПоле);
Если ЭлементПорядка <> Неопределено Тогда
Для Каждого ИндексТаблицыБД Из СтруктураХраненияТаблицы.Индексы Цикл
Если ИндексТаблицыБД.Поля[0].ИмяПоля = ПредопределенноеПоле Тогда
ЭлементПорядка.Доступность = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ЭлементПорядка.Доступность Тогда
НовыйПорядок = ПредопределенноеПоле;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЗначениеЗаполнено(НовыйПорядок) Тогда
// Обязательную установку делаем, чтобы в шапках появились индикаторы сортировки (антибаг платформы)
ОсновнойЭУ.Значение.Порядок.Установить(НовыйПорядок);
КонецЕсли;
//Компоновщик = ирКэш.ПолучитьКомпоновщикТаблицыМетаданныхЛкс(ОбъектМД.ПолноеИмя());
//#Если Сервер И Не Сервер Тогда
// Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
//#КонецЕсли
//Для Каждого ПолеВыбора Из Компоновщик.Настройки.ДоступныеПоляВыбора.Элементы Цикл
// Если ПолеВыбора.Папка Тогда
// Продолжить;
// КонецЕсли;
//КонецЦикла;
КонецЕсли;
Если ЛиКорневойТипСсылкиЛкс(КорневойТип) Тогда
КолонкаИдентификатора = ОсновнойЭУ.Колонки.Добавить("ИдентификаторСсылкиЛкс");
КолонкаИдентификатора.ТекстШапки = "Идентификатор ссылки";
КонецЕсли;
Если ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда
КолонкаИдентификатора = ОсновнойЭУ.Колонки.Добавить("ИмяПредопределенныхДанных");
КолонкаИдентификатора.ТекстШапки = "Имя предопределенных данных";
КолонкаИдентификатора.Видимость = Ложь;
КонецЕсли;
НастроитьЗаголовкиАвтоТабличногоПоляДинамическогоСпискаЛкс(ОсновнойЭУ, РежимИмяСиноним);
КонецПроцедуры
Процедура НастроитьЗаголовкиАвтоТабличногоПоляДинамическогоСпискаЛкс(Знач ОсновнойЭУ, Знач РежимИмяСиноним) Экспорт
Для Каждого ЭлементОтбора Из ОсновнойЭУ.Значение.Отбор Цикл
Колонка = ОсновнойЭУ.Колонки.Найти(ЭлементОтбора.Имя);
Если Колонка = Неопределено Тогда
Продолжить;
КонецЕсли;
Если РежимИмяСиноним Тогда
Колонка.ТекстШапки = ЭлементОтбора.Имя;
Иначе
Колонка.ТекстШапки = ЭлементОтбора.Представление;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // НастроитьАвтоТабличноеПолеДинамическогоСписка()
// Параметры
// МетаданныеКолонок - КоллекцияОбъектовМетаданных, ТаблицаЗначений - для таблицы значений используются колонки Имя и Метаданные
Процедура НастроитьДобавленныеКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, ОписанияТиповКолонок = Неопределено, МетаданныеКолонок = Неопределено, ДоступныеПоляВыбора = Неопределено,
ТолькоПросмотр = Ложь) Экспорт
Если ОписанияТиповКолонок = Неопределено Тогда
ОписанияТиповКолонок = ТабличноеПоле.Значение.Колонки;
КонецЕсли;
Для Каждого КолонкаТаблицы Из ОписанияТиповКолонок Цикл
КолонкаТабличногоПоля = ТабличноеПоле.Колонки.Найти(КолонкаТаблицы.Имя);
Если КолонкаТабличногоПоля = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ТолькоПросмотр Тогда
КолонкаТабличногоПоля.ТолькоПросмотр = Истина;
КонецЕсли;
ТипыРеквизита = КолонкаТаблицы.ТипЗначения.Типы();
Если ТипыРеквизита.Количество() = 1 И ТипыРеквизита[0] = Тип("Булево") Тогда
КолонкаТабличногоПоля.Данные = "";
КолонкаТабличногоПоля.ДанныеФлажка = КолонкаТаблицы.Имя;
КолонкаТабличногоПоля.РежимРедактирования = РежимРедактированияКолонки.Непосредственно;
КолонкаТабличногоПоля.Ширина = 3;
Иначе
Если КолонкаТаблицы.Ширина > 0 Тогда
КолонкаТабличногоПоля.Ширина = Мин(КолонкаТаблицы.Ширина, 50); // Почему то в редакторе таблицы значений не работала автоширина (-1)
КонецЕсли;
Если КолонкаТабличногоПоля.Ширина = 0 Тогда
КолонкаТабличногоПоля.Ширина = 3; // Для 8.2 необходимо, иначе колонки будут не видны
КонецЕсли;
КонецЕсли;
Если МетаданныеКолонок <> Неопределено Тогда
Если ТипЗнч(МетаданныеКолонок) = Тип("КоллекцияОбъектовМетаданных") Тогда
Метареквизит = МетаданныеКолонок.Найти(КолонкаТаблицы.Имя);
Иначе
СтрокаПоля = МетаданныеКолонок.Найти(КолонкаТаблицы.Имя, "Имя");
Если СтрокаПоля <> Неопределено Тогда
Метареквизит = СтрокаПоля.Метаданные;
Иначе
Метареквизит = Неопределено;
КонецЕсли;
КонецЕсли;
Если Метареквизит <> Неопределено Тогда
Попытка
Подсказка = Метареквизит.Подсказка;
Исключение
// У графы журнала нет подсказки
Подсказка = Неопределено;
КонецПопытки;
Если Подсказка <> Неопределено Тогда
КолонкаТабличногоПоля.ПодсказкаВШапке = Подсказка;
Если Метареквизит.МногострочныйРежим Тогда
КолонкаТабличногоПоля.ЭлементУправления.МногострочныйРежим = Метареквизит.МногострочныйРежим;
КолонкаТабличногоПоля.ЭлементУправления.РасширенноеРедактирование = Метареквизит.РасширенноеРедактирование;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ДоступныеПоляВыбора <> Неопределено Тогда
ДоступноеПоле = ДоступныеПоляВыбора.НайтиПоле(Новый ПолеКомпоновкиДанных(КолонкаТаблицы.Имя));
Если ДоступноеПоле <> Неопределено Тогда
КолонкаТабличногоПоля.ТекстШапки = ДоступноеПоле.Заголовок;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ДобавитьСтраницуТЧ()
Процедура ФормаОбработкаОповещенияЛкс(ЭтаФорма, ИмяСобытия, Параметр, Источник) Экспорт
Если ИмяСобытия = "ЗакрытьВсеФормыИнструментовРазработчика" Тогда
Если ЭтаФорма.Открыта() Тогда
ЭтаФорма.Закрыть();
Если ЭтаФорма.Открыта() Тогда
Параметр.Отказ = Истина;
КонецЕсли;
КонецЕсли;
ИначеЕсли ИмяСобытия = "ЕстьОткрытыеФормыИнструментовРазработчика" Тогда
Если ЭтаФорма.Открыта() Тогда
Параметр.Ответ = Истина;
КонецЕсли;
ИначеЕсли ИмяСобытия = "ОбнаружитьСебя" Тогда
Попытка
Сообщить(ЭтаФорма.Имя);
Исключение
Попытка
Сообщить(ЭтаФорма.ЭтотОбъект.Метаданные().ПолноеИмя());
Исключение
Сообщить("Неизвестная форма");
КонецПопытки;
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьФайлСПредупреждениемЛкс(ИмяФайла, СтандартнаяОбработка = Неопределено) Экспорт
СтандартнаяОбработка = Ложь;
Ответ = Вопрос("Вы уверены, что хотите открыть """ + ИмяФайла + """?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
ЗапуститьПриложение(ИмяФайла);
КонецЕсли;
КонецПроцедуры
// Создает новый экземпляр обработки и открывает его форму.
//
// Параметры:
// Объект - ОбработкаОбъект, ОтчетОбъект.
//
// Возвращаемое значение:
// Форма.
//
Функция ОткрытьНовоеОкноОбработкиЛкс(ЭтотОбъект) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
НовыйОбъект = ПолучитьМенеджерЛкс(ЭтотОбъект).Создать();
Иначе
ПолноеИмяОбъекта = ЭтотОбъект.Метаданные().ПолноеИмя();
НовыйОбъект = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяОбъекта);
КонецЕсли;
Результат = НовыйОбъект.ПолучитьФорму();
Результат.Открыть();
Возврат Результат;
КонецФункции // ОткрытьНовоеОкноОбработкиЛкс()
Функция ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры = Неопределено, Владелец = Неопределено, Уникальность = Неопределено, Окно = Неопределено, ТолькоВнешниеФормы = Ложь) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
//ирПортативный #Если Сервер И Не Сервер Тогда
// Такой прием нужен для обхода ошибка компиляции в портативном режиме
Результат = ПолучитьФорму(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
//ирПортативный #КонецЕсли
Иначе
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяФормы);
Если Не ТолькоВнешниеФормы Тогда
ОбъектМД = Метаданные.НайтиПоПолномуИмени(Фрагменты[0] + "." + Фрагменты[1]);
КонецЕсли;
Если ОбъектМД = Неопределено Тогда
ТипМетаданных = Фрагменты[0];
Менеджер = ирПортативный.ПолучитьМенеджерТипаМетаданныхЛкс(ТипМетаданных);
ПолноеИмяФайла = ирПортативный.ПолучитьПолноеИмяФайлаПортативногоОбъектаМетаданныхЛкс(Фрагменты[1], ТипМетаданных);
Если Истина
И СтрокиРавныЛкс(Фрагменты[2], "Форма")
И Фрагменты.Количество() = 4
Тогда
ИмяФормы = Фрагменты[3];
Иначе
ИмяФормы = Неопределено;
КонецЕсли;
Результат = Менеджер.ПолучитьФорму(ПолноеИмяФайла, ИмяФормы, Владелец, Уникальность);
Иначе
Результат = ирПортативный.ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОткрытьФормуЛкс(ПолноеИмяФормы, Параметры = Неопределено, Владелец = Неопределено, Уникальность = Неопределено, Окно = Неопределено) Экспорт
Форма = ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
Форма.Открыть();
Возврат Форма;
КонецФункции
Функция ПолучитьОбщуюКартинкуЛкс(Имя) Экспорт
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
Результат = ирПортативный.ПолучитьОбщуюКартинкуЛкс(Имя);
Иначе
Результат = БиблиотекаКартинок[Имя];
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьЦветСтиляЛкс(ИмяЦвета) Экспорт
Если Ложь
Или ирКэш.ЛиПортативныйРежимЛкс()
Или ирКэш.ЛиЭтоРасширениеКонфигурацииЛкс()
Тогда
//Результат = ирПортативный.ПолучитьЦветСтиляЛкс(Имя);
Если ИмяЦвета = "ирТекстИнформационнойНадписи" Тогда
Возврат Новый Цвет(83, 106, 194);
ИначеЕсли ИмяЦвета = "ирЦветФонаЧередованияСтрок" Тогда
Возврат WebЦвета.МятныйКрем;
ИначеЕсли ИмяЦвета = "ирЦветФонаВычисляемогоЗначения" Тогда
Возврат WebЦвета.ГолубойСКраснымОттенком;
ИначеЕсли ИмяЦвета = "ирЦветФонаОшибки" Тогда
Возврат Новый Цвет(255, 245, 245);
ИначеЕсли ИмяЦвета = "ирЦветФонаРасширенногоПредставленияЗначения" Тогда
Возврат Новый Цвет(255, 255, 180);
Иначе
Возврат Новый Цвет();
КонецЕсли;
Иначе
Результат = ЦветаСтиля[ИмяЦвета];
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// Значение -
// ОчиститьПередУстановкой - Булево
// УстановитьТекст - Булево
// УстановитьЗначение - Булево
//
Функция БуферОбмена_УстановитьЗначениеЛкс(Знач Значение = "", Знач ОчиститьПередУстановкой = Истина, Знач УстановитьТекст = Истина, Знач УстановитьЗначение = Истина) Экспорт
WinAPI = ирКэш.ПолучитьWinAPI();
Если ОчиститьПередУстановкой Тогда
WinAPI.OpenClipboard(0);
WinAPI.EmptyClipboard();
WinAPI.CloseClipboard();
КонецЕсли;
CF_TEXT = 1;
CF_UNICODETEXT = 13;
CF_OEMTEXT = 7;
Если УстановитьЗначение Тогда
ФорматБуфераОбмена1С = ирКэш.ПолучитьФорматБуфераОбмена1СЛкс();
ВнутреннееЗначение = СохранитьОбъектВВидеСтрокиXMLЛкс(Значение,,, Ложь);
БуферОбмена_УстановитьДанныеПоФорматуЛкс(ВнутреннееЗначение, ФорматБуфераОбмена1С);
КонецЕсли;
Если УстановитьТекст Тогда
ВнутреннееЗначение = "" + Значение; // Может тормозить из-за обращений к БД
Если ВнутреннееЗначение <> "" Тогда
БуферОбмена_УстановитьДанныеПоФорматуЛкс(ВнутреннееЗначение, CF_UNICODETEXT);
КонецЕсли;
КонецЕсли;
КонецФункции
// Параметры:
// ВнутреннееЗначение -
// ФорматЗначения - Число(0,0) - CF_TEXT = 1;
// ПомещатьВКодировкеUTF8 - Булево - Иначе используется UNICODE
//
Функция БуферОбмена_УстановитьДанныеПоФорматуЛкс(Знач ВнутреннееЗначение, Знач ФорматЗначения = 1, Знач ПомещатьВКодировкеUTF8 = Ложь) Экспорт
WinAPI = ирКэш.ПолучитьWinAPI();
ВнутреннееЗначение = "" + ВнутреннееЗначение;
КоличествоСимволов = СтрДлина(ВнутреннееЗначение);
ПромежуточныйТекст = WinAPI.StrPtr(ВнутреннееЗначение, "s");
GMEM_DDESHARE = 8192; // &H2000;
Дескриптор = WinAPI.GlobalAlloc(GMEM_DDESHARE, (КоличествоСимволов + 1) * 2);
Указатель = WinAPI.GlobalLock(Дескриптор);
WinAPI.MultiByteToWideChar(0, 0, ПромежуточныйТекст, -1, Указатель, КоличествоСимволов + 1);
Если ПомещатьВКодировкеUTF8 Тогда
Дескриптор2 = WinAPI.GlobalAlloc(GMEM_DDESHARE, (КоличествоСимволов + 1) * 1);
Указатель2 = WinAPI.GlobalLock(Дескриптор2);
CP_UTF8 = 65001; // UTF-8 translation
WinAPI.WideCharToMultiByte(CP_UTF8, 0, Указатель, -1, Указатель2, КоличествоСимволов + 1);
WinAPI.GlobalUnlock(Дескриптор);
Указатель = Указатель2;
Дескриптор = Указатель2;
КонецЕсли;
WinAPI.OpenClipboard(0);
WinAPI.SetClipboardData(ФорматЗначения, Дескриптор);
WinAPI.CloseClipboard();
WinAPI.GlobalUnlock(Дескриптор);
КонецФункции
// Параметры:
// ФорматЗначения - Число(0,0) - CF_TEXT = 1;
// Кодировка - Строка(0,П) - w (по умолчанию), s, z. Значения s и z нужны для чтения строки в ANSI- или OEM-кодировке, при этом она конвертируется в Юникод
//
Функция БуферОбмена_ПолучитьДанныеПоФорматуЛкс(Знач ФорматЗначения = 1, Знач Кодировка = "w") Экспорт
WinAPI = ирКэш.ПолучитьWinAPI();
WinAPI.OpenClipboard(0);
Дескриптор = WinAPI.GetClipboardData(ФорматЗначения);
Если Дескриптор <> 0 Тогда
Указатель = WinAPI.GlobalLock(Дескриптор);
Результат = WinAPI.StrGet(Указатель, Кодировка);
WinAPI.GlobalUnlock(Дескриптор);
Иначе
Результат = "";
КонецЕсли;
WinAPI.CloseClipboard();
Возврат Результат;
КонецФункции
Функция БуферОбмена_ПолучитьЗначениеЛкс() Экспорт
ФорматБуфераОбмена1С = ирКэш.ПолучитьФорматБуфераОбмена1СЛкс();
СтрокаXML = БуферОбмена_ПолучитьДанныеПоФорматуЛкс(ФорматБуфераОбмена1С);
Результат = ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаXML,,, Ложь);
Возврат Результат;
КонецФункции
Функция БуферОбмена_ПолучитьТекстЛкс() Экспорт
CF_UNICODETEXT = 13;
Результат = БуферОбмена_ПолучитьДанныеПоФорматуЛкс(CF_UNICODETEXT);
Возврат Результат;
КонецФункции
// Параметры:
// ПолеВвода - ПолеВвода
// Значение -
// Текст - Строка(0,П)
//
Функция ВставитьЗначениеВПолеВводаЛкс(Знач ПолеВвода, Знач Значение, Знач Текст = "") Экспорт
Результат = Ложь;
Если Истина
И Значение <> Неопределено
И Не ПолеВвода.ТолькоПросмотр
Тогда
ТипНовогоЗначения = ТипЗнч(Значение);
Если Ложь
Или ТипЗнч(ПолеВвода.Значение) = ТипНовогоЗначения
Или ПолеВвода.ОграничениеТипа.Типы().Количество() = 0
Или ПолеВвода.ОграничениеТипа.СодержитТип(ТипНовогоЗначения)
Тогда
Результат = ИнтерактивноЗаписатьВЭлементУправленияЛкс(ПолеВвода, Значение);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// НастройкаДействия - СправочникСсылка.ЭлементыКомандныхПанелей2iS - Для команд-списков содержит ссылку элемента списка
// Кнопка - КнопкаКоманднойПанели
// СтандартнаяОбработка - Булево - Используется в случае связи кнопки с параметром.
// ИсточникДействий - ПолеHTMLДокумента, ПолеВвода, ПолеТабличногоДокумента, ПолеТекстовогоДокумента, ТабличноеПоле, Форма
//
Функция БуферОбмена_ВставитьЛкс(Знач ЭтаФорма, Знач Кнопка) Экспорт
ТекущийЭлементФормы = ЭтаФорма.ТекущийЭлемент;
Текст = БуферОбмена_ПолучитьТекстЛкс();
Значение = БуферОбмена_ПолучитьЗначениеЛкс();
ПродолжитьОбработку = Истина;
ТипЗначения = ТипЗнч(Значение);
Если ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеВвода") Тогда
Если Не ЭтаФорма.ТолькоПросмотр Тогда
Если ТипЗначения = Тип("Массив") Тогда
Значение = Значение[0];
КонецЕсли;
ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ТекущийЭлементФормы, Значение, Текст);
Если ПродолжитьОбработку И ЗначениеЗаполнено(ТекущийЭлементФормы.Данные) Тогда
// Например ссылка таблицы внешнего источника в поле ввода не может быть установлена через оповещение выбора
Попытка
ЭтаФорма[ТекущийЭлементФормы.Данные] = Значение;
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле") Тогда
Попытка
РедактированиеВДиалоге = ТекущийЭлементФормы.СпособРедактирования = СпособРедактированияСписка.ВДиалоге;
Исключение
РедактированиеВДиалоге = Ложь;
КонецПопытки;
Если Истина
И Не РедактированиеВДиалоге
И Не ЭтаФорма.ТолькоПросмотр
И Не ТекущийЭлементФормы.ТолькоПросмотр
И ТекущийЭлементФормы.ТекущаяКолонка <> Неопределено
Тогда
ДобавитьСтроку = Истина
И ТекущийЭлементФормы.ТекущиеДанные = Неопределено
И ТекущийЭлементФормы.ИзменятьСоставСтрок;
Если Истина
И Значение <> Неопределено
И ТекущийЭлементФормы.ИзменятьСоставСтрок
И Не ДобавитьСтроку
Тогда
Ответ = Вопрос("Выполнить вставку значения в новую строку (иначе будет выполнена вставка в текущую)?", РежимДиалогаВопрос.ДаНет,
, КодВозвратаДиалога.Нет);
ДобавитьСтроку = Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если ДобавитьСтроку Тогда
ИмяТекущейКолонки = ТекущийЭлементФормы.ТекущаяКолонка.Имя;
ТекущийЭлементФормы.ДобавитьСтроку();
ТекущийЭлементФормы.ТекущаяКолонка = ТекущийЭлементФормы.Колонки[ИмяТекущейКолонки];
КонецЕсли;
Если ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено Тогда
ТекущийЭлементФормы.ИзменитьСтроку(); // Нужно делать, т.к. табличное поле выходит из режима редактирования строку при вызове команды и иногда установке текущей колонки
КонецЕсли;
Если ТекущийЭлементФормы.ТекущиеДанные <> Неопределено Тогда
ПолеВвода = ТекущийЭлементФормы.ТекущаяКолонка.ЭлементУправления;
Если ТипЗнч(ПолеВвода) = Тип("ПолеВвода") Тогда
Если ТипЗначения = Тип("Массив") Тогда
Значение = Значение[0];
КонецЕсли;
ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ПолеВвода, Значение, Текст);
ИмяКолонкиДанных = ТекущийЭлементФормы.ТекущаяКолонка.Данные;
Если ПродолжитьОбработку И ЗначениеЗаполнено(ИмяКолонкиДанных) Тогда
// Например ссылка таблицы внешнего источника в поле ввода не может быть установлена через оповещение выбора
Если ТипЗнч(ТекущийЭлементФормы.ТекущиеДанные) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
ИмяКолонкиДанных = ПолучитьПервыйФрагментЛкс(ИмяКолонкиДанных, "Для");
КонецЕсли;
Попытка
ТекущийЭлементФормы.ТекущиеДанные[ИмяКолонкиДанных] = Значение;
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ПродолжитьОбработку Тогда
мПлатформа = ирКэш.Получить();
мПлатформа.ПараметрыОбработчикаОжидания = Новый Структура("ИмяМетода, Кнопка, СочетаниеКлавиш", "УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс", Кнопка, Кнопка.СочетаниеКлавиш);
Кнопка.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.Нет);
//ирПлатформа.WshShell.SendKeys("^v^м", 20); //англ.v,русс.м
WinAPI = ирКэш.ПолучитьWinAPI();
ДескрипторОкнаФокуса = WinAPI.GetActiveWindow();
WinAPI.EnableWindow(ДескрипторОкнаФокуса);
WM_KEYDOWN = 256; //0x0100
WM_KEYUP = 257; //0x0101
WM_COPY = 757; //0x0301
WM_CHAR = 258; //0x0102
WM_PASTE = 758; //0x0302
WM_GETTEXT = 13; //0x000D
VK_CONTROL = 17; // CTRL
KEY_V = 86; // V
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, VK_CONTROL, 1);
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, KEY_V, 1);
Если WinAPI.GetAsyncKeyState(VK_CONTROL) = 0 Тогда
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, VK_CONTROL, 1);
КонецЕсли;
Если WinAPI.GetAsyncKeyState(KEY_V) = 0 Тогда
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, KEY_V, 1);
КонецЕсли;
ЭтаФорма.ПодключитьОбработчикОжидания("ОбработчикОжиданияСПараметрамиЛкс", 0.1, Истина);
КонецЕсли;
КонецФункции
// Параметры:
// ЭтаФорма - Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма
// НастройкаДействия - СправочникСсылка.ЭлементыКомандныхПанелей2iS - Для команд-списков содержит ссылку элемента списка
// Кнопка - КнопкаКоманднойПанели
// СтандартнаяОбработка - Булево - Используется в случае связи кнопки с параметром.
// ИсточникДействий - ПолеHTMLДокумента, ПолеВвода, ПолеТабличногоДокумента, ПолеТекстовогоДокумента, ТабличноеПоле, Форма
//
Функция БуферОбмена_КопироватьЛкс(Знач ЭтаФорма, Знач Кнопка) Экспорт
ТекущийЭлементФормы = ЭтаФорма.ТекущийЭлемент;
Если ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеВвода") Тогда
Значение = ТекущийЭлементФормы.Значение;
//Текст = "" + ТекущийЭлементФормы.ВыделенныйТекст;
Если ТипЗнч(Значение) = Тип("Строка") Тогда
Значение = Неопределено;
КонецЕсли;
ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле") Тогда
//:ТекущийЭлементФормы = Новый ("ТабличноеПоле")
Если Истина
И ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено
И ТекущийЭлементФормы.ТекущаяКолонка <> Неопределено
Тогда
Ячейка = ТекущийЭлементФормы.ОформлениеСтроки(ТекущийЭлементФормы.ТекущаяСтрока).Ячейки[ТекущийЭлементФормы.ТекущаяКолонка.Имя];
Значение = Ячейка.Значение;
//Если ТипЗнч(Значение) = Тип("Строка") Тогда
////Если ПолучитьОписаниеТиповВсеРедактируемыеТипыЛкс().СодержитТип(ТипЗнч(Значение)) Тогда
// ОбъектМДСписка = Метаданные.НайтиПоТипу(ТипЗнч(ТекущийЭлементФормы.Значение));
// Если ОбъектМДСписка <> Неопределено Тогда
// Если ЛиКорневойТипСсылкиЛкс(ПолучитьПервыйФрагментЛкс(ОбъектМДСписка.ПолноеИмя())) Тогда
// КлючеваяКолонкаДанных = "Ссылка";
// КонецЕсли;
// КонецЕсли;
// ТипСтроки = ТипЗнч(ТекущийЭлементФормы.ТекущаяСтрока);
// Если КлючеваяКолонкаДанных <> Неопределено Тогда
// Значение = Новый Массив;
// Для Каждого ВыделеннаяСтрока Из ТекущийЭлементФормы.ВыделенныеСтроки Цикл
// Значение.Добавить(ВыделеннаяСтрока[КлючеваяКолонкаДанных]);
// КонецЦикла;
// ИначеЕсли ТипСтроки = Тип("ДоступноеПолеКомпоновкиДанных") Тогда
// Значение = Новый Массив;
// Для Каждого ВыделеннаяСтрока Из ТекущийЭлементФормы.ВыделенныеСтроки Цикл
// Значение.Добавить(ВыделеннаяСтрока);
// КонецЦикла;
// Иначе
// Значение = Неопределено;
// КонецЕсли;
//КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеТабличногоДокумента") Тогда
#Если Сервер И Не Сервер Тогда
ТекущийЭлементФормы = Новый ТабличныйДокумент;
#КонецЕсли
Попытка
ДанныеРасшифровки = ЭтаФорма.ДанныеРасшифровки;
Исключение
ДанныеРасшифровки = Неопределено;
КонецПопытки;
Если Истина
И ДанныеРасшифровки <> Неопределено
И ТекущийЭлементФормы.ТекущаяОбласть <> Неопределено
И ТипЗнч(ТекущийЭлементФормы.ТекущаяОбласть.Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных")
Тогда
ЭлементРасшифровки = ДанныеРасшифровки.Элементы[ТекущийЭлементФормы.ТекущаяОбласть.Расшифровка];
Для каждого ЗначениеПоля Из ЭлементРасшифровки.ПолучитьПоля() Цикл
Если Не ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение, Ложь) Тогда
Продолжить;
КонецЕсли;
Значение = ЗначениеПоля.Значение;
Прервать;
КонецЦикла;
КонецЕсли;
КонецЕсли;
мПлатформа = ирКэш.Получить();
мПлатформа.ПараметрыОбработчикаОжидания = Новый Структура("ИмяМетода, Кнопка, СочетаниеКлавиш", "УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс", Кнопка, Кнопка.СочетаниеКлавиш);
Если Значение <> Неопределено Тогда
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("ИмяМетода", "БуферОбмена_УстановитьЗначениеИУстановитьСочетаниеКлавишОтложенноЛкс");
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("Значение", Значение);
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("ОчиститьПередУстановкой", Ложь);
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("УстановитьТекст", Ложь);
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("УстановитьЗначение", Истина);
КонецЕсли;
Кнопка.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.Нет);
//ирПлатформа.WshShell.SendKeys("^c^с"); //англ.C,русс.С
WinAPI = ирКэш.ПолучитьWinAPI();
ДескрипторОкнаФокуса = WinAPI.GetActiveWindow();
WinAPI.EnableWindow(ДескрипторОкнаФокуса);
WM_KEYDOWN = 256; //0x0100
WM_KEYUP = 257; //0x0101
WM_COPY = 757; //0x0301
WM_CHAR = 258; //0x0102
WM_PASTE = 758; //0x0302
WM_GETTEXT = 13; //0x000D
VK_CONTROL = 17; // CTRL
KEY_C = 67; // С
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, VK_CONTROL, 1);
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, KEY_C, 1);
Если WinAPI.GetAsyncKeyState(VK_CONTROL) = 0 Тогда
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, VK_CONTROL, 1);
КонецЕсли;
Если WinAPI.GetAsyncKeyState(KEY_C) = 0 Тогда
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, KEY_C, 1);
КонецЕсли;
ЭтаФорма.ПодключитьОбработчикОжидания("ОбработчикОжиданияСПараметрамиЛкс", 0.1, Истина);
КонецФункции
Функция ОткрытьРазличныеЗначенияКолонкиЛкс(Знач ТабличноеПоле) Экспорт
ирОбщий.ПолучитьФормуЛкс("Обработка.ирРазличныеЗначенияКолонки.Форма",, ТабличноеПоле).ОткрытьМодально();
КонецФункции
Процедура Форма_ВставитьСкрытуюКоманднуюПанельДляРаботыСБуферомОбменаЛкс(ЭтаФорма) Экспорт
ЭлементыФормы = ЭтаФорма.ЭлементыФормы;
ИмяКоманднойПанели = "КП_ПолеВвода";
КонтекстноеМенюФормы = ЭлементыФормы.Найти(ИмяКоманднойПанели);
Если КонтекстноеМенюФормы = Неопределено Тогда
КонтекстноеМенюФормы = ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), ИмяКоманднойПанели);
КонтекстноеМенюФормы.Видимость = Ложь;
КонецЕсли;
//лПлатформа = ирКэш.Получить();
//МакетФормы = лПлатформа.ПолучитьФорму("УниверсальныеКоманды");
//КонтекстноеМенюМакета = МакетФормы.ЭлементыФормы.КоманднаяПанель.Кнопки.ПолеВвода;
//ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(МакетФормы, КонтекстноеМенюМакета.Кнопки, КонтекстноеМенюФормы);
КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(КонтекстноеМенюФормы);
Для Каждого ЭлементФормы Из ЭлементыФормы Цикл
Если ТипЗнч(ЭлементФормы) = Тип("ПолеВвода") Тогда
Попытка
КонтекстноеМеню = ЭлементФормы.КонтекстноеМеню;
Исключение
// Поле ввода принадлежит не панели, поэтому у него нет свойства
Продолжить;
КонецПопытки;
Если КонтекстноеМеню = Неопределено Тогда
//ЭлементФормы.АвтоКонтекстноеМеню = Ложь;
ЭлементФормы.КонтекстноеМеню = КонтекстноеМенюФормы;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ДействияФормы = ЭлементыФормы.Найти("ДействияФормы");
Если ТипЗнч(ДействияФормы) <> Тип("КоманднаяПанель") Тогда
ПанельФормы = ЭтаФорма.Панель;
Если ПанельФормы.КонтекстноеМеню = Неопределено Тогда
ДействияФормы = ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), "ДействияФормыАвто", Ложь);
ДействияФормы.ИсточникДействий = ЭтаФорма;
ПанельФормы.КонтекстноеМеню = ДействияФормы;
Иначе
ДействияФормы = ПанельФормы.КонтекстноеМеню;
КонецЕсли;
КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(ДействияФормы);
КонецЕсли;
КонецПроцедуры
Процедура Форма_ПриЗакрытииЛкс(ЭтаФорма) Экспорт
// У некоторых из-за большого объема данных в настройках пользователя это вызывает большие задержки
//ПодключитьГлобальныйОбработчикОжиданияЛкс("СохранитьНастройкиПользователяОтложенноЛкс");
КонецПроцедуры
Процедура КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(Знач КоманднаяПанельПолеВвода)
КнопкаКопировать = КоманднаяПанельПолеВвода.Кнопки.Добавить("МакетФормы");
КнопкаКопировать.Имя = "БуферОбмена_Копировать";
КнопкаКопировать.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
КнопкаКопировать.Текст = "Копировать значение";
КнопкаКопировать.Подсказка = "Копировать значение в буфер обмена";
КнопкаКопировать.Пояснение = КнопкаКопировать.Подсказка;
КнопкаКопировать.Картинка = ПолучитьОбщуюКартинкуЛкс("ирКопировать");
КнопкаКопировать.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.C, Истина, , Истина);
Попытка
КнопкаКопировать.Действие = Новый Действие("КлсУниверсальнаяКомандаНажатие");
Исключение
КоманднаяПанельПолеВвода.Кнопки.Удалить(КнопкаКопировать);
Возврат;
КонецПопытки;
КнопкаКопировать = КоманднаяПанельПолеВвода.Кнопки.Добавить();
КнопкаКопировать.Имя = "БуферОбмена_Вставить";
КнопкаКопировать.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
КнопкаКопировать.Текст = "Вставить значение";
КнопкаКопировать.Подсказка = "Вставить значение из буфера обмена";
КнопкаКопировать.Пояснение = КнопкаКопировать.Подсказка;
КнопкаКопировать.Картинка = ПолучитьОбщуюКартинкуЛкс("ирВставить");
КнопкаКопировать.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.V, Истина, , Истина);
КнопкаКопировать.Действие = Новый Действие("КлсУниверсальнаяКомандаНажатие");
КонецПроцедуры
Процедура УниверсальнаяКомандаФормыЛкс(ЭтаФорма, Кнопка) Экспорт
Если Кнопка.Имя = "БуферОбмена_Копировать" Тогда
БуферОбмена_КопироватьЛкс(ЭтаФорма, Кнопка);
ИначеЕсли Кнопка.Имя = "БуферОбмена_Вставить" Тогда
БуферОбмена_ВставитьЛкс(ЭтаФорма, Кнопка);
КонецЕсли;
КонецПроцедуры
Процедура УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс(Параметры) Экспорт
Параметры.Кнопка.СочетаниеКлавиш = Параметры.СочетаниеКлавиш;
КонецПроцедуры
Процедура БуферОбмена_УстановитьЗначениеИУстановитьСочетаниеКлавишОтложенноЛкс(Параметры) Экспорт
БуферОбмена_УстановитьЗначениеЛкс(Параметры.Значение, Параметры.ОчиститьПередУстановкой, Параметры.УстановитьТекст, Параметры.УстановитьЗначение);
УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс(Параметры);
КонецПроцедуры
Процедура ОбработчикОжиданияСПараметрамиЛкс() Экспорт
мПлатформа = ирКэш.Получить();
ПараметрыОбработчикаОжидания = мПлатформа.ПараметрыОбработчикаОжидания;
Выполнить(ПараметрыОбработчикаОжидания.ИмяМетода + "(ПараметрыОбработчикаОжидания)");
мПлатформа.ПараметрыОбработчикаОжидания = Неопределено;
КонецПроцедуры
// Родственник ВернутьПостоянныйПарольПользователяЛкс
// Пароль устанавливается временный и опционально роль ирРазработчик
Функция УстановитьВременныеСвойстваПользователюИБЛкс(ПользовательИБ, ПодменитьПарольНаВремяЗапуска = Истина, ВременноПредоставитьПравоРазработчикИР = Истина,
ОтключитьЗащитуОтОпасныхДействийНаВремяЗапуска = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ПользовательИБ = ПользователиИнформационнойБазы.СоздатьПользователя();
#КонецЕсли
мПлатформа = ирКэш.Получить();
НужноВернутьАутентификациюОС = Ложь;
НужноВернутьАутентификациюПаролем = Ложь;
НужноВернутьПароль = Ложь;
НужноВернутьЗащитуОтОпасныхДействий = Ложь;
УдалитьРольРазработчикИР = Ложь;
Если ПодменитьПарольНаВремяЗапуска Тогда
Если СтрокиРавныЛкс(ПользовательИБ.Имя, ИмяПользователя()) Тогда
Сообщить("Назначение временного пароля собственному пользователю не допускается");
Возврат Неопределено;
КонецЕсли;
мhash = ПользовательИБ.СохраняемоеЗначениеПароля;
Если ПользовательИБ.АутентификацияОС = Истина Тогда
ПользовательИБ.АутентификацияОС = Ложь;
НужноВернутьАутентификациюОС = Истина;
КонецЕсли;
Если ПользовательИБ.АутентификацияСтандартная = Ложь Тогда
ПользовательИБ.АутентификацияСтандартная = Истина;
НужноВернутьАутентификациюПаролем = Истина;
КонецЕсли;
Пароль = Формат(ТекущаяДата(), "ДФ=HHmmss") + XMLСтрока(НомерСеансаИнформационнойБазы()) + "!_qQ";
ПользовательИБ.Пароль = Пароль;
НужноВернутьПароль = Истина;
КонецЕсли;
Если ВременноПредоставитьПравоРазработчикИР И Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПользовательИБ.Роли.Содержит(Метаданные.Роли.ирРазработчик) Тогда
УдалитьРольРазработчикИР = Истина;
ПользовательИБ.Роли.Добавить(Метаданные.Роли.ирРазработчик);
КонецЕсли;
КонецЕсли;
Если ОтключитьЗащитуОтОпасныхДействийНаВремяЗапуска Тогда
Если мПлатформа.ВерсияПлатформы > 803009 И ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях Тогда
ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Ложь;
НужноВернутьЗащитуОтОпасныхДействий = Истина;
КонецЕсли;
КонецЕсли;
ПользовательИБ.Записать();
НаборПараметров = Новый Структура();
НаборПараметров.Вставить("mHash", мhash);
НаборПараметров.Вставить("НужноВернутьАутентификациюПаролем", НужноВернутьАутентификациюПаролем);
НаборПараметров.Вставить("НужноВернутьАутентификациюОС", НужноВернутьАутентификациюОС);
НаборПараметров.Вставить("ПользовательИБ", ПользовательИБ);
НаборПараметров.Вставить("НужноВернутьПароль", НужноВернутьПароль);
НаборПараметров.Вставить("НужноВернутьЗащитуОтОпасныхДействий", НужноВернутьЗащитуОтОпасныхДействий);
НаборПараметров.Вставить("УдалитьРольРазработчикИР", УдалитьРольРазработчикИР);
НаборПараметров.Вставить("Имя", ПользовательИБ.Имя);
НаборПараметров.Вставить("Пароль", Пароль);
Возврат НаборПараметров;
КонецФункции
// Родственник УстановитьВременныеСвойстваПользователюИБЛкс
Процедура ВернутьПостоянныеСвойстваПользователюИБЛкс(НаборПараметров = Неопределено) Экспорт;
//УстановитьПривилегированныйРежим(Истина);
Если НаборПараметров <> Неопределено Тогда
мhash = НаборПараметров.mhash;
НужноВернутьАутентификациюПаролем = НаборПараметров.НужноВернутьАутентификациюПаролем;
НужноВернутьАутентификациюОС = НаборПараметров.НужноВернутьАутентификациюОС;
НужноВернутьПароль = НаборПараметров.НужноВернутьПароль;
НужноВернутьЗащитуОтОпасныхДействий = НаборПараметров.НужноВернутьЗащитуОтОпасныхДействий;
ПользовательИБ = НаборПараметров.ПользовательИБ;
УдалитьРольРазработчикИР = НаборПараметров.УдалитьРольРазработчикИР;
Иначе
Возврат;
КонецЕсли;
Если НужноВернутьПароль Тогда
ПользовательИБ.СохраняемоеЗначениеПароля = мHash;
КонецЕсли;
Если НужноВернутьАутентификациюПаролем Тогда
ПользовательИБ.АутентификацияСтандартная = Ложь;
КонецЕсли;
Если НужноВернутьАутентификациюОС Тогда
ПользовательИБ.АутентификацияОС = Истина;
КонецЕсли;
Если НужноВернутьЗащитуОтОпасныхДействий Тогда
ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Истина;
КонецЕсли;
Если УдалитьРольРазработчикИР Тогда
ПользовательИБ.Роли.Удалить(Метаданные.Роли.ирРазработчик);
КонецЕсли;
ПользовательИБ.Записать();
КонецПроцедуры
Процедура ОткрытьМенеджерТабличногоПоляЛкс(ТабличноеПоле, ЭтаФорма) Экспорт
ирКэш.Получить().ПолучитьФорму("МенеджерТабличногоПоля", ЭтаФорма).УстановитьСвязь(ТабличноеПоле);
КонецПроцедуры
Процедура ОткрытьСвязанныйСеансТонкогоКлиентаЛкс() Экспорт
Результат = ирКэш.ПолучитьСеансТонкогоКлиентаЛкс();
Результат.Visible = Истина;
Окна = Результат.ПолучитьОкна();
СписокОткрытыхОбъектов = Новый СписокЗначений;
Для Каждого Окно Из Окна Цикл
Попытка
Содержимое = Окно.Содержимое;
Исключение
// В 8.2 нет такого свойства
Продолжить;
КонецПопытки;
Для Каждого Форма Из Содержимое Цикл
Попытка
СсылкаCOM = Форма.Parameters.Key;
Исключение
СсылкаCOM = Неопределено;
КонецПопытки;
Если СсылкаCOM <> Неопределено Тогда
ФрагментыИмениТипа = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(Форма.FormName);
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(Новый УникальныйИдентификатор(Результат.String(СсылкаCOM.УникальныйИдентификатор())));
Ссылка = Новый (Тип(ФрагментыИмениТипа[0] + "Ссылка." + ФрагментыИмениТипа[1]), МассивПараметров);
СписокОткрытыхОбъектов.Добавить(Ссылка, ФрагментыИмениТипа[0] + "." + ФрагментыИмениТипа[1] + " - " + Ссылка);
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если СписокОткрытыхОбъектов.Количество() > 0 Тогда
СписокОткрытыхОбъектов.СортироватьПоПредставлению();
ВыбранныйЭлемент = СписокОткрытыхОбъектов.ВыбратьЭлемент("Выберите объект для открытия в редакторе объекта БД");
Если ВыбранныйЭлемент <> Неопределено Тогда
ОткрытьСсылкуВРедактореОбъектаБДЛкс(ВыбранныйЭлемент.Значение);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ОповеститьОЗаписиОбъектаЛкс(ТипОбъекта, Источник = Неопределено) Экспорт
Оповестить("ЗаписанОбъект", ТипОбъекта, Источник);
ОповеститьОбИзменении(ТипОбъекта);
КонецПроцедуры
Функция ОткрытьОбъектМетаданныхЛкс(ОбъектИлиПолноеИмяМД) Экспорт
Если ТипЗнч(ОбъектИлиПолноеИмяМД) = Тип("ОбъектМетаданных") Тогда
ОбъектМД = ОбъектИлиПолноеИмяМД;
Иначе
ОбъектМД = ПолучитьМетаданныеЛкс(ОбъектИлиПолноеИмяМД);
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.НайтиПоТипу();
#КонецЕсли
Если ОбъектМД = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
Фрагменты = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД);
Если Фрагменты.Количество() = 2 Тогда
Форма = ПолучитьФормуЛкс("Обработка.ирИнтерфейснаяПанель.Форма");
Форма.ПараметрИмяОбъектаМетаданных = ПолноеИмяМД;
Форма.ПрименитьПараметрыФормы();
КонецЕсли;
Возврат Форма;
КонецФункции
#КонецЕсли
#Если Клиент Тогда
Процедура ОткрытьСписокИнструментовЛкс() Экспорт
#Если ВебКлиент Тогда
Сообщить("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ФормаУправляемая");
#Иначе
ФормаСпискаИнструментов = ПолучитьФормуЛкс("Обработка.ирПортативный.Форма.Форма");
ФормаСпискаИнструментов.ПараметрТолькоОткрытьНастройки = Истина;
ФормаСпискаИнструментов.Открыть();
#КонецЕсли
КонецПроцедуры
Процедура СохранитьНастройкиПользователяЛкс() Экспорт
#Если ВебКлиент Тогда
Сообщить("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ФормаУправляемая");
#Иначе
СохранитьНастройкиПользователя();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьНастройкиАлгоритмовЛкс() Экспорт
Если ирКэш.ЛиЭтоРасширениеКонфигурацииЛкс() Тогда
Сообщить("Команда недоступна в варианте Расширение");
Возврат;
КонецЕсли;
#Если ВебКлиент Тогда
Сообщить("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ФормаУправляемая");
#Иначе
Форма = ирКэш.Получить().ПолучитьФорму("НастройкиАлгоритмов");
Форма.Открыть();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьАдминистративнаяРегистрацияCOMЛкс() Экспорт
#Если ВебКлиент Тогда
Сообщить("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ФормаУправляемая");
#Иначе
Форма = ирКэш.Получить().ПолучитьФорму("АдминистративнаяРегистрацияCOM");
Форма.Открыть();
#КонецЕсли
КонецПроцедуры
#КонецЕсли
// Проверяет правильность заполнения реквизитов объекта
// Параметры:
// Объект -
// ОбязательныеПоля - Строка(0,П), Массив
// Отказ - Булево
// Заголовок - Строка(0,П)
//
// Возвращаемое значение: Булево - истина, если проверка пройдена успешно
Функция ПроверитьЗаполнениеРеквизитовОбъектаЛкс(Знач Объект, Знач ОбязательныеПоля = "", Отказ = Ложь) Экспорт
Результат = Истина;
Попытка
ОбменДаннымиЗагрузка = Объект.ОбменДанными.Загрузка;
Исключение
ОбменДаннымиЗагрузка = Ложь;
КонецПопытки;
Если ОбменДаннымиЗагрузка Тогда
Возврат Результат;
КонецЕсли;
Если ТипЗнч(ОбязательныеПоля) = Тип("Строка") Тогда
МассивПолей = ПолучитьМассивИзСтрокиСРазделителемЛкс(ОбязательныеПоля, ",", Истина);
ОбязательныеПоля = Новый Соответствие;
Для каждого Значение Из МассивПолей Цикл
ОбязательныеПоля[Значение] = "";
КонецЦикла;
//ОбязательныеПоля = Новый Структура(ОбязательныеПоля);
КонецЕсли;
РеквизитыМД = Объект.Метаданные().Реквизиты;
Для каждого КлючЗначение Из ОбязательныеПоля Цикл
ПутьКДанным = КлючЗначение.Ключ;
Значение = Вычислить("Объект." + ПутьКДанным);
Если Не ЗначениеЗаполнено(Значение) Тогда // надо ругаться
Если Не ЗначениеЗаполнено(КлючЗначение.Значение) Тогда
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПутьКДанным);
ИндексСтрокиТЧ = Неопределено;
Если Фрагменты.Количество() > 1 Тогда
ИндексСтрокиТЧ = ПолучитьСтрокуМеждуМаркерамиЛкс(Фрагменты[0], "[", "]", Ложь);
Если ЗначениеЗаполнено(ИндексСтрокиТЧ) Тогда
ИндексСтрокиТЧ = Число(ИндексСтрокиТЧ);
//ИмяТЧ = ПолучитьПервыйФрагментИис(Фрагменты[0], "[");
КонецЕсли;
КонецЕсли;
//ПредставлениеРеквизита = РеквизитыМД[КлючЗначение.Ключ].Представление();
ПредставлениеРеквизита = СокрЛП(Фрагменты[Фрагменты.ВГраница()]);
СтрокаСообщения = "Не заполнено значение реквизита """ + ПредставлениеРеквизита + """";
Если ЗначениеЗаполнено(ИндексСтрокиТЧ) Тогда
СтрокаСообщения = СтрокаСообщения + " в строке №" + Формат(ИндексСтрокиТЧ + 1, "ЧГ=");
КонецЕсли;
Иначе
СтрокаСообщения = КлючЗначение.Значение;
КонецЕсли;
Отказ = Истина;
Сообщить(СтрокаСообщения, СтатусСообщения.Внимание);
Результат = Ложь;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ОписанияТиповПересекаютсяЛкс(ОписаниеТипов1, ОписаниеТипов2, ИсключаяПримитивныеТипы = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов1 = Новый ОписаниеТипов;
ОписаниеТипов2 = Новый ОписаниеТипов;
#КонецЕсли
Для Каждого Тип Из ОписаниеТипов1.Типы() Цикл
Если Истина
И ИсключаяПримитивныеТипы
И (Ложь
Или Тип = Тип("Булево")
Или Тип = Тип("Строка")
Или Тип = Тип("Число")
Или Тип = Тип("Дата"))
Тогда
Продолжить;
КонецЕсли;
Если ОписаниеТипов2.СодержитТип(Тип) Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
// Проверяет, отвечает ли строка правилам формирования имен переменных встроенного языка.
//
// Параметры:
// Строка – Строка.
//
// Возвращаемое значение:
// Булево.
//
Функция ЛиИмяПеременнойЛкс(Строка) Экспорт
Если ПустаяСтрока(Строка) Тогда
Возврат Ложь;
КонецЕсли;
Пустышка = Новый Структура;
Попытка
Пустышка.Вставить(Строка);
Возврат Истина;
Исключение
Возврат Ложь;
КонецПопытки;
КонецФункции // ЛиИмяПеременнойЛкс()
// Пространство имен текущей конфигурации иис Возвращаемое значение:
//
Функция ПространствоИменТекущейКонфигурацииЛкс() Экспорт
Возврат "http://v8.1c.ru/8.1/data/enterprise/current-config";
КонецФункции
Функция БезопасноПолучитьЗначениеСвойстваЛкс(ЭлементФормы, Знач ИмяСвойстваЗаголовка) Экспорт
СтруктураЗначений = Новый Структура(ИмяСвойстваЗаголовка);
ЗаполнитьЗначенияСвойств(СтруктураЗначений, ЭлементФормы);
ЗаголовокЭлемента = СтруктураЗначений[ИмяСвойстваЗаголовка];
Возврат ЗаголовокЭлемента;
КонецФункции
Функция ВосстановитьТекущуюСтрокуТаблицыФормыЛкс(ТаблицаФормы, Знач КлючТекущейСтроки, ДанныеТаблицы = Неопределено, ИмяКлючевойКолонки = "Ссылка") Экспорт
Если КлючТекущейСтроки <> Неопределено Тогда
Если ДанныеТаблицы = Неопределено Тогда
ДанныеТаблицы = ТаблицаФормы.Значение;
КонецЕсли;
Если ТипЗнч(КлючТекущейСтроки) <> Тип("Структура") Тогда
КлючТекущейСтроки = Новый Структура(ИмяКлючевойКолонки, КлючТекущейСтроки);
КонецЕсли;
НайденныеСтроки = ДанныеТаблицы.НайтиСтроки(КлючТекущейСтроки);
Если НайденныеСтроки.Количество() > 0 Тогда
Строка = НайденныеСтроки[0];
Попытка
ИдентификаторСтроки = Строка.ПолучитьИдентификатор();
Исключение
ИдентификаторСтроки = Строка;
КонецПопытки;
ТаблицаФормы.ТекущаяСтрока = ИдентификаторСтроки;
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ПолучитьКлючТекущейСтрокиЛкс(ТаблицаФормы, ИмяКлючевойКолонки = "Ссылка") Экспорт
ТекущиеДанные = ТаблицаФормы.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
КлючТекущейСтроки = ТекущиеДанные[ИмяКлючевойКолонки];
КонецЕсли;
Возврат КлючТекущейСтроки;
КонецФункции