////////////////////////////////////////////////////////////////////////////////
// Подсистема "Инструменты разработчика"
// Авторское право (с) 2007-2020, Старых С.А.
// Разрешается повторное распространение и использование как в виде исходника так и в двоичной форме,
// с модификациями или без, при соблюдении следующих условий:
// - При повторном распространении исходного кода должно оставаться указанное выше уведомление об авторском
// праве, этот список условий и нижеследующий отказ от гарантий.
// - При повторном распространении двоичного кода должно воспроизводиться указанное выше уведомление об
// авторском праве, этот список условий и нижеследующий отказ от гарантий в документации и/или в других
// материалах, поставляемых при распространении.
//
// ЭТО ПРОГРАММА ПРЕДОСТАВЛЕНА БЕСПЛАТНО ДЕРЖАТЕЛЯМИ АВТОРСКИХ ПРАВ И/ИЛИ ДРУГИМИ СТОРОНАМИ "КАК ОНА ЕСТЬ"
// БЕЗ КАКОГО-ЛИБО ВИДА ГАРАНТИЙ, ВЫРАЖЕННЫХ ЯВНО ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ,
// ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ КОММЕРЧЕСКОЙ ЦЕННОСТИ И ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. НИ В КОЕМ СЛУЧАЕ,
// ЕСЛИ НЕ ТРЕБУЕТСЯ СООТВЕТСТВУЮЩИМ ЗАКОНОМ, ИЛИ НЕ УСТАНОВЛЕНО В УСТНОЙ ФОРМЕ, НИ ОДИН ДЕРЖАТЕЛЬ АВТОРСКИХ
// ПРАВ И НИ ОДНО ДРУГОЕ ЛИЦО, КОТОРОЕ МОЖЕТ ИЗМЕНЯТЬ И/ИЛИ ПОВТОРНО РАСПРОСТРАНЯТЬ ПРОГРАММУ, КАК БЫЛО
// РАЗРЕШЕНО ВЫШЕ, НЕ ОТВЕТСТВЕННЫ ПЕРЕД ВАМИ ЗА УБЫТКИ, ВКЛЮЧАЯ ЛЮБЫЕ ОБЩИЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ ИЛИ
// ПОСЛЕДОВАВШИЕ УБЫТКИ, ПРОИСТЕКАЮЩИЕ ИЗ ИСПОЛЬЗОВАНИЯ ИЛИ НЕВОЗМОЖНОСТИ ИСПОЛЬЗОВАНИЯ ПРОГРАММЫ (ВКЛЮЧАЯ,
// НО НЕ ОГРАНИЧИВАЯСЬ ПОТЕРЕЙ ДАННЫХ, ИЛИ ДАННЫМИ, СТАВШИМИ НЕПРАВИЛЬНЫМИ, ИЛИ ПОТЕРЯМИ ПРИНЕСЕННЫМИ ИЗ-ЗА
// ВАС ИЛИ ТРЕТЬИХ ЛИЦ, ИЛИ ОТКАЗОМ ПРОГРАММЫ РАБОТАТЬ СОВМЕСТНО С ДРУГИМИ ПРОГРАММАМИ), ДАЖЕ ЕСЛИ ТАКОЙ
// ДЕРЖАТЕЛЬ ИЛИ ДРУГОЕ ЛИЦОт БЫЛИ ИЗВЕЩЕНЫ О ВОЗМОЖНОСТИ ТАКИХ УБЫТКОВ.
//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирПривилегированный Экспорт;
////////////////////////////////////////////////////////////////////////////////
// ОТЛАДКА
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
// Присваивает первому параметру второй.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
//
// Параметры:
// П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Объект, HttpСоединение - открывает Запрос или ADODB.Command или ADODB.Connection в консоли запросов
// ПостроительЗапроса - открывает результирующий запрос построителя запросов в консоли запросов
// ПостроительОтчета - открывает построитель отчета в консоли построителей отчетов, откуда можно открыть результирующий запрос построителя отчета в консоли запросов
// СхемаКомпоновки - открывает схему компоновки в консоли компоновки данных, откуда можно открыть результирующие (из макета компоновки) запросы в консоли запросов
// МакетКомпоновкиДанных - открывает запросы макета компоновки в консоли запросов
// ОтчетОбъект - открывает схему и настройки компоновки отчета в консоли компоновки данных, откуда можно открыть результирующие (из макета компоновки) запросы в консоли запросов
// РегистрСведенийНаборЗаписей - открывает группировку таблицы набора записей по измерениям
//
// Параметры:
// Объект – Запрос, ПостроительЗапроса, ПостроительОтчета, СхемаКомпоновкиДанных, МакетКомпоновкиДанных, ОтчетОбъект, ADODB.Command, ADODB.Connection, HttpСоединение,
// РегистрСведенийНаборЗаписей, ДинамическийСписок, ТаблицаФормы - исследуемый объект;
// Модально – Булево - открывать окно модально, должно быть Истина для использования функции в отладчике;
// Объект2 - НастройкиКомпоновкиДанных, Строка, *Неопределено -
// если первый параметр СхемаКомпоновкиДанных, то настройки компоновки,
// если первый параметр WMI или ADODB.Connection, то текст запроса,
// если первый параметр HttpСоединение, то HttpЗапрос,
// если первый параметр Запрос, имена временных таблиц разделенных запятыми;
// ВнешниеНаборыДанных - Структура, *Неопределено - внешние наборы данных для схемы компоновки;
// ОтложеннаяОтладка - Булево - на сервере игнорируется (равно Истина), вместо открытия инструмента отладки сразу выполняется помещение
// объектов отладки во временное хранилище;
// ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки - Число, *500000 - допустимое количество строк во всех временных таблицах запроса
// для отложенной отладки, больше этого количества строки не сохраняются, о чем сообщается в результате;
// Наименование - Строка - наименование сохраняемого объекта отложенной отладки;
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОтладитьЛкс(Знач Объект, Модально = Ложь, Знач Объект2 = Неопределено, Знач ВнешниеНаборыДанных = Неопределено,
ОтложенноеВыполнение = Ложь, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки = 500000, выхОбъектДляОтладки = Неопределено, Наименование = "") Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольЗапросов) Тогда
Возврат СообщениеПользователюНетПраваИРЛкс();
КонецЕсли;
КонецЕсли;
#Если Не Клиент Тогда
ОтложенноеВыполнение = Истина;
#КонецЕсли
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ОтложенноеВыполнение = Истина;
КонецЕсли;
#КонецЕсли
ТребоватьТипЛкс(Модально, "Модально", Тип("Булево"));
ТребоватьТипЛкс(ОтложенноеВыполнение, "ОтложенноеВыполнение", Тип("Булево"));
ТребоватьТипЛкс(ВнешниеНаборыДанных, "ВнешниеНаборыДанных", Тип("Неопределено"), Тип("Структура"));
ТребоватьТипЛкс(Объект2, "Объект2", Тип("Неопределено"), Тип("Строка"),
Тип("НастройкиКомпоновкиДанных"), Тип("HTTPЗапрос"));
Если Не ОтложенноеВыполнение Тогда
#Если Клиент Тогда
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(Объект));
Если Ложь
Или ТипЗнч(Объект) = Тип("Запрос")
Или ТипЗнч(Объект) = Тип("COMОбъект")
Тогда
КонсольЗапросов = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
Результат = КонсольЗапросов.ОткрытьДляОтладки(Объект, , , Модально, Объект2);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительЗапроса") Тогда
КонсольЗапросов = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
Результат = КонсольЗапросов.ОткрытьДляОтладки(Объект.ПолучитьЗапрос(), , , Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительОтчета") Тогда
КонсольПостроителейОтчетов = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольПостроителейОтчетов");
#Если Сервер И Не Сервер Тогда
КонсольПостроителейОтчетов = Обработки.ирКонсольПостроителейОтчетов.Создать();
#КонецЕсли
Результат = КонсольПостроителейОтчетов.ОткрытьДляОтладки(Объект, Модально);
ИначеЕсли Ложь
Или ТипЗнч(Объект) = Тип("СхемаКомпоновкиДанных")
Или ТипЗнч(Объект) = Тип("МакетКомпоновкиДанных")
Тогда
КонсольКомпоновкиДанных = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольКомпоновокДанных");
#Если Сервер И Не Сервер Тогда
КонсольКомпоновкиДанных = Обработки.ирКонсольКомпоновокДанных.Создать();
#КонецЕсли
Результат = КонсольКомпоновкиДанных.ОткрытьДляОтладки(Объект, Объект2, ВнешниеНаборыДанных, Модально);
ИначеЕсли Истина
И ОбъектМД <> Неопределено
И Метаданные.Отчеты.Индекс(ОбъектМД) <> -1
Тогда
КонсольКомпоновкиДанных = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольКомпоновокДанных");
#Если Сервер И Не Сервер Тогда
КонсольКомпоновкиДанных = Обработки.ирКонсольКомпоновокДанных.Создать();
Объект = КонсольКомпоновкиДанных;
#КонецЕсли
Если Объект.СхемаКомпоновкиДанных = Неопределено Тогда
Возврат "У отчета не установлена схема компоновки данных";
КонецЕсли;
Результат = КонсольКомпоновкиДанных.ОткрытьДляОтладки(Объект.СхемаКомпоновкиДанных, Объект.КомпоновщикНастроек.ПолучитьНастройки(), ВнешниеНаборыДанных, Модально);
ИначеЕсли Истина
И ОбъектМД <> Неопределено
И Метаданные.РегистрыСведений.Индекс(ОбъектМД) <> -1
Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
Объект = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаРедактирования = мПлатформа.ПолучитьФорму("ТаблицаЗначений");
ФормаРедактирования.НачальноеЗначениеВыбора = Объект.Выгрузить();
ФормаРедактирования.Открыть();
ОткрытьГруппировкуТабличногоПоляЛкс(ФормаРедактирования.ЭлементыФормы.ПолеТаблицы,, СтрСоединитьЛкс(ЗначенияСвойстваКоллекцииЛкс(Объект.Метаданные().Измерения)));
ИначеЕсли ТипЗнч(Объект) = Тип("HTTPСоединение") Тогда
КонсольHttpЗапросов = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольHttpЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольHttpЗапросов = Обработки.ирКонсольHttpЗапросов.Создать();
#КонецЕсли
Результат = КонсольHttpЗапросов.ОткрытьДляОтладки(Объект, Объект2, Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("ДинамическийСписок") Тогда
Возврат "Отладка динамического списка доступна только на сервере";
Иначе
//Возврат "Не поддерживаемый тип """ + ТипЗнч(Объект) + """ первого параметра";
ИсЛкс(Объект,, ОтложенноеВыполнение);
КонецЕсли;
#КонецЕсли
Иначе
СтруктураПараметров = СтруктураОбъектаДляОтладкиЛкс(Объект, Объект2, ВнешниеНаборыДанных, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки);
Если СтруктураПараметров.Объект <> Неопределено Тогда
Результат = ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки, Наименование);
Иначе
Результат = ИсЛкс(Объект,, ОтложенноеВыполнение);
Если Результат = Неопределено Тогда
Результат = "Отложенная отладка объекта типа """ + ТипЗнч(Объект) + """ не поддерживается";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СтруктураОбъектаДляОтладкиЛкс(Знач Объект, Знач Объект2, Знач ВнешниеНаборыДанных, Знач ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки = 500000) Экспорт
ТребоватьТипЛкс(ВнешниеНаборыДанных, "ВнешниеНаборыДанных", Тип("Неопределено"), Тип("Структура"));
ТребоватьТипЛкс(Объект2, "НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц", Тип("Неопределено"), Тип("Строка"), Тип("НастройкиКомпоновкиДанных"), Тип("HTTPЗапрос"));
СтруктураПараметров = Новый Структура("Объект, НастройкаКомпоновки, ВнешниеНаборыДанных, ТипОбъекта");
Результат = Неопределено;
Если ТипЗнч(Объект) = Тип("Запрос") Тогда
#Если Сервер И Не Сервер Тогда
Объект = Новый Запрос;
#КонецЕсли
СтруктураЗапроса = Новый Структура("Текст, Параметры, ВременныеТаблицы, ТипЗапроса");
ВременныеТаблицы = Неопределено;
Если Объект.МенеджерВременныхТаблиц <> Неопределено Тогда
ВременныеТаблицы = ПолВТЛкс(Объект, Объект2, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки);
Результат = "";
Для Каждого КлючИЗначение Из ВременныеТаблицы Цикл
Если Результат <> "" Тогда
Результат = Результат + ", ";
КонецЕсли;
Если КлючИЗначение.Значение.Количество() = ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки Тогда
Результат = Результат + КлючИЗначение.Ключ;
КонецЕсли;
КонецЦикла;
Если Результат <> "" Тогда
Результат = "Временные таблицы " + Результат + " были сохранены частично!";
КонецЕсли;
СтруктураЗапроса.ВременныеТаблицы = ВременныеТаблицы;
КонецЕсли;
СтруктураЗапроса.Текст = Объект.Текст;
СтруктураЗапроса.ТипЗапроса = "Обычный";
СтруктураЗапроса.Параметры = ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(Объект.Параметры);
СтруктураПараметров.Объект = СтруктураЗапроса;
СтруктураПараметров.ТипОбъекта = "Запрос";
ИначеЕсли ТипЗнч(Объект) = Тип("COMОбъект") Тогда
Попытка
Пустышка = Объект.CommandText;
ЭтоКомандаADO = Истина;
Исключение
ЭтоКомандаADO = Ложь;
Попытка
Пустышка = Объект.ConnectionString;
ЭтоСоединениеADO = Истина;
Исключение
ЭтоСоединениеADO = Ложь;
КонецПопытки;
КонецПопытки;
СтруктураЗапроса = Новый Структура("Текст, Параметры, ВременныеТаблицы, ТипЗапроса");
Если Ложь
Или ЭтоКомандаADO
Или ЭтоСоединениеADO
Тогда
Если ЭтоСоединениеADO Тогда
СтруктураЗапроса.Текст = Объект2;
Иначе
СтруктураЗапроса.Текст = Объект.CommandText;
// Антибаг платформы 8.2.18. Некорректная сериализация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СтруктураЗапроса.Параметры = КопияОбъектаЛкс(Объект.Параметры);
СтруктураЗапроса.Параметры = Новый Структура();
Для Каждого Parameter Из Объект.Parameters Цикл
КлючПараметра = Parameter.Name;
Если Не ЛиИмяПеременнойЛкс(КлючПараметра) Тогда
КлючПараметра = "_" + КлючПараметра;
КонецЕсли;
Если Не ЛиИмяПеременнойЛкс(КлючПараметра) Тогда
КлючПараметра = КлючПараметра + XMLСтрока(СтруктураЗапроса.Параметры.Количество());
КонецЕсли;
Если СтруктураЗапроса.Параметры.Свойство(КлючПараметра) Тогда
ВызватьИсключение "Не удалось назначить параметру уникальное имя";
КонецЕсли;
СтруктураЗапроса.Параметры.Вставить(КлючПараметра, ЗначениеВСтрокуВнутр(Parameter.Value));
КонецЦикла;
КонецЕсли;
СтруктураЗапроса.ТипЗапроса = "ADO";
//ВременныеТаблицы = Неопределено;
//ВременныеТаблицы = ПолВТ(Объект, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки);
//Результат = "";
//Для Каждого КлючИЗначение Из ВременныеТаблицы Цикл
// Если Результат <> "" Тогда
// Результат = Результат + ", ";
// КонецЕсли;
// Если КлючИЗначение.Значение.Количество() = ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки Тогда
// Результат = Результат + КлючИЗначение.Ключ;
// КонецЕсли;
//КонецЦикла;
//Если Результат <> "" Тогда
// Результат = Результат + Символы.ПС + "Временные таблицы " + Результат + " были сохранены частично!";
//КонецЕсли;
//СтруктураЗапроса.ВременныеТаблицы = ВременныеТаблицы;
СтруктураПараметров.Объект = СтруктураЗапроса;
Иначе
СтруктураЗапроса.ТипЗапроса = "WQL";
СтруктураЗапроса.Текст = Объект2;
КонецЕсли;
СтруктураПараметров.ТипОбъекта = "COMОбъект";
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительЗапроса") Тогда
СтруктураЗапроса = Новый Структура("Текст, Параметры");
ЗаполнитьЗначенияСвойств(СтруктураЗапроса, Объект.ПолучитьЗапрос());
СтруктураЗапроса.Параметры = ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(СтруктураЗапроса.Параметры);
СтруктураПараметров.Объект = СтруктураЗапроса;
СтруктураПараметров.ТипОбъекта = "Запрос";
ИначеЕсли ТипЗнч(Объект) = Тип("МакетКомпоновкиДанных") Тогда
СтруктураПараметров.Вставить("Объект", Объект);
СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных);
СтруктураПараметров.ТипОбъекта = "МакетКомпоновкиДанных";
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительОтчета") Тогда
Результат = "Отложенная отладка построителя отчета не поддерживается";
ИначеЕсли ТипЗнч(Объект) = Тип("СхемаКомпоновкиДанных") Тогда
СтруктураПараметров.Вставить("Объект", Объект);
СтруктураПараметров.Вставить("НастройкаКомпоновки", Объект2);
СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных);
СтруктураПараметров.ТипОбъекта = "СхемаКомпоновкиДанных";
ИначеЕсли ТипЗнч(Объект) = Тип("HTTPСоединение") Тогда
#Если Сервер И Не Сервер Тогда
Объект = Новый HttpСоединение;
#КонецЕсли
ИменаСвойств = "Сервер, Порт, Пользователь, Пароль, Таймаут, Защищенное, ИспользоватьАутентификациюОС";
СтруктураСоединения = Новый Структура(ИменаСвойств);
ЗаполнитьЗначенияСвойств(СтруктураСоединения, Объект, ИменаСвойств);
Если ТипЗнч(Объект2) = Тип("HTTPЗапрос") Тогда
#Если Сервер И Не Сервер Тогда
Объект2 = Новый HTTPЗапрос;
#КонецЕсли
ИменаСвойств = "АдресРесурса, Заголовки";
СтруктураЗапроса = Новый Структура(ИменаСвойств);
ЗаполнитьЗначенияСвойств(СтруктураЗапроса, Объект2, ИменаСвойств);
СтруктураЗапроса.Вставить("ТелоДвоичныеДанные", Объект2.ПолучитьТелоКакДвоичныеДанные());
КонецЕсли;
СтруктураПараметров.Вставить("Объект", СтруктураСоединения);
СтруктураПараметров.Вставить("НастройкаКомпоновки", СтруктураЗапроса);
СтруктураПараметров.ТипОбъекта = "HttpСоединение";
ИначеЕсли ТипЗнч(Объект) = Тип("ДинамическийСписок") Тогда
#Если Не Сервер Тогда
Возврат "Отладка динамического списка доступна только на сервере";
#КонецЕсли
НастройкаКомпоновки = Неопределено;
Схема = Неопределено;
ПолучитьСхемуИНастройкиКомпоновкиДинамическогоСпискаЛкс(Объект, НастройкаКомпоновки, Схема);
СтруктураПараметров.Вставить("Объект", Схема);
СтруктураПараметров.Вставить("НастройкаКомпоновки", НастройкаКомпоновки);
СтруктураПараметров.ТипОбъекта = "СхемаКомпоновкиДанных";
ИначеЕсли ТипЗнч(Объект) = Тип("ТаблицаФормы") Тогда
#Если Не Сервер Тогда
Возврат "Отладка динамического списка доступна только на сервере";
#КонецЕсли
Схема = Объект.ПолучитьИсполняемуюСхемуКомпоновкиДанных();
НастройкаКомпоновки = Объект.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();
СтруктураПараметров.Вставить("Объект", Схема);
СтруктураПараметров.Вставить("НастройкаКомпоновки", НастройкаКомпоновки);
СтруктураПараметров.ТипОбъекта = "СхемаКомпоновкиДанных";
Иначе
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(Объект));
Если ОбъектМД <> Неопределено Тогда
Если Метаданные.Отчеты.Индекс(ОбъектМД) <> -1 Тогда
Если Объект.СхемаКомпоновкиДанных = Неопределено Тогда
Возврат "У отчета не установлена схема компоновки данных";
Иначе
СтруктураПараметров.Вставить("Объект", Объект.СхемаКомпоновкиДанных);
СтруктураПараметров.Вставить("НастройкаКомпоновки", Объект.КомпоновщикНастроек.ПолучитьНастройки());
СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных);
СтруктураПараметров.ТипОбъекта = "СхемаКомпоновкиДанных";
КонецЕсли;
ИначеЕсли Метаданные.РегистрыСведений.Индекс(ОбъектМД) <> -1 Тогда
СтруктураПараметров.Вставить("Объект", Объект);
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтруктураПараметров.Вставить("ТипОперации", "Отладить");
СтруктураПараметров.Вставить("ИмяПользователя", ИмяПользователя());
Возврат СтруктураПараметров;
КонецФункции
Функция СнимокОбъектаДляОтладкиЛкс(Знач Объект, Знач Объект2 = Неопределено, Знач ВнешниеНаборыДанных = Неопределено,
Знач ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки = 500000) Экспорт
СтруктураПараметров = СтруктураОбъектаДляОтладкиЛкс(Объект, Объект2, ВнешниеНаборыДанных, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки);
Результат = СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров);
Возврат Результат;
КонецФункции
// Обертка ирОбщий.ОтладитьЛкс(). Модально (на клиенте) или отложенно (на сервере) открывает нужную консоль для редактирования/отладки объекта.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
Функция ОтЛкс(Знач Объект, Знач Объект2 = Неопределено, Знач ВнешниеНаборыДанных = Неопределено, ОтложеннаяОтладка = Ложь, Наименование = "") Экспорт
Результат = ОтладитьЛкс(Объект, Истина, Объект2, ВнешниеНаборыДанных, ОтложеннаяОтладка,,, Наименование);
Возврат Результат;
КонецФункции
// Открывает исследователь объектов.
//
// Параметры:
// Объект – Произвольный, *Неопределено - объект, который будет исследован;
// Модально – Булево - открывать окно модально;
// КакКоллекцию – Булево, *Ложь - исследовать как коллекцию вместо объекта.
//
// Возвращаемое значение:
// Сам объект.
//
Функция ИсследоватьЛкс(Знач Объект = Неопределено, Модально = Ложь, КакКоллекцию = Ложь, ОтложенноеВыполнение = Ложь, ТекущееВыражение = Неопределено) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирИсследовательОбъектов) Тогда
Возврат СообщениеПользователюНетПраваИРЛкс();
КонецЕсли;
КонецЕсли;
#Если Не Клиент Тогда
ОтложенноеВыполнение = Истина;
#КонецЕсли
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ОтложенноеВыполнение = Истина;
КонецЕсли;
#КонецЕсли
ТребоватьТипЛкс(Модально, "Модально", Тип("Булево"));
ТребоватьТипЛкс(КакКоллекцию, "КакКоллекцию", Тип("Булево"));
ТребоватьТипЛкс(ОтложенноеВыполнение, "ОтложенноеВыполнение", Тип("Булево"));
Если Не ОтложенноеВыполнение Тогда
ИсследовательОбъектов = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИсследовательОбъектов");
#Если Сервер И Не Сервер Тогда
ИсследовательОбъектов = Обработки.ирИсследовательОбъектов.Создать();
#КонецЕсли
Если КакКоллекцию Тогда
Результат = ИсследовательОбъектов.ИсследоватьКоллекцию(Объект, Модально);
Иначе
Результат = ИсследовательОбъектов.ИсследоватьОбъект(Объект, Модально, ТекущееВыражение);
КонецЕсли;
Если Результат <> Неопределено Тогда
Объект = Результат;
КонецЕсли;
Иначе
Если ТипЗнч(Объект) = Тип("ДанныеФормыДерево") Тогда
Объект = ДанныеФормыВЗначение(Объект, Тип("ДеревоЗначений"));
ИначеЕсли ТипЗнч(Объект) = Тип("ДанныеФормыКоллекция") Тогда
Объект = ДанныеФормыВЗначение(Объект, Тип("ТаблицаЗначений"));
КонецЕсли;
СтруктураПараметров = Новый Структура("Объект, Модально, КакКоллекцию, СериализацияФабрикой", , Модально, КакКоллекцию, Ложь);
Наименование = "" + Объект;
Если Истина
И ТипЗнч(Объект) <> Тип("ОбъектXDTO")
И ТипЗнч(Объект) <> Тип("ЗначениеXDTO")
Тогда
Попытка
ОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(СтруктураПараметров);
Исключение
ОбъектXDTO = Неопределено;
КонецПопытки;
Иначе
СтруктураПараметров.СериализацияФабрикой = Истина;
Попытка
Объект = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
Исключение
Объект = Неопределено;
КонецПопытки;
ОбъектXDTO = Объект;
КонецЕсли;
Если ОбъектXDTO <> Неопределено Тогда
СтруктураПараметров.Вставить("ТипОперации", "Исследовать");
СтруктураПараметров.Вставить("Объект", Объект);
выхОбъектДляОтладки = Неопределено;
Результат = ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки, Наименование);
Иначе
Результат = "Отложенная отладка объекта такого типа не поддерживается";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // Исследовать()
// Обертка Исследовать. Модально открывает объект в исследователе объектов
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
Функция ИсЛкс(Знач Объект = Неопределено, КакКоллекцию = Ложь, ОтложенноеВыполнение = Ложь) Экспорт
Возврат ИсследоватьЛкс(Объект, Истина, КакКоллекцию, ОтложенноеВыполнение);
КонецФункции // Ис()
// Возвращает текст из файла
Функция ФайлЛкс(Знач ИмяФайла, Знач Кодировка = "") Экспорт
Текст = Новый ТекстовыйДокумент;
Попытка
Текст.Прочитать(ИмяФайла, Кодировка);
Результат = Текст.ПолучитьТекст();
Исключение
Результат = ОписаниеОшибки();
КонецПопытки;
Возврат Результат;
КонецФункции
// Удаляет все элементы коллекции с возможностью оставить один элемент.
// Параметры:
// ОставитьЭлементИлиИндекс - Число, Строка, *Неопределено - при Число Или Строка оставляется элемент с таким ключом (0 - первый), иначе удаляется все
Функция СокрКолЛкс(Коллекция, ОставитьЭлементИлиКлюч = Неопределено) Экспорт
Если Ложь
Или ТипЗнч(ОставитьЭлементИлиКлюч) = Тип("Число")
Или ТипЗнч(ОставитьЭлементИлиКлюч) = Тип("Строка")
Тогда
Если ОставитьЭлементИлиКлюч = 0 Тогда
ОставитьЭлемент = "<Первый>";
Иначе
ОставитьЭлемент = Коллекция[ОставитьЭлементИлиКлюч];
КонецЕсли;
Иначе
Попытка
Коллекция.Очистить();
Возврат Истина;
Исключение
ОставитьЭлемент = Неопределено;
КонецПопытки;
КонецЕсли;
МассивКУдалению = Новый Массив;
Для Каждого Элемент Из Коллекция Цикл
Если ОставитьЭлемент = "<Первый>" Или ОставитьЭлемент = Элемент Тогда
ОставитьЭлемент = Элемент;
Продолжить;
КонецЕсли;
Если Ложь
Или ТипЗнч(Коллекция) = Тип("Структура")
Или ТипЗнч(Коллекция) = Тип("Соответствие")
Тогда
МассивКУдалению.Добавить(Элемент.Ключ);
Иначе
МассивКУдалению.Добавить(Элемент);
КонецЕсли;
КонецЦикла;
Для Каждого УдаляемыйЭлемент Из МассивКУдалению Цикл
Коллекция.Удалить(УдаляемыйЭлемент);
КонецЦикла;
КонецФункции
// Проверяет что переданное значение отличается от предыдущего переданного с тем же именем.
// Полезно использовать в условных точках останова например для остановки в том проходе цикла, в котором изменяется значение выражения.
// https://www.hostedredmine.com/issues/892539
// Параметры:
// Значение - Произвольный - проверяемое значение. Все типы, кроме ссылок БД, преобразуются к строке через функцию РасширенноеПредставлениеЗначенияЛкс(), которая также используется при отображении значений в консоли кода.
// ИмяЗначения - Строка, Число, *"" - имя/идентификатор значения
// НужноеСтароеЗначение - Произвольный, * - игнорировать все старые значения кроме этого
// НужноеНовоеЗначение - Произвольный, * - игнорировать все новые значения кроме этого
// Результат:
// Булево - Истина, если значение изменилось
Функция ИзмЛкс(Знач Значение, Знач ИмяЗначения = "", Знач НужноеСтароеЗначение = "фйъх13м9", Знач НужноеНовоеЗначение = "фйъх13м9") Экспорт
ИмяЗначения = "_" + XMLСтрока(ИмяЗначения);
СтруктураСтарыхЗначений = ирКэш.ЗначенияДляПроверкиИзмененияЛкс();
Если Не ЛиСсылкаНаОбъектБДЛкс(Значение, Ложь) Тогда
Значение = Лев(РасширенноеПредставлениеЗначенияЛкс(Значение), 1000); // Чтобы избежать залипания в кэше больших объектов
КонецЕсли;
Если СтруктураСтарыхЗначений.Свойство(ИмяЗначения) Тогда
СтароеЗначение = СтруктураСтарыхЗначений[ИмяЗначения];
Результат = СтароеЗначение <> Значение;
Иначе
Результат = Ложь;
КонецЕсли;
СтруктураСтарыхЗначений.Вставить(ИмяЗначения, Значение);
Если Результат Тогда
Если НужноеСтароеЗначение <> "фйъх13м9" Тогда
Если Не ЛиСсылкаНаОбъектБДЛкс(НужноеСтароеЗначение, Ложь) Тогда
НужноеСтароеЗначение = Лев(РасширенноеПредставлениеЗначенияЛкс(НужноеСтароеЗначение), 1000);
КонецЕсли;
Если НужноеСтароеЗначение <> СтароеЗначение Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
Если НужноеНовоеЗначение <> "фйъх13м9" Тогда
Если Не ЛиСсылкаНаОбъектБДЛкс(НужноеНовоеЗначение, Ложь) Тогда
НужноеНовоеЗначение = Лев(РасширенноеПредставлениеЗначенияЛкс(НужноеНовоеЗначение), 1000);
КонецЕсли;
Если НужноеНовоеЗначение <> Значение Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
#КонецЕсли
// ОТЛАДКА
////////////////////////////////////////////////////////////////////////////////
Функция НомерВерсииПлатформыЛкс(Знач СтрокаВерсии, Знач ВключаяНомерСборки = Ложь) Экспорт
Фрагменты = ирОбщий.СтрРазделитьЛкс(СтрокаВерсии);
#Если Сервер И Не Сервер Тогда
Фрагменты = Новый Массив;
#КонецЕсли
Для Счетчик = Фрагменты.Количество() По 4 Цикл
Фрагменты.Добавить("0");
КонецЦикла;
Результат = Число(Фрагменты[0]) * 100 * 1000 + Число(Фрагменты[1]) * 1000 + Число(Фрагменты[2]); // 6 цифр
Если ВключаяНомерСборки Тогда
Результат = Результат * 10000 + Число(Фрагменты[3]); // 10 цифр
КонецЕсли;
Возврат Результат;
КонецФункции
Функция АдресОсновногоСайтаЛкс() Экспорт
Возврат "devtool1c.ucoz.ru";
КонецФункции
Функция АдресСайтаЗадачЛкс() Экспорт
Возврат "https://www.hostedredmine.com/projects/devtool1c";
КонецФункции
Функция СообщениеПользователюНетПраваИРЛкс() Экспорт
Возврат "Нет права использования функции. Добавьте пользователю """ + ИмяПользователя() + """ роль из подсистемы ""Инструменты разработчика"".";
КонецФункции // РП()
// Выполняет текст алгоритма. Возращается результат через переменную "Результат".
//
// Параметры:
// ТекстДляВыполнения – Строка;
// _АлгоритмОбъект - СправочникОбъект
// *СтруктураПараметров - Структура, *Неопределено.
//
Функция ВыполнитьАлгоритм(_ТекстДляВыполнения, _АлгоритмОбъект = Null, _Режим = Null,
_П0 = Null, _П1 = Null, _П2 = Null, _П3 = Null, _П4 = Null, _П5 = Null, _П6 = Null, _П7 = Null, _П8 = Null, _П9 = Null) Экспорт
Перем Результат;
Выполнить(_ТекстДляВыполнения);
Возврат Результат;
КонецФункции
Процедура ВыполнитьАлгоритмБезРезультата(_ТекстДляВыполнения) Экспорт
Выполнить(_ТекстДляВыполнения);
КонецПроцедуры
Процедура ВыполнитьАлгоритмВКонтекстеЛкс(ТекстДляВыполнения, СтруктураПараметров, НаСервере = Ложь, ЧерезВнешнююОбработку = Ложь, ИмяФайлаВнешнейОбработки = "",
ЛиСинтаксическийКонтроль = Ложь, ВремяНачала = Неопределено, АдресПараметровВыхода = Неопределено, Знач ВерсияАлгоритма = Неопределено) Экспорт
#Если Сервер И Не Клиент Тогда
КонтекстВыполнения = ирОбщий;
#Иначе
Если НаСервере Тогда
КонтекстВыполнения = ирСервер;
Иначе
КонтекстВыполнения = ирОбщий;
КонецЕсли;
#КонецЕсли
Если Истина
И Не ЛиСинтаксическийКонтроль
И ЧерезВнешнююОбработку
Тогда
КонтекстВыполнения.ВыполнитьАлгоритмЧерезВнешнююОбработкуЛкс(ИмяФайлаВнешнейОбработки, СтруктураПараметров, ВремяНачала, ВерсияАлгоритма);
Иначе
ВремяНачала = ирОбщий.ТекущееВремяВМиллисекундахЛкс();
КонтекстВыполнения.ВыполнитьАлгоритм(ТекстДляВыполнения, СтруктураПараметров);
КонецЕсли;
Если ЗначениеЗаполнено(АдресПараметровВыхода) Тогда
СтруктураПараметров.Вставить("Служебный_ВремяНачала", ВремяНачала);
ПоместитьВоВременноеХранилище(СтруктураПараметров, АдресПараметровВыхода);
КонецЕсли;
КонецПроцедуры
Функция ВычислитьВыражение(Выражение9124327783, Параметры = Неопределено, НаСервере9124327783 = Ложь) Экспорт
// Здесь должен быть максимально чистый контекст выполнения
Если НаСервере9124327783 Тогда
Результат9124327783 = ирСервер.ВычислитьВыражение(Выражение9124327783, Параметры);
Иначе
Если Параметры = Неопределено Тогда
Результат9124327783 = ВычислитьВыражениеБезПараметровЛкс(Выражение9124327783);
Иначе
Результат9124327783 = Вычислить(Выражение9124327783);
КонецЕсли;
КонецЕсли;
Возврат Результат9124327783;
КонецФункции
Функция ВычислитьВыражениеБезПараметровЛкс(Выражение9124327783) Экспорт
Возврат Вычислить(Выражение9124327783);
КонецФункции
Функция ПолучитьПриглашениеОткрытьОтладчикЛкс() Экспорт
Возврат "Если нет кнопки ""Подробно"", разрешите отладку. Нажмите кнопку ""Подробно"", а затем ""Конфигуратор"", чтобы начать отладку!";
КонецФункции
Процедура ОткрытьОтладчикЛкс() Экспорт
#Если ВебКлиент Тогда
СообщитьЛкс("Команда недоступна в вебклиенте");
#Иначе
ВызватьИсключение ПолучитьПриглашениеОткрытьОтладчикЛкс();
#КонецЕсли
КонецПроцедуры
Процедура ПерейтиКОпределениюМетодаВКонфигуратореЛкс(Знач СтрокаВызоваМетодаБезСкобок) Экспорт
ТекстМодуля = СтрокаВызоваМетодаБезСкобок + "();";
ИмяВнешнейОбработки = "ПереходВКонфигураторе." + СтрокаВызоваМетодаБезСкобок;
ИмяФайла = КаталогВременныхФайлов() + ИмяВнешнейОбработки + ".epf";
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФайлВнешнейОбработки = Новый Файл(ИмяФайла);
мПлатформа.СформироватьВнешнююОбработку(ФайлВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля);
мПлатформа.ОткрытьМодульВнешнейОбработкиВОтладчике(ИмяФайла, 1,, Истина );
КонецПроцедуры
Процедура ПерейтиКОбъектуМетаданныхВКонфигуратореЛкс(Знач ПолноеИмя) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ТекстМодуля = ПолноеИмяМДЕдинственноеВМножественноеЛкс(ПолноеИмя);
Если Не ЗначениеЗаполнено(ТекстМодуля) Тогда
Возврат;
КонецЕсли;
ИмяВнешнейОбработки = "ПереходВКонфигураторе." + ПолноеИмя;
ИмяФайла = КаталогВременныхФайлов() + ИмяВнешнейОбработки + ".epf";
ФайлВнешнейОбработки = Новый Файл(ИмяФайла);
мПлатформа.СформироватьВнешнююОбработку(ФайлВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля);
мПлатформа.ОткрытьМодульВнешнейОбработкиВОтладчике(ИмяФайла, 1,, Истина );
КонецПроцедуры
// Параметры:
// ПолноеИмя - ? -
// ТекстМодуля - ? -
// ТипВыхода - Строка - Служебный параметр для перехода после вызова метода
Функция ПолноеИмяМДЕдинственноеВМножественноеЛкс(ПолноеИмя) Экспорт
Фрагменты = СтрРазделитьЛкс(ПолноеИмя);
#Если Сервер И Не Сервер Тогда
Фрагменты = Новый Массив;
#КонецЕсли
Для Счетчик = 1 По Фрагменты.Количество() / 2 Цикл
Индекс = (Счетчик - 1) * 2;
МножественноеИмяМД = ирОбщий.МножественноеИмяМДЛкс(Фрагменты[Индекс]);
Если МножественноеИмяМД = Неопределено Тогда
Для ИндексОстатка = Индекс По Фрагменты.ВГраница() Цикл
Фрагменты.Удалить(Индекс);
КонецЦикла;
Прервать;
КонецЕсли;
Фрагменты[Индекс] = МножественноеИмяМД;
КонецЦикла;
ТекстМодуля = СтрСоединитьЛкс(Фрагменты, ".");
Возврат ТекстМодуля;
КонецФункции
Функция ПолучитьОписаниеТиповОдногоТипаИзОписанияТиповЛкс(Тип, ОписаниеТипов) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов = Новый ОписаниеТипов;
#КонецЕсли
Массив = Новый Массив;
Массив.Добавить(Тип);
Результат = Новый ОписаниеТипов(Массив, ОписаниеТипов.КвалификаторыЧисла, ОписаниеТипов.КвалификаторыСтроки, ОписаниеТипов.КвалификаторыДаты, ОписаниеТипов.КвалификаторыДвоичныхДанных);
Возврат Результат;
КонецФункции
Функция ЭтоИмяЛокальногоКомпьютераЛкс(ИмяКомпьютера) Экспорт
Результат = Ложь
Или Не ЗначениеЗаполнено(ИмяКомпьютера)
Или ИмяКомпьютера = "."
Или СтрокиРавныЛкс(ИмяКомпьютера, "localhost")
Или ИмяКомпьютера = "127.0.0.1"
#Если Не ВебКлиент Тогда
Или СтрокиРавныЛкс(ИмяКомпьютера, ИмяКомпьютера())
#КонецЕсли
;
Возврат Результат;
КонецФункции
Функция ИмяКомпьютераКластераЛкс() Экспорт
Результат = ирОбщий.ПервыйФрагментЛкс(НСтр(СтрокаСоединенияИнформационнойБазы(), "Srvr"), ":");
Возврат Результат;
КонецФункции
Процедура ТребоватьТипЛкс(Значение, ИмяПараметра = "", Тип1, Тип2 = Неопределено, Тип3 = Неопределено, Тип4 = Неопределено, Тип5 = Неопределено, Тип6 = Неопределено) Экспорт
ТипЗначения = ТипЗнч(Значение);
Если Ложь
Или ТипЗначения = Тип1
Или ТипЗначения = Тип2
Или ТипЗначения = Тип3
Или ТипЗначения = Тип4
Или ТипЗначения = Тип5
Или ТипЗначения = Тип6
Тогда
Возврат;
КонецЕсли;
Массив = Новый Массив;
Массив.Добавить(Тип1);
Массив.Добавить(Тип2);
Массив.Добавить(Тип3);
Массив.Добавить(Тип4);
Массив.Добавить(Тип5);
Массив.Добавить(Тип6);
СтрокаТипов = "";
Для Каждого Тип Из Массив Цикл
Если ТипЗначения = Тип Тогда
Возврат;
КонецЕсли;
Если Тип = Неопределено Тогда
Прервать;
КонецЕсли;
Если СтрокаТипов <> "" Тогда
СтрокаТипов = СтрокаТипов + ", ";
КонецЕсли;
СтрокаТипов = СтрокаТипов + Тип;
КонецЦикла;
Текст = "";
Если ЗначениеЗаполнено(ИмяПараметра) Тогда
Текст = Текст + "Для параметра """ + ИмяПараметра + """ ";
КонецЕсли;
Текст = Текст + "Получено значение типа """ + ТипЗначения + """ вместо ожидаемых типов: " + СтрокаТипов + ".";
ВызватьИсключение Текст;
КонецПроцедуры
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
Функция ЗагрузитьЗначениеИзФайлаЛкс(Знач ПолноеИмяФайла, Знач Сжатие = Ложь) Экспорт
Если Сжатие Тогда
ВременныйКаталог = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ВременныйКаталог);
ЗипЧтение = Новый ЧтениеZipФайла(ПолноеИмяФайла);
ЗипЧтение.ИзвлечьВсе(ВременныйКаталог);
ПолноеИмяФайла = ВременныйКаталог + "\" + ЗипЧтение.Элементы[0].Имя;
КонецЕсли;
ЧтениеХМЛ = Новый ЧтениеXML;
ЧтениеХМЛ.ОткрытьФайл(ПолноеИмяФайла);
Попытка
//Результат = ЗначениеИзФайла(ВыборФайла.ПолноеИмяФайла);
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеХМЛ);
Исключение
СообщитьЛкс(ОписаниеОшибки());
Результат = Неопределено;
КонецПопытки;
ЧтениеХМЛ.Закрыть();
Если Сжатие Тогда
УдалитьФайлы(ВременныйКаталог, "*");
КонецЕсли;
Если ТипЗнч(Результат) = Тип("Структура") И Результат.Свойство("ВложенноеНесериализуемоеЗначение") Тогда
Результат = Результат.ВложенноеНесериализуемоеЗначение.Получить();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СохранитьЗначениеВФайлЛкс(Знач Значение, Знач ПолноеИмяФайла, Сжатие = Ложь, УровеньСжатия = Неопределено) Экспорт
ЗаписьХМЛ = Новый ЗаписьXML;
ЗаписьХМЛ.ОткрытьФайл(ПолноеИмяФайла);
Результат = Истина;
Попытка
//ЗначениеВФайл(ПолноеИмяФайла, Значение);
СериализаторXDTO.ЗаписатьXML(ЗаписьХМЛ, Значение);
Исключение
ЗаписьХМЛ.Закрыть();
ЗаписьХМЛ = Новый ЗаписьXML;
ЗаписьХМЛ.ОткрытьФайл(ПолноеИмяФайла);
Значение = Новый Структура("ВложенноеНесериализуемоеЗначение", Новый ХранилищеЗначения(Значение));
Попытка
СериализаторXDTO.ЗаписатьXML(ЗаписьХМЛ, Значение);
СообщитьЛкс("При сохранении данных в файл использована сериализация через хранилище значения из-за наличия недопустимых символов XML");
Исключение
СообщитьЛкс(ОписаниеОшибки());
Результат = Ложь;
КонецПопытки;
КонецПопытки;
ЗаписьХМЛ.Закрыть();
Если Результат И Сжатие Тогда
ВременныйКаталог = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ВременныйКаталог);
Файл = Новый Файл(ПолноеИмяФайла);
ИмяВременногоФайла = ВременныйКаталог + "\" + Файл.ИмяБезРасширения + ".xml";
ПереместитьФайл(Файл.ПолноеИмя, ИмяВременногоФайла);
ЗаписьЗип = Новый ЗаписьZipФайла(ПолноеИмяФайла,,,, УровеньСжатия);
ЗаписьЗип.Добавить(ИмяВременногоФайла);
ЗаписьЗип.Записать();
УдалитьФайлы(ВременныйКаталог, "*");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция КомпоновщикТаблицыМетаданныхЛкс(Знач ПолноеИмяМД, ВызыватьИсключениеПриОтсутствииПрав = Истина, ИндексПараметраПериодичность = Неопределено,
ВыражениеПараметраПериодичность = "", ИменаВместоПредставлений = Ложь) Экспорт
СхемаКомпоновкиДанных = ирОбщий.ПолучитьСхемуКомпоновкиПоОбъектуМетаданныхЛкс(ПолноеИмяМД,, Ложь,, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность,
ИменаВместоПредставлений);
#Если Сервер И Не Сервер Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
Попытка
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных);
Исключение
// Антибаг платформы 8.2.18
// Ошибка при вызове конструктора (ИсточникДоступныхНастроекКомпоновкиДанных)
// ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных);
//по причине:
//Ошибка получения информации набора данных
//по причине:
//Ошибка в запросе набора данных
//по причине:
//{(1, 17)}: Неверное присоединение
//ВЫБРАТЬ Т.* ИЗ <>>КАК Т
ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяМД);
Если ОбъектМД = Неопределено Тогда
// Возможно эта логика уже есть в какой то функции
лПолноеИмяМД = ПолноеИмяМД;
Фрагменты = ирОбщий.СтрРазделитьЛкс(ПолноеИмяМД);
Если Фрагменты.Количество() > 1 Тогда
Фрагменты.Удалить(Фрагменты.Количество() - 1);
лПолноеИмяМД = ирОбщий.СтрСоединитьЛкс(Фрагменты, ".");
КонецЕсли;
ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(лПолноеИмяМД);
КонецЕсли;
Если Ложь
Или ОбъектМД = Неопределено
Или Не ПравоДоступа("Чтение", ОбъектМД)
Тогда
Если ВызыватьИсключениеПриОтсутствииПрав Тогда
ВызватьИсключение "Таблица отсутствует или нет прав на ее чтение """ + ПолноеИмяМД + """";
Иначе
Возврат Неопределено;
КонецЕсли;
Иначе
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроек.Инициализировать(ИсточникДоступныхНастроек);
// Для сравнения скорости в отладчике. Примерно та же скорость через построитель.
//ПсевдонимТаблицы = "Т";
//ПолноеИмяИлиОбъектМД = ПолноеИмяМД;
//Если ТипЗнч(ПолноеИмяИлиОбъектМД) = Тип("Строка") Тогда
// ПолноеИмяМД = ПолноеИмяИлиОбъектМД;
//Иначе
// ПолноеИмяМД = ПолноеИмяИлиОбъектМД.ПолноеИмя();
//КонецЕсли;
//ПолноеИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
//Если ИндексПараметраПериодичность <> Неопределено Тогда
// ПолноеИмяТаблицыБД = ПолноеИмяТаблицыБД + "(";
// Для Индекс = 1 По ИндексПараметраПериодичность Цикл
// ПолноеИмяТаблицыБД = ПолноеИмяТаблицыБД + ",";
// КонецЦикла;
// ПолноеИмяТаблицыБД = ПолноеИмяТаблицыБД + ВыражениеПараметраПериодичность + ")";
//КонецЕсли;
//ТекстЗапроса = "ВЫБРАТЬ " + ПсевдонимТаблицы + ".* ИЗ " + ПолноеИмяТаблицыБД + " КАК " + ПсевдонимТаблицы;
//Построитель = Новый ПостроительЗапроса(ТекстЗапроса);
//Построитель.ЗаполнитьНастройки();
Возврат КомпоновщикНастроек;
КонецФункции
Функция ЕстьНекорректныеЭлементыВКомпоновщикеНастроекЛкс(Знач ПроверочныйКомпоновщик, выхСтрокаТекущихНастроек = "", выхСтрокаИсправленныхНастроек = "") Экспорт
выхСтрокаТекущихНастроек = СохранитьОбъектВВидеСтрокиXMLЛкс(ПроверочныйКомпоновщик.Настройки);
ПроверочныйКомпоновщик.Восстановить();
выхСтрокаИсправленныхНастроек = СохранитьОбъектВВидеСтрокиXMLЛкс(ПроверочныйКомпоновщик.Настройки);
ЕстьНекорректныеЭлементы = выхСтрокаИсправленныхНастроек <> выхСтрокаТекущихНастроек;
Возврат ЕстьНекорректныеЭлементы;
КонецФункции
Процедура ОбработкаПолученияФормыЛкс(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка, ЕстьУправляемаяФорма = Ложь) Экспорт
Если ЕстьУправляемаяФорма Тогда
Возврат;
КонецЕсли;
#Если Сервер Тогда
ПроверитьФлажокИспользоватьОбычныеФормыВУправляемомПриложенииЛкс();
#КонецЕсли
СтандартнаяОбработка = Ложь;
Если Не ирКэш.ЛиТолстыйКлиентЛкс() Тогда
ВыбраннаяФорма = "Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая";
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьФлажокИспользоватьОбычныеФормыВУправляемомПриложенииЛкс() Экспорт
Если Не Метаданные.ИспользоватьОбычныеФормыВУправляемомПриложении Тогда
СообщитьЛкс("Для использования отчетов подсистемы запустите обычное приложение либо в свойствах конфигурации установите флажок ""Использовать обычные формы в управляемом приложении""
| доступный в режиме ""Сервис""/""Параметры""/""Редактирование конфигурации для режимов запуска""=""Управляемое приложение и обычное приложение"".");
КонецЕсли;
КонецПроцедуры
Функция ВыполнитьАлгоритмЧерезВнешнююОбработкуЛкс(ИмяФайлаВнешнейОбработки, СтруктураПараметров, выхВремяНачала = Неопределено, ВерсияАлгоритма = Неопределено) Экспорт
#Если Сервер И Не Клиент Тогда
Файл = Новый Файл(ИмяФайлаВнешнейОбработки);
Если Не Файл.Существует() Тогда
КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс();
Если Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
ВызватьИсключение "файл внешней обработки алгоритма не доступен на сервере. Рекомендуется в общих настройках инструментов задать сетевой каталог объектов для отладки.";
КонецЕсли;
КонецЕсли;
#КонецЕсли
ВнешняяОбработка = ВнешниеОбработки.Создать(ИмяФайлаВнешнейОбработки, Ложь);
Если ВерсияАлгоритма <> Неопределено И ВнешняяОбработка.ВерсияАлгоритма() <> ВерсияАлгоритма Тогда
// Антибаг 8.3.11.2700-?. Testplatform@1c.ru - Support #17972. В обычном приложении на клиенте при повторном создании с одним именем файла и внутренней версией используются метаданные первой обработки в сеансе.
СообщитьЛкс("Внешняя обработка не обновилась в кэше процесса 1С. Для ее обновления рекомендуется выполнить перезапуск процесса.", СтатусСообщения.Внимание);
КонецЕсли;
ОбщиеМодули = ПолучитьСтруктуруОсновныхОбщихМодулейЛкс();
выхВремяНачала = ирОбщий.ТекущееВремяВМиллисекундахЛкс();
ВнешняяОбработка.мМетод(СтруктураПараметров, ОбщиеМодули);
//Возврат Результат;
КонецФункции
Функция ТекстМодуляСгенерированнойВнешнейОбработки(ПолноеИмяФайла) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Файл = Новый Файл(ПолноеИмяФайла);
Текст = мПлатформа.ТекстМодуляСгенерированнойВнешнейОбработки(Файл);
Возврат Текст;
КонецФункции
Функция ПолучитьСтруктуруОсновныхОбщихМодулейЛкс() Экспорт
ОбщиеМодули = Новый Структура;
ОбщиеМодули.Вставить("ирОбщий", ирОбщий);
ОбщиеМодули.Вставить("ирКэш", ирКэш);
ОбщиеМодули.Вставить("ирСервер", ирСервер);
Возврат ОбщиеМодули;
КонецФункции // ВыполнитьЛокально()
Процедура ОбновитьТипЗначенияВСтрокеТаблицыЛкс(ТекущаяСтрока, Знач ИмяКолонкиЗначения = "Значение", Знач ИмяКолонкиИлиОписаниеТипов = "ОписаниеТипов",
Знач ИмяКолонкиТипаЗначения = "ТипЗначения", Знач ИмяКолонкиИмяТипаЗначения = "ИмяТипаЗначения", Знач Колонки = Неопределено, Знач РасширенноеЗначение = Неопределено) Экспорт
Если Колонки = Неопределено Тогда
Колонки = ТекущаяСтрока.Владелец().Колонки;
Иначе
ТребоватьТипЛкс(Колонки, Тип("ТаблицаЗначений"), Тип("КоллекцияКолонокТаблицыЗначений"), Тип("КоллекцияКолонокДереваЗначений"), Тип("КоллекцияКолонокРезультатаЗапроса"), , Тип("КоллекцияОбъектовМетаданных"));
#Если Сервер И Не Сервер Тогда
Колонки = Новый ТаблицаЗначений;
Колонки = Колонки.Колонки;
#КонецЕсли
КонецЕсли;
Если ЗначениеЗаполнено(ИмяКолонкиЗначения) Тогда
РасширенноеЗначение = ТекущаяСтрока[ИмяКолонкиЗначения];
КонецЕсли;
ТипЗначения = ТипЗнч(РасширенноеЗначение);
Если ТипЗнч(ИмяКолонкиИлиОписаниеТипов) <> Тип("ОписаниеТипов") Тогда
КолонкаОписанияТипов = Колонки.Найти(ИмяКолонкиИлиОписаниеТипов);
Если КолонкаОписанияТипов <> Неопределено Тогда
ИмяКолонкиИлиОписаниеТипов = ТекущаяСтрока[ИмяКолонкиИлиОписаниеТипов];
Иначе
ИмяКолонкиИлиОписаниеТипов = Неопределено;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(Колонки) = Тип("ТаблицаЗначений") Тогда
ЕстьКолонкаТипЗначения = Колонки.Найти(ИмяКолонкиТипаЗначения, "Имя") <> Неопределено;
Иначе
ЕстьКолонкаТипЗначения = Колонки.Найти(ИмяКолонкиТипаЗначения) <> Неопределено;
КонецЕсли;
Если ЕстьКолонкаТипЗначения Тогда
ТекущаяСтрока[ИмяКолонкиТипаЗначения] = ПредставлениеТипаЛкс(ТипЗначения, ИмяКолонкиИлиОписаниеТипов, Ложь);
КонецЕсли;
Если ТипЗнч(Колонки) = Тип("ТаблицаЗначений") Тогда
ЕстьКолонкаИмяТипаЗначения = Колонки.Найти(ИмяКолонкиИмяТипаЗначения, "Имя") <> Неопределено;
Иначе
ЕстьКолонкаИмяТипаЗначения = Колонки.Найти(ИмяКолонкиИмяТипаЗначения) <> Неопределено;
КонецЕсли;
Если ЕстьКолонкаИмяТипаЗначения Тогда
ТекущаяСтрока[ИмяКолонкиИмяТипаЗначения] = ПредставлениеТипаЛкс(ТипЗначения, ИмяКолонкиИлиОписаниеТипов, Истина);
КонецЕсли;
КонецПроцедуры
Функция ПараметрыЗапускаПриложения1СЛкс(Знач ИмяПользователяИнфобазы = "", Знач ПарольПользователяИнфобазы = "", КодРазрешения = "", РежимКонфигуратора = Ложь,
РежимЗапуска = "ОбычноеПриложение", РазрешитьОтладку = Истина, ОчисткаКэшаКлиентСерверныхВызовов = Ложь, ДополнительныеПараметры = "", СообщитьСтрокуПараметров = Истина,
СтрокаСоединения = "", ОткрытьПортативныеИнструменты = Ложь, РежимИнтерфейсаТакси = Ложь, РазделениеДанных = "", ОтключитьАутентификациюОС = Ложь, КодЯзыка = "", ПараметрЗапуска = "") Экспорт
Если Не ЗначениеЗаполнено(СтрокаСоединения) Тогда
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
КонецЕсли;
ПараметрыЗапуска = "";
Если РежимКонфигуратора Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " CONFIG";
Иначе
ПараметрыЗапуска = ПараметрыЗапуска + " ENTERPRISE";
КонецЕсли;
ПараметрыЗапуска = ПараметрыЗапуска + " /IBConnectionString""" + СтрЗаменить(СтрокаСоединения, """", """""") + """";
Если ЗначениеЗаполнено(ИмяПользователяИнфобазы) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /N""" + ИмяПользователяИнфобазы + """";
КонецЕсли;
Если ОтключитьАутентификациюОС Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /WA-";
КонецЕсли;
Если ЗначениеЗаполнено(ПарольПользователяИнфобазы) Тогда
СтрокаПараметраПароля = "/P""" + ПарольПользователяИнфобазы + """";
СтрокаЗаменыПароля = "/P""" + "***" + """";
ПараметрыЗапуска = ПараметрыЗапуска + " " + СтрокаПараметраПароля;
КонецЕсли;
Если ЗначениеЗаполнено(ПараметрЗапуска) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /C""" + ПараметрЗапуска + """";
КонецЕсли;
ПараметрыЗапуска = ПараметрыЗапуска + " /UC""" + КодРазрешения + """";
Если Не РежимКонфигуратора Тогда
Если РазрешитьОтладку Тогда
ПараметрыЗапускаДляОтладки = ПараметрыЗапускаСеансаТекущиеЛкс();
ПараметрыЗапуска = ПараметрыЗапуска + " " + ПараметрыЗапускаДляОтладки;
КонецЕсли;
Если ОчисткаКэшаКлиентСерверныхВызовов Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /ClearCache";
КонецЕсли;
Если РежимИнтерфейсаТакси Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /iTaxi";
КонецЕсли;
Если ОткрытьПортативныеИнструменты И ирКэш.ЛиПортативныйРежимЛкс() Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /Execute""" + ирПортативный.ИспользуемоеИмяФайла + """";
КонецЕсли;
Если СтрокиРавныЛкс(РежимЗапуска, "Авто") Тогда
// Из-за этого иногда долго стартует почему то
ПараметрыЗапуска = ПараметрыЗапуска + " /AppAutoCheckMode"; // Автоматический выбор типа приложения для запуска
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "ОбычноеПриложение") Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /RunModeOrdinaryApplication";
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "УправляемоеПриложениеТолстый") Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /RunModeManagedApplication";
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "УправляемоеПриложениеТонкий") Тогда
//ПараметрыЗапуска = ПараметрыЗапуска + "/IBConnectionString""" + СтрЗаменить(СтрокаСоединения, """", """""") + """";
КонецЕсли;
Если ЗначениеЗаполнено(РазделениеДанных) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /Z""" + РазделениеДанных + """";
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(КодЯзыка) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /L""" + КодЯзыка + """";
КонецЕсли;
Если ЗначениеЗаполнено(ДополнительныеПараметры) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " " + ДополнительныеПараметры;
КонецЕсли;
Если СообщитьСтрокуПараметров Тогда
СообщитьЛкс(СтрЗаменить(ПараметрыЗапуска, СтрокаПараметраПароля, СтрокаЗаменыПароля));
КонецЕсли;
Возврат ПараметрыЗапуска;
КонецФункции
Функция СоздатьСсылочныйОбъектПоМетаданнымЛкс(ОбъектИлиИмяМД, ЭтоГруппаДляНового = Ложь, ИдентификаторСсылки = Неопределено, ЗаполнитьРеквизитыЗначениямиЗаполнения = Ложь) Экспорт
УстановитьПривилегированныйРежим(Истина);
Менеджер = ПолучитьМенеджерЛкс(ОбъектИлиИмяМД);
Если ТипЗнч(ОбъектИлиИмяМД) = Тип("ОбъектМетаданных") Тогда
ОбъектМД = ОбъектИлиИмяМД;
Иначе
ОбъектМД = ПолучитьМетаданныеЛкс(ОбъектИлиИмяМД);
КонецЕсли;
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ИмяТипаМетаданного = ПеревестиВРусский(ПервыйФрагментЛкс(ПолноеИмяМД));
Попытка
Если ИмяТипаМетаданного = "Справочник" Или ИмяТипаМетаданного = "ПланВидовХарактеристик" Тогда
Если ЭтоГруппаДляНового Тогда
Объект = Менеджер.СоздатьГруппу();
Иначе
Объект = Менеджер.СоздатьЭлемент();
КонецЕсли;
ИначеЕсли ИмяТипаМетаданного = "Документ" Тогда
Объект = Менеджер.СоздатьДокумент();
ИначеЕсли ИмяТипаМетаданного = "Задача" Тогда
Объект = Менеджер.СоздатьЗадачу();
ИначеЕсли ИмяТипаМетаданного = "БизнесПроцесс" Тогда
Объект = Менеджер.СоздатьБизнесПроцесс();
ИначеЕсли ИмяТипаМетаданного = "ПланОбмена" Тогда
Объект = Менеджер.СоздатьУзел();
ИначеЕсли ИмяТипаМетаданного = "ПланВидовРасчета" Тогда
Объект = Менеджер.СоздатьВидРасчета();
ИначеЕсли ИмяТипаМетаданного = "ПланСчетов" Тогда
Объект = Менеджер.СоздатьСчет();
ИначеЕсли ИмяТипаМетаданного = "ВнешнийИсточникДанных" Тогда
Объект = Менеджер.СоздатьОбъект();
Иначе
ВызватьИсключение "Неизвестный тип метаданных """ + ИмяТипаМетаданного + """";
КонецЕсли;
Исключение
ПроверитьОшибкуПодписокНаКлиентеЛкс(ОписаниеОшибки());
ВызватьИсключение;
КонецПопытки;
Если ИдентификаторСсылки = Неопределено Тогда
ИдентификаторСсылки = Новый УникальныйИдентификатор();
КонецЕсли;
Объект.УстановитьСсылкуНового(Менеджер.ПолучитьСсылку(ИдентификаторСсылки));
Если ЗаполнитьРеквизитыЗначениямиЗаполнения Тогда
Объект.Заполнить(Неопределено);
КонецЕсли;
Возврат Объект;
КонецФункции
Процедура ПроверитьОшибкуПодписокНаКлиентеЛкс(ОписаниеОшибки)
#Если Клиент Тогда
Если Найти(ОписаниеОшибки, "Обработчик события не найден") > 0 Тогда
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
СообщитьЛкс("Для предотвращения ошибок инициализации объектов рекомендуется в общих параметрах записи установить флажок ""Объекты на сервере""=Да или перейти на непортативный вариант инструментов");
Иначе
СообщитьЛкс("Для предотвращения ошибок инициализации объектов рекомендуется в общих параметрах записи установить флажки ""Объекты на сервере""=Да и ""Не использовать имитаторы""=Нет");
КонецЕсли;
КонецЕсли;
#КонецЕсли
КонецПроцедуры
Функция СтрокаПустогоИдентификатораЛкс() Экспорт
Возврат "00000000-0000-0000-0000-000000000000";
КонецФункции
Функция ИмяТипаИзПолногоИмениМДЛкс(Знач ПолноеИмяИлиОбъектМД, Знач ПодтипРус = "Ссылка") Экспорт
Если ТипЗнч(ПолноеИмяИлиОбъектМД) <> Тип("Строка") Тогда
ПолноеИмяИлиОбъектМД = ПолноеИмяИлиОбъектМД.ПолноеИмя();
КонецЕсли;
Фрагменты = СтрРазделитьЛкс(ПолноеИмяИлиОбъектМД);
Если Фрагменты.Количество() = 3 Тогда
ИмяТипа = ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяИлиОбъектМД);
Иначе
ПервоеСлово = "";
ИменаМД = "";
Для Счетчик = 1 По Фрагменты.Количество() / 2 Цикл
ПервоеСлово = ПервоеСлово + Фрагменты[(Счетчик - 1) * 2];
ИменаМД = ИменаМД + "." + Фрагменты[(Счетчик - 1) * 2 + 1];
КонецЦикла;
Подтип = ПеревестиСтроку(ПодтипРус);
ИмяТипа = ПервоеСлово + Подтип + ИменаМД;
КонецЕсли;
Возврат ИмяТипа;
КонецФункции
Функция ИмяТипаИзПолногоИмениТаблицыБДЛкс(ИмяТаблицыБД, Знач ПодтипРус = "Ссылка") Экспорт
Если Найти(ИмяТаблицыБД, "." + ПеревестиСтроку("Точки")) > 0 Тогда
ОписаниеТаблицыБД = ОписаниеТаблицыБДЛкс(ИмяТаблицыБД);
КонецЕсли;
Если Истина
И ОписаниеТаблицыБД <> Неопределено
И ОписаниеТаблицыБД.Тип = "Точки"
Тогда
Если ПодтипРус = "Ссылка" Тогда
Фрагменты = СтрРазделитьЛкс(ИмяТаблицыБД);
Результат = ПеревестиСтроку("ТочкаМаршрутаБизнесПроцессаСсылка") + "." + Фрагменты[1];
КонецЕсли;
Иначе
ПолноеИмяМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ИмяТаблицыБД);
Если ПолноеИмяМД <> Неопределено Тогда
Результат = ИмяТипаИзПолногоИмениМДЛкс(ПолноеИмяМД, ПодтипРус);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Возвращает имя типа, который будет использован в xml файле для указанного объекта метаданных
// Используется при поиске и замене ссылок при загрузке, при модификации схемы current-config при записи
//
// Параметры:
// Значение - Объект метаданных или Ссылка
//
// Возвращаемое значение:
// Строка - Строка вида CatalogRef.Валюты, описывающая объект метаданных
//
Функция XMLТипСсылкиЛкс(Знач ОбъектМДИлиСсылка) Экспорт
Если ТипЗнч(ОбъектМДИлиСсылка) = Тип("ОбъектМетаданных") Тогда
Ссылка = Новый (ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(ОбъектМДИлиСсылка));
Иначе
Ссылка = ОбъектМДИлиСсылка;
КонецЕсли;
Результат = СериализаторXDTO.XMLТипЗнч(Ссылка).ИмяТипа;
Возврат Результат;
КонецФункции
Функция ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, Знач ПодтипРус = "НаборЗаписей") Экспорт
Подтип = ПеревестиСтроку(ПодтипРус);
Фрагменты = СтрРазделитьЛкс(ПолноеИмяТаблицыБД);
Если Фрагменты.Количество() > 2 Тогда
Если Фрагменты[0] = ПеревестиСтроку("РегистрРасчета") Тогда
ИмяТипа = ПеревестиСтроку("Перерасчет") + Подтип + "." + Фрагменты[1] + "." + Фрагменты[2];
ИначеЕсли Фрагменты[0] = ПеревестиСтроку("РегистрБухгалтерии") Тогда
ИмяТипа = ПеревестиСтроку("РегистрБухгалтерии") + Подтип + "." + Фрагменты[1];
ИначеЕсли ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(Фрагменты[0]) Тогда
ИмяТипа = ПеревестиСтроку("ВнешнийИсточникДанныхТаблица") + Подтип + "." + Фрагменты[1] + "." + Фрагменты[3];
КонецЕсли;
Иначе
ИмяТипа = СтрЗаменить(ПеревестиСтроку(Фрагменты[0]) + "." + Фрагменты[1], ".", Подтип + ".");
КонецЕсли;
Возврат ИмяТипа;
КонецФункции
Функция ЗаменитьИдентификаторОбъектаЛкс(Объект, ИдентификаторСсылки = Неопределено) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() И ТипЗнч(Объект) = Тип("ОбработкаОбъект.ирИмитаторСсылочныйОбъект") Тогда
Возврат Объект.ЗаменитьИдентификаторОбъекта();
КонецЕсли;
Если ИдентификаторСсылки = Неопределено Тогда
ИдентификаторСсылки = Новый УникальныйИдентификатор;
КонецЕсли;
// Антибаг платформы 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=967697#967697
//Объект = СериализаторXDTO.ЗаписатьXDTO(Объект);
//Объект.Ref = ИдентификаторСсылки;
//Объект.IsFolder = ЭтоГруппаДляНового;
//Объект = СериализаторXDTO.ПрочитатьXDTO(Объект);
//
// Этот метод опасный, т.к. может привести к нежелательным изменениям в объекте!
ЗаписьХмл = Новый ЗаписьXML;
ЗаписьХмл.УстановитьСтроку();
ЗаписатьXML(ЗаписьХмл, Объект);
СтрокаХмл = ЗаписьХмл.Закрыть();
Попытка
ТекущийИДСсылки = XMLСтрока(Объект.Ссылка);
Исключение
// Внешний источник данных
ТекущийИДСсылки = "";
КонецПопытки;
Если ЗначениеЗаполнено(ТекущийИДСсылки) Тогда
ИмяЭлементаСсылки = "Ref";
СтрокаХмл = СтрЗаменить(СтрокаХмл, "<" + ИмяЭлементаСсылки + ">" + ТекущийИДСсылки + "" + ИмяЭлементаСсылки + ">",
"<" + ИмяЭлементаСсылки + ">" + XMLСтрока(ИдентификаторСсылки) + "" + ИмяЭлементаСсылки + ">");
//ИмяЭлементаЭтоГруппа = "IsFolder";
//Если Найти(СтрокаХмл, "<" + ИмяЭлементаЭтоГруппа + ">") > 0 Тогда
// СтрокаХмл = СтрЗаменить(СтрокаХмл, "<" + ИмяЭлементаЭтоГруппа + ">" + XMLСтрока(Объект.IsFolder) + "" + ИмяЭлементаЭтоГруппа + ">",
// "<" + ИмяЭлементаЭтоГруппа + ">" + XMLСтрока(ЭтоГруппаДляНового) + "" + ИмяЭлементаЭтоГруппа + ">");
//КонецЕсли;
КонецЕсли;
ЧтениеХмл = Новый ЧтениеXML;
ЧтениеХмл.УстановитьСтроку(СтрокаХмл);
Объект = ПрочитатьXML(ЧтениеХмл);
Возврат Объект;
КонецФункции
Функция НедоступноИзменениеПоляСсылочногоОбъектаЛкс(Знач ИмяПоля) Экспорт
НедоступноИзменениеПоля = Ложь
Или Нрег(ИмяПоля) = Нрег("Ссылка")
Или Нрег(ИмяПоля) = Нрег("ВерсияДанных")
Или Нрег(ИмяПоля) = Нрег("ЭтоГруппа")
//Или Нрег(ИмяПоля) = Нрег("ЭтотУзел") // ошибочно помечен как нередактируемый в синтакс-помощнике
Или Нрег(ИмяПоля) = Нрег("Предопределенный");
Возврат НедоступноИзменениеПоля;
КонецФункции
// Функция - Параметры доступа к объекту МДЛкс
//
// Параметры:
// Право - -
// МетаОбъект - -
// РольИлиПользователь - -
// выхПраваНеПрименимы - -
// выхИмяПоля - Строка - Неопределено - сначала подбор полей Ссылка, Период; "" - сразу получаем все поля и берем первое
//
// Возвращаемое значение:
// -
//
Функция ПараметрыДоступаКОбъектуМДЛкс(Знач Право, Знач МетаОбъект, Знач РольИлиПользователь = Неопределено, выхПраваНеПрименимы = Ложь, выхИмяПоля = Неопределено) Экспорт
Если выхИмяПоля = Неопределено Тогда
ИменаПолей = Новый Массив;
ИменаПолей.Добавить("Ссылка");
ИменаПолей.Добавить("Период");
Для Каждого ИмяПоля Из ИменаПолей Цикл
Попытка
ПараметрыДоступа = ПараметрыДоступа(Право, МетаОбъект, ИмяПоля, РольИлиПользователь);
Прервать;
Исключение
КонецПопытки;
КонецЦикла;
ИначеЕсли выхИмяПоля <> "" Тогда
Попытка
ПараметрыДоступа = ПараметрыДоступа(Право, МетаОбъект, выхИмяПоля, РольИлиПользователь);
Исключение
КонецПопытки;
КонецЕсли;
Если ПараметрыДоступа = Неопределено Тогда
Попытка
ПоляТаблицы = ПоляТаблицыМДЛкс(МетаОбъект, Ложь,,, Ложь);
ИмяПоля = ПоляТаблицы[0].Имя;
ПараметрыДоступа = ПараметрыДоступа(Право, МетаОбъект, ИмяПоля, РольИлиПользователь);
выхИмяПоля = ИмяПоля;
Исключение
// Например это Обработка, Перечисление
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
ПараметрыДоступа = Неопределено;
// Баг 8.3.13 Эта функция возвращает Истина даже для некорректных комбинаций параметров
//Попытка
// ПараметрыДоступа = ПравоДоступа(КлючИЗначение.Ключ, МетаОбъект, Роль);
//Исключение
выхПраваНеПрименимы = Истина;
//КонецПопытки;
КонецПопытки;
КонецЕсли;
Возврат ПараметрыДоступа;
КонецФункции
Функция ЕстьОграниченияДоступаКСтрокамТаблицыНаЧтениеЛкс(Знач ОбъектМД) Экспорт
ЕстьПраваДоступаКСтрокам = Ложь;
ПараметрыДоступа = ПараметрыДоступаКОбъектуМДЛкс("Чтение", ОбъектМД);
Если ПараметрыДоступа = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ПараметрыДоступа = ПараметрыДоступа();
#КонецЕсли
Если ПараметрыДоступа.Доступность Тогда
ЕстьПраваДоступаКСтрокам = ПараметрыДоступа.ОграничениеУсловием;
КонецЕсли;
Возврат ЕстьПраваДоступаКСтрокам;
КонецФункции
Функция ПолучитьРежимОбъектыНаСервереПоУмолчаниюЛкс(РазрешитьВПортативномВарианте = Истина) Экспорт
Результат = Истина
И (Ложь
Или Не ирКэш.ЛиПортативныйРежимЛкс()
Или РазрешитьВПортативномВарианте И ирПортативный.ЛиСерверныйМодульДоступенЛкс())
И Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение;
Возврат Результат;
КонецФункции
Функция СкопироватьКолонкиКоллекцииЛкс(КоллекцияИсточник, КоллекцияПриемник = Неопределено, БезТипов = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
КоллекцияИсточник = Новый ТаблицаЗначений;
#КонецЕсли
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый (ТипЗнч(КоллекцияИсточник));
КонецЕсли;
#Если Сервер И Не Сервер Тогда
КоллекцияПриемник = Новый ТаблицаЗначений;
#КонецЕсли
Для Каждого Колонка Из КоллекцияИсточник.Колонки Цикл
Если КоллекцияПриемник.Колонки.Найти(Колонка.Имя) <> Неопределено Тогда
Продолжить;
КонецЕсли;
Если БезТипов Тогда
НовыйТип = Новый ОписаниеТипов;
Иначе
НовыйТип = Колонка.ТипЗначения;
КонецЕсли;
КоллекцияПриемник.Колонки.Добавить(Колонка.Имя, НовыйТип, Колонка.Заголовок, Колонка.Ширина);
КонецЦикла;
Возврат КоллекцияПриемник;
КонецФункции
// ПропускатьДвиженияВнеПланаОбмена - Булево - при РегистрироватьДвиженияВместеСДокументом = Истина позволяет управлять поведением для тех движений, которые не входят в план обмена,
// Если Истина, то такие движения пропускаются, иначе вызывается исключение
Функция ПланыОбменаИзменитьРегистрациюЛкс(УзелИлиМассив, КлючОбъекта, НовоеЗначение = Истина, РегистрироватьДвиженияВместеСДокументом = Ложь, ДвиженияВместеСПоследовательностями = Ложь,
ПропускатьДвиженияВнеПланаОбмена = Истина, ПроверятьНаличиеТаблицыИзмененийДляКаждогоУзла = Ложь) Экспорт
Если КлючОбъекта = Неопределено Тогда
ВызватьИсключение "Изменение регистрации всех данных недопустимо";
КонецЕсли;
Если ТипЗнч(КлючОбъекта) = Тип("ОбъектМетаданных") Тогда
ОбъектМД = КлючОбъекта;
Иначе
ОбъектМД = Метаданные.НайтиПоТипу(ТипОбъектаБДЛкс(КлючОбъекта));
КонецЕсли;
Если РегистрироватьДвиженияВместеСДокументом Тогда
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ЭтоДокумент = ЛиКорневойТипДокументаЛкс(ПервыйФрагментЛкс(ПолноеИмяМД));
КонецЕсли;
Если РегистрироватьДвиженияВместеСДокументом И ЭтоДокумент И ТипЗнч(КлючОбъекта) = Тип("ОбъектМетаданных") Тогда
Запрос = Новый Запрос("ВЫБРАТЬ Т.Ссылка ИЗ " + ПолноеИмяМД + " КАК Т");
МассивОбъектов = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(0);
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(МассивОбъектов.Количество(), "Изменение регистрации");
Иначе
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(КлючОбъекта);
КонецЕсли;
Если ТипЗнч(УзелИлиМассив) = Тип("Массив") Тогда
Если УзелИлиМассив.Количество() > 0 Тогда
ОдинУзелОбмена = УзелИлиМассив[0];
Иначе
ОдинУзелОбмена = Неопределено;
КонецЕсли;
МассивУзлов = УзелИлиМассив;
Иначе
ОдинУзелОбмена = УзелИлиМассив;
МассивУзлов = Новый Массив;
МассивУзлов.Добавить(УзелИлиМассив);
КонецЕсли;
Если Не ЗначениеЗаполнено(ОдинУзелОбмена) Тогда
СообщитьЛкс("Не указан узел для регистрации изменений");
Возврат Ложь;
КонецЕсли;
Если ПроверятьНаличиеТаблицыИзмененийДляКаждогоУзла Тогда
УзлыДляРегистрации = ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(ОбъектМД, МассивУзлов);
Если УзлыДляРегистрации.Количество() = 0 Тогда
Возврат Истина;
КонецЕсли;
Иначе
УзлыДляРегистрации = МассивУзлов;
КонецЕсли;
Успех = Истина;
НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
Для Каждого Объект Из МассивОбъектов Цикл
Если Индикатор <> Неопределено Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
Если ТипЗнч(Объект) = Тип("Структура") Тогда
Объект = Объект.Методы;
КонецЕсли;
Если Истина
И ТипЗнч(Объект) = Тип("ОбъектМетаданных")
И Не ПравоДоступа("Изменение", Объект)
Тогда
СообщитьЛкс("Нет доступа к таблице """ + Объект.ПолноеИмя() + """", СтатусСообщения.Внимание);
Продолжить;
КонецЕсли;
ИзменитьРегистрациюОбъектаДляУзлаЛкс(УзлыДляРегистрации, Объект, НовоеЗначение, ОдинУзелОбмена, НомерВерсииПлатформы);
Если РегистрироватьДвиженияВместеСДокументом И ЭтоДокумент Тогда
ОбъектыМД = ирОбщий.ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(ОбъектМД, ДвиженияВместеСПоследовательностями, Истина);
Для Каждого МетаРегистр из ОбъектыМД Цикл
Если Не ОдинУзелОбмена.Метаданные().Состав.Содержит(МетаРегистр) Тогда
Если ПропускатьДвиженияВнеПланаОбмена Тогда
Продолжить;
Иначе
ВызватьИсключение "Движение документа по регистру " + МетаРегистр.ПолноеИмя() + " не может быть зарегистрировано в плане обмена " + ОдинУзелОбмена.Метаданные().Имя;
КонецЕсли;
КонецЕсли;
ИмяТаблицыБДРегистра = ирКэш.ИмяТаблицыИзМетаданныхЛкс(МетаРегистр.ПолноеИмя());
ИмяПоляОтбора = ирОбщий.ИмяПоляОтбораПодчиненногоНабораЗаписейЛкс(ИмяТаблицыБДРегистра);
СтруктураНабораЗаписей = ОбъектБДПоКлючуЛкс(ИмяТаблицыБДРегистра, Новый Структура(ИмяПоляОтбора, Объект.Ссылка),, Ложь);
ИзменитьРегистрациюОбъектаДляУзлаЛкс(УзлыДляРегистрации, СтруктураНабораЗаписей.Методы, НовоеЗначение, ОдинУзелОбмена, НомерВерсииПлатформы);
КонецЦикла;
КонецЕсли;
КонецЦикла;
Если Индикатор <> Неопределено Тогда
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
Возврат Успех;
КонецФункции
Процедура ИзменитьРегистрациюОбъектаДляУзлаЛкс(Знач УзлыДляРегистрации, Знач Объект, Знач НовоеЗначение, Знач ОдинУзелОбменаДляПроверки, Знач НомерВерсииПлатформы = "") Экспорт
НесобственныеУзлы = Новый Массив;
Для Каждого Узел Из УзлыДляРегистрации Цикл
Если ПланыОбмена[Метаданные.НайтиПоТипу(ТипЗнч(Узел)).Имя].ЭтотУзел() = Узел Тогда
// Изменение регистрации для собственных узлов выбросит исключение
Продолжить;
КонецЕсли;
НесобственныеУзлы.Добавить(Узел);
КонецЦикла;
ТипОбъекта = ТипЗнч(Объект);
ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта);
Если ЭтоИмитатор Тогда
ОбъектXML = Объект.Снимок();
ирСервер.ИзменитьРегистрациюОбъектаДляУзлаЛкс(ОбъектXML, ТипОбъекта, НесобственныеУзлы, НовоеЗначение, ОдинУзелОбменаДляПроверки, НомерВерсииПлатформы);
Иначе
Если НовоеЗначение Тогда
ПланыОбмена.ЗарегистрироватьИзменения(НесобственныеУзлы, Объект);
Если НомерВерсииПлатформы = Неопределено Тогда
НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
КонецЕсли;
// Антибаг платформы 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 Тогда
Возврат Результат;
КонецЕсли;
Для Каждого СтрокаПараметра Из Параметры Цикл
Если Не ЛиИмяПеременнойЛкс(СтрокаПараметра.Имя) Тогда
Результат = Ложь;
СообщитьЛкс(Заголовок + "Имя параметра """ + СтрокаПараметра.Имя + """ некорректно",
СтатусСообщения.Внимание);
КонецЕсли;
КонецЦикла;
НеуникальныеИмена = НеуникальныеЗначенияКолонкиТаблицыЛкс(Параметры, "Имя");
Для Каждого НеуникальноеИмя Из НеуникальныеИмена Цикл
СообщитьЛкс(Заголовок + "Параметр """ + НеуникальноеИмя + """ встречается более одного раза", СтатусСообщения.Внимание);
Результат = Ложь;
КонецЦикла;
Возврат Результат;
КонецФункции
// Возможно нужно объединить с ПолучитьМетаданныеЛкс
Функция ПолучитьМетаданныеПоПолномуИмениЛкс(ПолноеИмяМД) Экспорт
Объект = СоздатьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД);
Результат = Объект.Метаданные();
Возврат Результат;
КонецФункции
// Функция - Таблицы внешнего источника данных лкс
//
// Параметры:
// ОбъектМД - -
// ЛиОбъектные - Булево, *Ложь - Если Ложь то вернет только объектные таблицы, иначе - только необъектные
//
// Возвращаемое значение:
// -
//
Функция ТаблицыВнешнегоИсточникаДанныхЛкс(РодительскийОбъектМД, ЛиОбъектные = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
РодительскийОбъектМД = Метаданные.ВнешниеИсточникиДанных.ВнешнийИсточникДанных1;
#КонецЕсли
Результат = Новый Массив;
Для Каждого ОбъектМД Из РодительскийОбъектМД.Таблицы Цикл
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.ВнешниеИсточникиДанных.ВнешнийИсточникДанных1.Таблицы.Таблица1;
#КонецЕсли
Если Ложь
Или (ЛиОбъектные И ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.НеобъектныеДанные)
Или (Не ЛиОбъектные И ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные)
Тогда
Продолжить;
КонецЕсли;
Результат.Добавить(ОбъектМД);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция МножественноеИмяМДЛкс(Единственное) Экспорт
ТаблицаТиповМетаОбъектов = ирКэш.ТипыМетаОбъектов();
СтрокаТаблицы = ТаблицаТиповМетаОбъектов.Найти(НРег(Единственное), "НЕдинственное");
Если СтрокаТаблицы <> Неопределено Тогда
Результат = СтрокаТаблицы.Множественное;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЕдинственноеИмяМДЛкс(Множественное) Экспорт
ТаблицаТиповМетаОбъектов = ирКэш.ТипыМетаОбъектов();
СтрокаТаблицы = ТаблицаТиповМетаОбъектов.Найти(НРег(Множественное), "НМножественное");
Если СтрокаТаблицы <> Неопределено Тогда
Результат = СтрокаТаблицы.Единственное;
КонецЕсли;
Возврат Результат;
КонецФункции
// Получает тип из описания типов, типа или значения.
//
// Параметры:
// пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Тип - найденный тип.
//
Функция ПолучитьТипОбъектаЛкс(пОбъект)
ТипОбъекта = Тип("Неопределено");
ТипПараметра = ТипЗнч(пОбъект);
Если ТипПараметра = Тип("ОписаниеТипов") Тогда
Если пОбъект.Типы().Количество() > 0 Тогда
ТипОбъекта = пОбъект.Типы()[0];
КонецЕсли;
ИначеЕсли ТипПараметра <> Тип("Тип") Тогда
ТипОбъекта = ТипПараметра;
Иначе
ТипОбъекта = пОбъект;
КонецЕсли;
Возврат ТипОбъекта;
КонецФункции // ПолучитьТипОбъектаЛкс()
// Проверяет, является ли строка именем корневого типа объекта БД.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина – тип является корневым типом объекта БД;
// Ложь – иначе.
//
Функция ЛиКорневойТипСсылочногоОбъектаБДЛкс(Знач КорневойТип) Экспорт
Если Найти(КорневойТип, ".") > 0 Тогда
КорневойТип = ПервыйФрагментЛкс(КорневойТип);
КонецЕсли;
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "БизнесПроцесс"
ИЛИ КорневойТип = "Задача"
ИЛИ КорневойТип = "Документ"
ИЛИ КорневойТип = "ПланВидовРасчета"
ИЛИ КорневойТип = "ПланВидовХарактеристик"
ИЛИ КорневойТип = "ПланОбмена"
ИЛИ КорневойТип = "ПланСчетов"
ИЛИ КорневойТип = "Справочник"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипКонстантыЛкс(Знач КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "Константа"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипПланаОбменаЛкс(Знач КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "ПланОбмена"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипДокументаЛкс(Знач КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "Документ"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипБизнесПроцессаЛкс(Знач КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "БизнесПроцесс"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Проверяет, является ли строка именем корневого типа ссылки.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина – тип является корневым типом ссылки;
// Ложь – иначе.
//
Функция ЛиКорневойТипСсылкиЛкс(Знач КорневойТип, ИсключаяСсылкиМетаданных = Ложь) Экспорт
Если Найти(КорневойТип, ".") > 0 Тогда
КорневойТип = ПервыйФрагментЛкс(КорневойТип);
КонецЕсли;
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ Не ИсключаяСсылкиМетаданных И КорневойТип = "Перечисление"
ИЛИ Не ИсключаяСсылкиМетаданных И КорневойТип = "Точки" // Грязно
ИЛИ ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Проверяет, является ли строка именем корневого типа регистра БД.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина – тип является корневым типом регистра БД;
// Ложь – иначе.
//
Функция ЛиКорневойТипРегистраБДЛкс(Знач КорневойТип, СчитатьПоследовательностьРегистром = Истина) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "РегистрСведений"
ИЛИ КорневойТип = "РегистрНакопления"
ИЛИ КорневойТип = "РегистрБухгалтерии"
ИЛИ КорневойТип = "ДвиженияССубконто"
ИЛИ КорневойТип = "РегистрРасчета"
ИЛИ КорневойТип = "Перерасчет"
ИЛИ (Истина
И СчитатьПоследовательностьРегистром
И КорневойТип = "Последовательность")
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипРегистраРасчетаЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если КорневойТип = "РегистрРасчета" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипРегистраСведенийЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если КорневойТип = "РегистрСведений" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипРегистраБухгалтерииЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если КорневойТип = "РегистрБухгалтерии" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипРегистраНакопленияЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если КорневойТип = "РегистрНакопления" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипПоследовательностиЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если КорневойТип = "Последовательность" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если КорневойТип = "ВнешнийИсточникДанных" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипПеречисленияЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если КорневойТип = "Перечисление" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиТипТаблицыМетассылкиЛкс(ТипТаблицы) Экспорт
Если КодСимвола(ТипТаблицы, 1) < 128 Тогда
ТипТаблицы = ПеревестиВРусский(ТипТаблицы);
КонецЕсли;
Если Ложь
ИЛИ ТипТаблицы = "Перечисление"
ИЛИ ТипТаблицы = "Точки"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "ЖурналДокументов"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипКритерияОтбораЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "КритерийОтбора"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипТаблицыБДЛкс(КорневойТип, ВключаяВнешниеИсточникиДанных = Истина) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
Или ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип)
Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип)
Или ЛиКорневойТипРегистраБДЛкс(КорневойТип)
Или (ВключаяВнешниеИсточникиДанных И ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип))
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Проверяет, является ли строка именем типа вложенной таблицы БД.
//
// Параметры:
// ТипТаблицы - Строка, Неопределено - имя типа таблицы.
//
// Возвращаемое значение:
// Булево.
//
Функция ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Экспорт
Если КодСимвола(ТипТаблицы, 1) < 128 Тогда
ТипТаблицы = ПеревестиВРусский(ТипТаблицы);
КонецЕсли;
Если Ложь
ИЛИ ТипТаблицы = "ТабличнаяЧасть"
ИЛИ ЛиИмяПредопределеннойТабличнойЧастиЛкс(ТипТаблицы)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиИмяПредопределеннойТабличнойЧастиЛкс(ТипТаблицы) Экспорт
Если КодСимвола(ТипТаблицы, 1) < 128 Тогда
ТипТаблицы = ПеревестиВРусский(ТипТаблицы);
КонецЕсли;
Если Ложь
ИЛИ ТипТаблицы = "ВидыСубконто"
ИЛИ ТипТаблицы = "БазовыеВидыРасчета"
ИЛИ ТипТаблицы = "ВедущиеВидыРасчета"
ИЛИ ТипТаблицы = "ВытесняющиеВидыРасчета"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Проверяет, корневой тип на наличие реквизита "Код".
//
// Параметры:
// КорневойТип - Строка, Произвольный.
//
// Возвращаемое значение:
// Истина – реквизит "Код" имеется;
// Ложь – иначе.
//
Функция ЛиКорневойТипОбъектаСКодомЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
Или КорневойТип = "ПланВидовХарактеристик"
Или КорневойТип = "ПланОбмена"
Или КорневойТип = "ПланСчетов"
Или КорневойТип = "ПланРасчета"
Или КорневойТип = "Справочник"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипОбъектаСКодомЛкс()
// Проверяет, корневой тип на наличие реквизита "Предопределенный".
//
// Параметры:
// КорневойТип - Строка, Произвольный.
//
// Возвращаемое значение:
// Истина – реквизит "Предопределенный" имеется;
// Ложь – иначе.
//
Функция ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Экспорт
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
Или КорневойТип = "Справочник"
Или КорневойТип = "ПланСчетов"
Или КорневойТип = "ПланВидовХарактеристик"
Или КорневойТип = "ПланВидовРасчета"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипОбъектаСПредопределеннымЛкс()
Функция ЛиМетаданныеВнешнегоИсточникаДанныхЛкс(ОбъектМД) Экспорт
Если ОбъектМД = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(ОбъектМД);
Возврат ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип);
КонецФункции
// Проверяет, метаданные на иерархию.
// Иначе говоря проверяется наличие реквизита "Родитель".
//
// Параметры:
// пМетаданныеТипа - ОбъектМетаданных, Неопределено.
//
// Возвращаемое значение:
// Истина – метаданные с иерархией;
// Ложь – иначе.
//
Функция ЛиМетаданныеИерархическогоОбъектаЛкс(ОбъектМД) Экспорт
Если ОбъектМД = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(ОбъектМД);
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
Или КорневойТип = "ПланСчетов"
Или (Истина
И (Ложь
Или КорневойТип = "Справочник"
Или КорневойТип = "ПланВидовХарактеристик")
И ОбъектМД.Иерархический)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМетаданныеИерархическогоОбъектаЛкс()
// Проверяет, метаданные на иерархию.
// Иначе говоря проверяется начилие реквизита "Родитель".
//
// Параметры:
// пМетаданныеТипа - ОбъектМетаданных, Неопределено.
//
// Возвращаемое значение:
// Истина – метаданные с иерархией;
// Ложь – иначе.
//
Функция ЛиМетаданныеПодчиненногоОбъектаЛкс(ОбъектМД) Экспорт
Если ОбъектМД = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(ОбъектМД);
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Истина
И (Ложь
Или КорневойТип = "Справочник"
Или КорневойТип = "ПланВидовХарактеристик")
И ОбъектМД.Владельцы.Количество() > 0
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМетаданныеИерархическогоОбъектаЛкс()
// Проверяет, метаданные на иерархию с группами.
// Иначе говоря проверяется начилие реквизита "ЭтоГруппа".
//
// Параметры:
// пМетаданныеТипа - ОбъектМетаданных, Неопределено.
//
// Возвращаемое значение:
// Истина – метаданные с иерархией групп;
// Ложь – иначе.
//
Функция ЛиМетаданныеОбъектаСГруппамиЛкс(ОбъектМД) Экспорт
Если ОбъектМД = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(ОбъектМД, Истина);
Если КодСимвола(КорневойТип, 1) < 128 Тогда
КорневойТип = ПеревестиВРусский(КорневойТип);
КонецЕсли;
Если Ложь
Или (Истина
И КорневойТип = "Справочник"
И ОбъектМД.Иерархический
И ОбъектМД.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов)
Или (Истина
И КорневойТип = "ПланВидовХарактеристик"
И ОбъектМД.Иерархический)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиМетаданныеСсылочногоОбъектаЛкс(ОбъектМД, ДляТабличнойЧастиПроверятьРодителя = Ложь, ИсключаяСсылкиМетаданных = Ложь, ИсключаяВнешниеИсточникиДанных = Ложь) Экспорт
Если ОбъектМД = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.РегистрыСведений.КурсыВалют;
#КонецЕсли
Фрагменты = СтрРазделитьЛкс(ОбъектМД.ПолноеИмя());
КорневойТип = Фрагменты[0];
Если Истина
И Не ИсключаяВнешниеИсточникиДанных
И Фрагменты.Количество() = 4
И ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип)
Тогда
Возврат (ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные);
Иначе
Если Истина
И Не ДляТабличнойЧастиПроверятьРодителя
И Фрагменты.Количество() > 2
Тогда
Возврат Ложь;
КонецЕсли;
Если ЛиКорневойТипСсылкиЛкс(КорневойТип, ИсключаяСсылкиМетаданных) Тогда
Возврат Истина;
Иначе
Возврат Ложь;
КонецЕсли;
КонецЕсли;
КонецФункции
Функция ЛиМетаданныеРегистраЛкс(ОбъектМД, СчитатьПоследовательностьРегистром = Истина) Экспорт
Если ОбъектМД = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.РегистрыСведений.КурсыВалют;
#КонецЕсли
Фрагменты = СтрРазделитьЛкс(ОбъектМД.ПолноеИмя());
КорневойТип = Фрагменты[0];
Если ЛиКорневойТипРегистраБДЛкс(КорневойТип, СчитатьПоследовательностьРегистром) Тогда
Возврат Истина;
ИначеЕсли Истина
И Фрагменты.Количество() = 4
И ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип)
Тогда
Возврат (ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.НеобъектныеДанные);
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
Функция ЛиМетаданныеНезависимогоРегистраЛкс(ОбъектМД) Экспорт
Если ОбъектМД = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.РегистрыСведений.КурсыВалют;
#КонецЕсли
Фрагменты = СтрРазделитьЛкс(ОбъектМД.ПолноеИмя());
КорневойТип = Фрагменты[0];
ЭтоНезависимыйРегистр = Ложь
Или (Истина
И ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип)
И ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.НеобъектныеДанные)
Или (Истина
И ирОбщий.ЛиКорневойТипРегистраСведенийЛкс(КорневойТип)
И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.Независимый);
Возврат ЭтоНезависимыйРегистр;
КонецФункции
// https://www.hostedredmine.com/issues/895490
Функция ЛиДоступноРедактированиеВФормеОбъектаЛкс(ОбъектМД) Экспорт
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Справочники.Валюты;
#КонецЕсли
Результат = Истина;
//Если Ложь
// #Если ТолстыйКлиентУправляемоеПриложение Тогда
// Или Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.ОбычноеПриложение
// #ИначеЕсли ТолстыйКлиентОбычноеПриложение Тогда
// Или Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение
// Или ирОбщий.ТипТаблицыБДЛкс(ОбъектМД.ПолноеИмя()) = "Внешняя" // Обычные формы для таблиц внешних источников не обеспечивает платформа
// #КонецЕсли
//Тогда
Если ирОбщий.ЛиМетаданныеРегистраЛкс(ОбъектМД) Тогда
ИмяФормы = "ФормаЗаписи";
Иначе
ИмяФормы = "ФормаОбъекта";
КонецЕсли;
Попытка
ОсновнаяФорма = ОбъектМД["Основная" + ИмяФормы];
Исключение
ОсновнаяФорма = Неопределено;
КонецПопытки;
Если ОсновнаяФорма = Неопределено Тогда
Результат = Ложь;
КонецЕсли;
//КонецЕсли;
Возврат Результат;
КонецФункции
// Проверяет, является ли значение ссылкой на объект БД.
//
// Параметры:
// пЗначение – ОбъектМетаданных, Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – значение является ссылкой на объект БД;
// Ложь – значение не является ссылкой на объект БД.
//
Функция ЛиСсылкаНаОбъектБДЛкс(пЗначение, ИсключаяСсылкиМетаданных = Истина) Экспорт
//Результат = ЛиКорневойТипСсылочногоОбъектаБДЛкс(ПолучитьКорневойТипКонфигурацииЛкс(пЗначение, Истина));
Результат = ЛиТипСсылкиБДЛкс(ТипЗнч(пЗначение), ИсключаяСсылкиМетаданных);
Возврат Результат;
КонецФункции // ЛиСсылкаНаОбъектБДЛкс
Функция ЛиТипСсылкиБДЛкс(Тип, ИсключаяСсылкиМетаданных = Истина) Экспорт
Результат = Ложь;
ХмлТип = XMLТип(Тип);
Если ХмлТип <> Неопределено Тогда
Если Найти(ХмлТип.ИмяТипа, "Ref.") > 0 Тогда
Если Ложь
Или Не ИсключаяСсылкиМетаданных
Или (Истина
И Найти(ХмлТип.ИмяТипа, "BusinessProcessRoutePointRef.") = 0
И Найти(ХмлТип.ИмяТипа, "EnumRef.") = 0)
Тогда
Результат = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиТипОбъектаБДЛкс(Тип) Экспорт
Результат = Ложь;
ХмлТип = XMLТип(Тип);
Если ХмлТип <> Неопределено Тогда
Если Ложь
Или Найти(ХмлТип.ИмяТипа, "Object.") > 0
Или Найти(ХмлТип.ИмяТипа, "RecordSet.") > 0
Или Найти(ХмлТип.ИмяТипа, "ValueManager.") > 0
Тогда
Результат = Истина;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиТипСсылкиТочкиМаршрутаЛкс(Тип) Экспорт
XMLТип = XMLТип(Тип);
Если XMLТип <> Неопределено Тогда
Если Найти(XMLТип.ИмяТипа, "BusinessProcessRoutePointRef.") > 0 Тогда
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиТипСсылкиВнешнейТаблицыЛкс(Тип) Экспорт
XMLТип = XMLТип(Тип);
Если XMLТип <> Неопределено Тогда
Если Найти(XMLТип.ИмяТипа, "ExternalDataSourceTableRef.") > 0 Тогда
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Получить структуру отбора по связям И параметрам выбора
//
// Параметры:
// ЭтотОбъект - <тип> -
// ПолеФормыИлиРеквизитМетаданных - <тип> -
// ДляОчистки - <тип>, Ложь -
//
// Возвращаемое значение:
//
Функция ПолучитьСтруктуруОтбораПоСвязямИПараметрамВыбораЛкс(ЭтотОбъект, ПолеФормыИлиРеквизитМетаданных, СтруктураТЧ = Неопределено, ДляОчистки = Ложь) Экспорт
Попытка
СвязиПараметровВыбора = ПолеФормыИлиРеквизитМетаданных.СвязиПараметровВыбора;
Исключение
Возврат Новый Структура();
КонецПопытки;
ПараметрыВыбора = ПолеФормыИлиРеквизитМетаданных.ПараметрыВыбора;
Результат = Новый Структура("Отбор", Новый Структура);
Для Каждого СвязьПараметраВыбора Из СвязиПараметровВыбора Цикл
#Если Сервер И Не Сервер Тогда
СвязьПараметраВыбора = Новый СвязьПараметраВыбора;
#КонецЕсли
Если Истина
И ДляОчистки
И СвязьПараметраВыбора.ИзменениеЗначения = РежимИзмененияСвязанногоЗначения.НеИзменять
Тогда
Продолжить;
КонецЕсли;
ПолныйПутьКДанным = "ЭтотОбъект." + СвязьПараметраВыбора.ПутьКДанным;
Если СтруктураТЧ <> Неопределено Тогда
КлючИЗначениеТЧ = Неопределено;
Для Каждого КлючИЗначение Из СтруктураТЧ Цикл
КлючИЗначениеТЧ = КлючИЗначение;
Прервать;
КонецЦикла;
Если ирОбщий.СтрокиРавныЛкс(ирОбщий.ПервыйФрагментЛкс(СвязьПараметраВыбора.ПутьКДанным), КлючИЗначениеТЧ.Ключ) Тогда
ПолныйПутьКДанным = "СтруктураТЧ." + СвязьПараметраВыбора.ПутьКДанным;
КонецЕсли;
КонецЕсли;
Попытка
ЗначениеДанных = Вычислить(ПолныйПутьКДанным);
Исключение
// Например поле таблицы или на сервере текущая строка таблицы
Продолжить;
КонецПопытки;
УстановитьВложенноеСвойствоСтруктурыЛкс(Результат, СвязьПараметраВыбора.Имя, ЗначениеДанных);
КонецЦикла;
Для Каждого ПараметрВыбора Из ПараметрыВыбора Цикл
#Если Сервер И Не Сервер Тогда
ПараметрВыбора = Новый ПараметрВыбора;
#КонецЕсли
УстановитьВложенноеСвойствоСтруктурыЛкс(Результат, ПараметрВыбора.Имя, ПараметрВыбора.Значение);
КонецЦикла;
Результат = Результат.Отбор; // Возможно потом перейдем везде на передачу полной структуры
Возврат Результат;
КонецФункции
Процедура УстановитьВложенноеСвойствоСтруктурыЛкс(Знач НачальнаяСтруктура, Знач ПолноеИмяСвойства, Знач ЗначениеДанных)
Фрагменты = СтрРазделитьЛкс("_." + ПолноеИмяСвойства);
ТекущаяСтруктура = Новый Структура("_", НачальнаяСтруктура);
Для Индекс = 0 По Фрагменты.Вграница() - 1 Цикл
ТекущаяСтруктура = ТекущаяСтруктура[Фрагменты[Индекс]];
Если Не ТекущаяСтруктура.Свойство(Фрагменты[Индекс + 1]) Тогда
ТекущаяСтруктура.Вставить(Фрагменты[Индекс + 1], Новый Структура);
КонецЕсли;
КонецЦикла;
ТекущаяСтруктура[Фрагменты[Фрагменты.Вграница()]] = ЗначениеДанных;
КонецПроцедуры
// Проверяет, является ли значение ссылкой на значение перечисления.
//
// Параметры:
// пЗначение – Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – значение является ссылкой на объект БД;
// Ложь – значение не является ссылкой на объект БД.
//
Функция ЛиСсылкаНаПеречислениеЛкс(пЗначение) Экспорт
Возврат (ПолучитьКорневойТипКонфигурацииЛкс(пЗначение) = "Перечисление");
КонецФункции // ЛиСсылкаНаПеречислениеЛкс()
// Проверяет, является ли ключом записи регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – тип ключа записи регистра подтвержден;
// Ложь – тип ключа записи регистра не подтвержден.
//
Функция ЛиКлючЗаписиРегистраЛкс(Объект, ИсключаяВнешниеИсточникиДанных = Ложь) Экспорт
ТипОбразец = ирКэш.ПервыйПроизводныйТипРегистраЛкс("КлючЗаписи");
Результат = Истина
И ТипОбразец <> Неопределено
//И ирОбщий.ПоследнийФрагментЛкс(ирОбщий.ПервыйФрагментЛкс("" + ТипОбразец, ":"), " ") = ирОбщий.ПоследнийФрагментЛкс(ирОбщий.ПервыйФрагментЛкс("" + ПолучитьТипОбъектаЛкс(Объект), ":"), " ")
// Замена для поддержки внешних истчоников данных
И СтрНайтиЛкс(ирОбщий.ПервыйФрагментЛкс(" " + ПолучитьТипОбъектаЛкс(Объект), ":"), ирОбщий.ПоследнийФрагментЛкс(ирОбщий.ПервыйФрагментЛкс("" + ТипОбразец, ":"), " ")) > 0;
Возврат Результат;
КонецФункции // ЛиКлючЗаписиРегистраЛкс()
&НаКлиенте
Функция ЛиКлючСсылкиИлиРегистраЛкс(Знач Объект) Экспорт
Возврат Ложь
Или ЛиСсылкаНаОбъектБДЛкс(Объект)
Или ЛиКлючЗаписиРегистраЛкс(Объект);
КонецФункции
// Проверяет, является ли записью регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – тип записи регистра подтвержден;
// Ложь – тип записи регистра не подтвержден.
//
Функция ЛиЗаписьРегистраЛкс(Объект) Экспорт
ТипОбразец = ирКэш.ПервыйПроизводныйТипРегистраЛкс("Запись");
Результат = Истина
И ТипОбразец <> Неопределено
И ирОбщий.ПоследнийФрагментЛкс(ирОбщий.ПервыйФрагментЛкс("" + ТипОбразец, ":"), " ") = ирОбщий.ПоследнийФрагментЛкс(ирОбщий.ПервыйФрагментЛкс("" + ПолучитьТипОбъектаЛкс(Объект), ":"), " ");
Возврат Результат;
КонецФункции // ЛксЛиКлючЗаписиБД()
// Проверяет, является ли набором записей регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – тип набора записей регистра подтвержден;
// Ложь – тип набора записей регистра не подтвержден.
//
Функция ЛиНаборЗаписейРегистраЛкс(Объект) Экспорт
ТипОбразец = ирКэш.ПервыйПроизводныйТипРегистраЛкс("НаборЗаписей");
Результат = Истина
И ТипОбразец <> Неопределено
И ирОбщий.ПервыйФрагментЛкс("" + ТипОбразец, ":") = ирОбщий.ПервыйФрагментЛкс("" + ПолучитьТипОбъектаЛкс(Объект), ":");
Возврат Результат;
КонецФункции // ЛиНаборЗаписейРегистраЛкс()
// Проверяет, является ли менеджером записи регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – тип менеджер записи регистра подтвержден;
// Ложь – тип менеджер записи регистра не подтвержден.
//
Функция ЛиМенеджерЗаписиРегистраЛкс(Объект) Экспорт
ТипОбразец = ирКэш.ПервыйПроизводныйТипРегистраЛкс("МенеджерЗаписи");
Результат = Истина
И ТипОбразец <> Неопределено
И ирОбщий.ПервыйФрагментЛкс("" + ТипОбразец, ":") = ирОбщий.ПервыйФрагментЛкс("" + ПолучитьТипОбъектаЛкс(Объект), ":");
Возврат Результат;
КонецФункции
// Проверяет, является ли субконтом описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – тип субконто подтвержден;
// Ложь – тип субконто не подтвержден.
//
Функция ЛиСубконтоЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "субконто:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиСубконтоЛкс()
// Проверяет, является ли значение табличной частью внешней обработки.
//
// Параметры:
// пЗначение – Произвольный – проверяемое значение.
//
// Возвращаемое значение:
// Истина – значение является табличной частью внешней обработки;
// Ложь – значение не является табличной частью внешней обработки.
//
Функция ЛиТабличнаяЧастьВнешнейОбработкиЛкс(пЗначение) Экспорт
СтрокаТипЗначения = ПервыйФрагментЛкс(Строка(пЗначение));
Возврат (СтрокаТипЗначения = "ВнешняяОбработкаТабличнаяЧасть");
КонецФункции // ЛксЛиВнешняяОбработка()
// Получает ссылочный тип по метаданным.
//
// Параметры:
// пМетаданные – ОбъектМетаданных.
//
// Возвращаемое значение:
// – Тип - ссылочный;
// Неопределено – тип нельзя получить.
//
Функция ПолучитьСсылочныйТипПоМетаданнымЛкс(пМетаданные) Экспорт
Результат = Неопределено;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданные, Истина);
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
Результат = Тип(КорневойТип + "Ссылка." + пМетаданные.Имя);
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьСсылочныйТипПоМетаданнымЛкс()
// Получает метаданные по полному имени, описанию типов, типу, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Произвольный – для чего получаем метаданные.
//
// Возвращаемое значение:
// – Метаданные - полученные;
// Неопределено - не удалось получить метаданные.
//
Функция ПолучитьМетаданныеЛкс(пОбъект) Экспорт
Если ТипЗнч(пОбъект) = Тип("Строка") Тогда
Если ПустаяСтрока(пОбъект) Тогда
Результат = Неопределено;
Иначе
Фрагменты = СтрРазделитьЛкс(пОбъект);
#Если Сервер И Не Сервер Тогда
Фрагменты = Новый Массив;
#КонецЕсли
Если Фрагменты.Количество() % 2 = 1 Тогда
// ВидыСубконто, Изменения
Фрагменты.Удалить(Фрагменты.ВГраница());
ПолноеИмяМД = СтрСоединитьЛкс(Фрагменты, ".");
Иначе
ПолноеИмяМД = пОбъект;
КонецЕсли;
Результат = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяМД);
КонецЕсли;
Возврат Результат;
КонецЕсли;
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Результат = Метаданные.НайтиПоТипу(ТипОбъекта);
Возврат Результат;
КонецФункции
// Получает метаданные списка по описанию типов, типу или значению.
// Для описания типов берется первый тип массива типов.
//
//
// Параметры:
// пОбъект – Произвольное – проверяемое значение.
//
// Возвращаемое значение:
// – Метаданные - списка;
// Неопределено – значение не является списком.
//
Функция ПолучитьМетаданныеСпискаЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
МаркерСписка = "список:";
Если Найти(Строка(ТипОбъекта), МаркерСписка) > 0 Тогда
Возврат ПолучитьМетаданныеЛкс(ТипОбъекта);
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции // ПолучитьМетаданныеСпискаЛкс()
// Определяет корневой тип конфигурации по описанию типов, типу, метаданным, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Произвольный – для чего получаем метаданные;
// *пЛиТолькоДляКорневого - Булево, *Ложь - возвращать только для объекта корневого типа.
//
// Возвращаемое значение:
// - Строка – имя типа корневого объекта метаданных;
// Неопределено - не удалось получить имя типа.
//
Функция ПолучитьКорневойТипКонфигурацииЛкс(пОбъект, пЛиТолькоДляКорневого = Ложь) Экспорт
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
МетаданныеТипа = пОбъект;
Иначе
МетаданныеТипа = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
Результат = Неопределено;
Если МетаданныеТипа <> Неопределено Тогда
ПолноеИмя = МетаданныеТипа.ПолноеИмя();
Если пЛиТолькоДляКорневого Тогда
МассивФрагментов = СтрРазделитьЛкс(ПолноеИмя);
Если МассивФрагментов.Количество() = 2 Тогда
Результат = МассивФрагментов[0];
КонецЕсли;
Иначе
Результат = ПервыйФрагментЛкс(ПолноеИмя);
КонецЕсли;
//Если Результат = "ВнешнийИсточникДанных" Тогда
// Результат = Результат + "Таблица";
//КонецЕсли;
КонецЕсли;
Результат = ПеревестиВРусский(Результат);
Если Результат = "ТабличнаяЧасть" Тогда
// Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьКорневойТипКонфигурацииЛкс()
// Определяет имя корневого типа строки табличной части по описанию типов, типу или значению.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Произвольный – для чего получаем корневой тип строки табличной части.
//
// Возвращаемое значение:
// - Строка – имя типа корневого объекта метаданных;
// Неопределено – значение не является строкой табличной части.
//
Функция ПолучитьКорневойТипСтрокиТабличнойЧастиЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "табличная часть строка:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат ПервыйФрагментЛкс(Метаданные.НайтиПоТипу(ТипОбъекта).ПолноеИмя());
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьКорневойТипСтрокиТабличнойЧастиЛкс()
// Определяет имя корневого типа табличной части по описанию типов, типу, метаданным, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Произвольный – для чего определяем корневой тип.
//
// Возвращаемое значение:
// - Строка – имя типа корневого объекта метаданных;
// Неопределено – значение не является строкой табличной части.
//
Функция ПолучитьКорневойТипТабличнойЧастиЛкс(пОбъект) Экспорт
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
МетаданныеТипа = пОбъект;
Иначе
МетаданныеТипа = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
Если МетаданныеТипа <> Неопределено Тогда
ПолноеИмя = МетаданныеТипа.ПолноеИмя();
МассивФрагментов = СтрРазделитьЛкс(ПолноеИмя);
Если Истина
И МассивФрагментов.Количество() >= 4
И МассивФрагментов[2] = "ТабличнаяЧасть"
Тогда
Возврат МассивФрагментов[2];
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьКорневойТипТабличнойЧастиЛкс()
// Определяет имя корневого типа списка по описанию типов, типу или значению.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Произвольный – для чего получаем корневой тип строки табличной части.
//
// Возвращаемое значение:
// - Строка – имя типа корневого объекта метаданных;
// Неопределено – значение не является списком.
//
Функция ПолучитьКорневойТипСпискаЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "список:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат ПервыйФрагментЛкс(Метаданные.НайтиПоТипу(ТипОбъекта).ПолноеИмя());
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьКорневойТипСпискаЛкс()
// Определяет имя табличной части по ее метаданным.
//
// Параметры:
// пМетаданные – ОбъектМетаданных – который проверяем.
//
// Возвращаемое значение:
// - Строка – имя табличной части;
// Неопределено – это метаданные не табличной части.
//
Функция ПолучитьИмяТабличнойЧастиЛкс(пМетаданные) Экспорт
Если пМетаданные <> Неопределено Тогда
МассивФрагментов = СтрРазделитьЛкс(пМетаданные.ПолноеИмя());
Если МассивФрагментов.ВГраница() >= 2 Тогда
Если МассивФрагментов[2] = "ТабличнаяЧасть" Тогда
Возврат МассивФрагментов[3];
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьИмяТабличнойЧастиЛкс()
// Получает менеджер по описанию типов, типу, метаданным, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект – Произвольный – для чего получаем менеджер.
//
// Возвращаемое значение:
// – МенеджерОбъекта - для ссылки или ссылочного типа;
// Неопределено - не удалось получить.
//
Функция ПолучитьМенеджерЛкс(пОбъект) Экспорт
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
МетаданныеОбъекта = пОбъект;
Иначе
МетаданныеОбъекта = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
Если МетаданныеОбъекта = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
МассивФрагментов = СтрРазделитьЛкс(МетаданныеОбъекта.ПолноеИмя());
КорневойТип = МассивФрагментов[0];
Менеджер = Неопределено;
Если Истина
И МассивФрагментов.Количество() = 4
И ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип)
Тогда
ИмяТипаМенеджера = МассивФрагментов[0] + ПеревестиСтроку("ТаблицаМенеджер") + "." + МассивФрагментов[1] + "." + МассивФрагментов[3];
Иначе
//КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(МетаданныеОбъекта, Истина); // Изменил 02.03.2012
Если КорневойТип <> Неопределено Тогда
ИмяТипаМенеджера = КорневойТип + ПеревестиСтроку("Менеджер") + "." + МетаданныеОбъекта.Имя;
Иначе
ИмяТипаМенеджера = "Неопределено";
КонецЕсли;
КонецЕсли;
Попытка
Менеджер = Новый (ИмяТипаМенеджера);
Исключение
КонецПопытки;
Возврат Менеджер;
КонецФункции // ПолучитьМенеджерЛкс()
// Получает запись регистра по ключу записи.
//
// Параметры:
// пКлючЗаписи – КлючЗаписиРегистра – идентифицирующий запись.
//
// Возвращаемое значение:
// – ЗаписьРегистра – найденная запись.
//
Функция ПолучитьЗаписьРегистраПоКлючуЛкс(пКлючЗаписи) Экспорт
МенеджерЗначения = ПолучитьМенеджерЛкс(пКлючЗаписи);
МенеджерЗаписи = МенеджерЗначения.СоздатьМенеджерЗаписи();
ЗаполнитьЗначенияСвойств(МенеджерЗаписи, пКлючЗаписи);
МенеджерЗаписи.Прочитать();
Возврат МенеджерЗаписи;
КонецФункции // ПолучитьЗаписьРегистраПоКлючуЛкс()
// Больше не используется. Кандидат на удаление.
// Получает список реквизитов объекта БД.
//
// Параметры:
// пОбъект – определитель объекта метаданных;
// *ЛиВключатьТолькоЧитаемые - Булево, *Ложь - включать ли в список только читаемые реквизиты;
// *ЛиВключатьНедоступные - Булево, *Ложь - включать ли в список недоступные (группы/элементы) реквизиты;
// *ЛиСортировать - Булево, *Ложь - отсортировать ли по представлению;
// *ЛиСКартинками - Булево, *Ложь - добавлять ли картинки;
// *ЛиСТабличнымиЧастями - Булево, *Ложь - включать ли в список табличные части.
//
// Возвращаемое значение:
// СписокЗначений – содержащий в качестве значений имена реквизитов.
//
Функция ПолучитьСписокРеквизитовОбъектаБДЛкс(пОбъект, ЛиВключатьТолькоЧитаемые = Ложь,
ЛиВключатьНедоступные = Ложь, ЛиСортировать = Ложь, ЛиСКартинками = Ложь, ЛиСТабличнымиЧастями = Ложь) Экспорт
СписокРеквизитов = Новый СписокЗначений;
Если пОбъект = Неопределено Тогда
Возврат СписокРеквизитов;
КонецЕсли;
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
ОбъектМетаданных = пОбъект;
Иначе
ОбъектМетаданных = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(ОбъектМетаданных);
КорневойТип = ПеревестиВРусский(КорневойТип);
ИерархияГрупп = Ложь;
КартинкаРеквизита = Неопределено;
#Если Клиент Тогда
Если ЛиСКартинками Тогда
КартинкаРеквизита = БиблиотекаКартинок.СлужебныйРеквизит;
КонецЕсли;
#КонецЕсли
Если КорневойТип = "Задача" Тогда
СписокРеквизитов.Добавить("БизнесПроцесс", "Бизнес процесс", , КартинкаРеквизита);
СписокРеквизитов.Добавить("Дата", "Дата", , КартинкаРеквизита);
Если ОбъектМетаданных.ДлинаНаименования > 0 Тогда
СписокРеквизитов.Добавить("Наименование", "Наименование", , КартинкаРеквизита);
КонецЕсли;
Если ОбъектМетаданных.ДлинаНомера > 0 Тогда
СписокРеквизитов.Добавить("Номер", "Номер", , КартинкаРеквизита);
КонецЕсли;
СписокРеквизитов.Добавить("ТочкаМаршрута", "Точка маршрута", , КартинкаРеквизита);
СписокРеквизитов.Добавить("Выполнена", "Выполнена", , КартинкаРеквизита);
Для Каждого Рекв из ОбъектМетаданных.РеквизитыАдресации Цикл
СписокРеквизитов.Добавить(Рекв.Имя, Рекв.Представление(), , КартинкаРеквизита);
КонецЦикла;
КонецЕсли;
Если КорневойТип = "Документ" Тогда
СписокРеквизитов.Добавить("Дата", "Дата", , КартинкаРеквизита);
Если ОбъектМетаданных.ДлинаНомера > 0 Тогда
СписокРеквизитов.Добавить("Номер", "Номер", , КартинкаРеквизита);
КонецЕсли;
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("Проведен", "Проведен", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
Если КорневойТип = "Справочник" Тогда
Если ОбъектМетаданных.Владельцы.Количество() > 0 Тогда
СписокРеквизитов.Добавить("Владелец", "Владелец", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
ЭтоГруппа = Ложь;
Если ЛиКорневойТипОбъектаСКодомЛкс(КорневойТип) Тогда
Если ОбъектМетаданных.ДлинаКода > 0 Тогда
СписокРеквизитов.Добавить("Код", "Код", , КартинкаРеквизита);
КонецЕсли;
Если ОбъектМетаданных.ДлинаНаименования > 0 Тогда
СписокРеквизитов.Добавить("Наименование", "Наименование", , КартинкаРеквизита);
КонецЕсли;
Если ЛиМетаданныеИерархическогоОбъектаЛкс(ОбъектМетаданных) Тогда
СписокРеквизитов.Добавить("Родитель", "Родитель", , КартинкаРеквизита);
Если ЛиМетаданныеОбъектаСГруппамиЛкс(ОбъектМетаданных) Тогда
ИерархияГрупп = Истина;
Если Не ЛиВключатьНедоступные Тогда
ЭтоГруппа = пОбъект.ЭтоГруппа;
КонецЕсли;
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("ЭтоГруппа", "Это группа", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("Предопределенный", "Предопределенный", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
СписокРеквизитов.Добавить("ПометкаУдаления", "Пометка удаления", , КартинкаРеквизита);
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("Ссылка", "Ссылка", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
Для Каждого СтрокаРеквизита Из СписокРеквизитов Цикл
СтрокаРеквизита.Значение = ПеревестиСтроку(СтрокаРеквизита.Значение);
КонецЦикла;
#Если Клиент Тогда
Если ЛиСКартинками Тогда
КартинкаРеквизита = ирКэш.КартинкаПоИмениЛкс("ирРеквизит");
КонецЕсли;
#КонецЕсли
Для Каждого МетаРеквизит Из ОбъектМетаданных.Реквизиты Цикл
Если Ложь
Или ЛиВключатьНедоступные
Или Не ИерархияГрупп
Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента
Или (Истина
И ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы)
Или (Истина
И Не ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента)
Тогда
СписокРеквизитов.Добавить(МетаРеквизит.Имя, МетаРеквизит.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
Если ирКэш.ДоступныОбщиеРеквизитыЛкс() Тогда
Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл
Если ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Тогда
СписокРеквизитов.Добавить(ОбщийРеквизит.Имя, ОбщийРеквизит.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЛиСТабличнымиЧастями Тогда
#Если Клиент Тогда
Если ЛиСКартинками Тогда
КартинкаРеквизита = БиблиотекаКартинок.ТабличнаяЧасть;
КонецЕсли;
#КонецЕсли
Для Каждого МетаТабличнаяЧасть Из ОбъектМетаданных.ТабличныеЧасти Цикл
Если Ложь
Или ЛиВключатьНедоступные
Или Не ИерархияГрупп
Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента
Или (Истина
И ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы)
Или (Истина
И Не ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента)
Тогда
СписокРеквизитов.Добавить(МетаТабличнаяЧасть.Имя, МетаТабличнаяЧасть.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЛиСортировать Тогда
СписокРеквизитов.СортироватьПоПредставлению();
КонецЕсли;
Возврат СписокРеквизитов;
КонецФункции // ПолучитьСписокРеквизитовОбъектаБДЛкс()
Функция ИмяФайлаСпискаИнфобазПользователяОСЛкс() Экспорт
App = Новый COMОбъект("Shell.Application");
AppData = App.Namespace(26).Self.Path;
ИмяФайлаСписка = AppData + "\1C\1CEStart\ibases.v8i";
Возврат ИмяФайлаСписка;
КонецФункции
// Описатель - ОбъектМетаданных - его реквизиты переносятся в коллекцию в качестве элементов для структуры и в качестве колонок для дерева или таблицы
// - Коллекция с элементами РеквизитФормы, ОбъектМетаданных:Реквизит
// ИсходнаяКоллекция - ТаблицаЗначений, ДеревоЗначений, Структура - по умолчанию создается ТаблицаЗначений
//
Функция УстановитьМетаданныеКоллекцииЛкс(Описатель, ИсходнаяКоллекция = Неопределено) Экспорт
Если ИсходнаяКоллекция = Неопределено Тогда
ИсходнаяКоллекция = Новый ТаблицаЗначений;
КонецЕсли;
ТипИсходнойКоллекции = ТипЗнч(ИсходнаяКоллекция);
Если Ложь
Или ТипИсходнойКоллекции = Тип("ДеревоЗначений")
Или ТипИсходнойКоллекции = Тип("ТаблицаЗначений")
Тогда
Коллекция = ИсходнаяКоллекция.Колонки;
Колонки = Коллекция;
Иначе//Если ТипИсходнойКоллекции = Тип("Структура") Тогда
Коллекция = ИсходнаяКоллекция;
Если ТипЗнч(ИсходнаяКоллекция) = Тип("Структура") Тогда
Пустышка = Новый ТаблицаЗначений;
Колонки = Пустышка.Колонки;
Иначе
Колонки = Коллекция;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(Описатель) = Тип("ОбъектМетаданных") Тогда
Реквизиты = Описатель.Реквизиты;
Иначе
Реквизиты = Описатель;
КонецЕсли;
Для Каждого Реквизит Из Реквизиты Цикл
Если ТипЗнч(Реквизит) = Тип("РеквизитФормы") Тогда
Колонки.Добавить(Реквизит.Имя, Реквизит.ТипЗначения, Реквизит.Заголовок);
ИначеЕсли ТипЗнч(Реквизит) = Тип("ОбъектМетаданных") Тогда
Колонки.Добавить(Реквизит.Имя, Реквизит.Тип, Реквизит.Представление());
ИначеЕсли ТипЗнч(Реквизит) = Тип("ПолеНастройки") Тогда
Колонки.Добавить(Реквизит.Имя, Реквизит.ТипЗначения, Реквизит.Представление);
Иначе
ВызватьИсключение "Неизвестный тип описания реквизита """ + ТипЗнч(Реквизит) + """";
КонецЕсли;
КонецЦикла;
Если ТипЗнч(Коллекция) = Тип("Структура") Тогда
Для Каждого Колонка Из Колонки Цикл
Коллекция.Вставить(Колонка.Имя, Колонка.ТипЗначения.ПривестиЗначение(Неопределено));
КонецЦикла;
КонецЕсли;
Возврат ИсходнаяКоллекция;
КонецФункции
Функция ПолучитьСписокБазПользователяОСЛкс(Знач ПолноеИмяФайла = Неопределено, ВычислятьРазмерыКаталогов = Ложь, ВычислятьПоследнегоПользователя = Ложь,
ТаблицаПриемник = Неопределено) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если ТаблицаПриемник = Неопределено Тогда
Результат = мПлатформа.СписокБазПользователя.ВыгрузитьКолонки();
Иначе
Результат = ТаблицаПриемник;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
Результат = мПлатформа.СписокБазПользователя;
#КонецЕсли
Если ПолноеИмяФайла = Неопределено Тогда
лПолноеИмяФайла = ИмяФайлаОбщегоСпискаИнфобазВсехПользователейОСЛкс();
Если ЗначениеЗаполнено(лПолноеИмяФайла) Тогда
ПолучитьСписокБазПользователяОСЛкс(лПолноеИмяФайла,,, Результат);
КонецЕсли;
лПолноеИмяФайла = ИмяФайлаОбщегоСпискаИнфобазТекущегоПользователяОСЛкс();
Если ЗначениеЗаполнено(лПолноеИмяФайла) Тогда
ПолучитьСписокБазПользователяОСЛкс(лПолноеИмяФайла,,, Результат);
КонецЕсли;
ПолноеИмяФайла = ИмяФайлаСпискаИнфобазПользователяОСЛкс();
КонецЕсли;
Если ЛиИдентификацияБазыВСпискеПоНаименованиюЛкс() Тогда
КолонкаConnect = Неопределено;
Иначе
КолонкаConnect = Результат.Колонки.Connect;
КонецЕсли;
Файл = Новый Файл(ПолноеИмяФайла);
ДобавленныеСтроки = Новый Массив;
Если Файл.Существует() Тогда
ЧтениеФайла = Новый ЧтениеТекста;
Попытка
ЧтениеФайла.Открыть(ПолноеИмяФайла, КодировкаТекста.UTF8);
СтрокаИзФайла = ЧтениеФайла.ПрочитатьСтроку();
Исключение
// Файл существует, но недоступен http://www.hostedredmine.com/issues/882846
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
СтрокаИзФайла = Неопределено;
КонецПопытки;
Пока СтрокаИзФайла <> Неопределено Цикл
Если СтрДлина(СокрЛП(СтрокаИзФайла)) Тогда
ТекущаяСтрока = СокрЛП(СтрокаИзФайла);
Если Лев(ТекущаяСтрока, 1) = "[" Тогда
НовоеНаименование = Сред(ТекущаяСтрока, 2, СтрДлина(ТекущаяСтрока) - 2); // Убираем квадратные скобки вначале и вконце
Если КолонкаConnect = Неопределено Тогда
НоваяСтрока = Результат.Найти(НРег(НовоеНаименование), "КлючСтроки");
Если НоваяСтрока <> Неопределено Тогда
НоваяСтрока = Неопределено;
СтрокаИзФайла = ЧтениеФайла.ПрочитатьСтроку();
Продолжить;
КонецЕсли;
КонецЕсли;
НоваяСтрока = Результат.Добавить();
НоваяСтрока.ФайлСписка = ПолноеИмяФайла;
НоваяСтрока.Наименование = НовоеНаименование;
ДобавленныеСтроки.Добавить(НоваяСтрока);
КонецЕсли;
ИмяКолонки = ПервыйФрагментЛкс(ТекущаяСтрока, "=", Ложь);
Если НоваяСтрока <> Неопределено И ЗначениеЗаполнено(ИмяКолонки) Тогда
Колонка = Результат.Колонки.Найти(ИмяКолонки);
Если Колонка <> Неопределено Тогда
ПредставлениеЗначения = Сред(ТекущаяСтрока, СтрДлина(ИмяКолонки + "=") + 1);
ЗначениеПараметра = Колонка.ТипЗначения.ПривестиЗначение(ПредставлениеЗначения);
НоваяСтрока[Колонка.Имя] = ЗначениеПараметра;
Если Колонка = КолонкаConnect Тогда
СуществующаяСтрока = Результат.Найти(НРег(ЗначениеПараметра), "КлючСтроки");
Если СуществующаяСтрока <> Неопределено Тогда
Результат.Удалить(НоваяСтрока);
ДобавленныеСтроки.Удалить(ДобавленныеСтроки.ВГраница());
НоваяСтрока = Неопределено;
СтрокаИзФайла = ЧтениеФайла.ПрочитатьСтроку();
Продолжить;
КонецЕсли;
КонецЕсли;
Иначе
Пустышка = 0; // Для отладки
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтрокаИзФайла = ЧтениеФайла.ПрочитатьСтроку();
КонецЦикла;
КонецЕсли;
КаталогФайловыхКэшей = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс();
КаталогНастроекИнфобаз = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс(Ложь);
Для Каждого СтрокаТЧ Из ДобавленныеСтроки Цикл
СтрокаТЧ.КаталогКэша = КаталогФайловыхКэшей + "\" + СтрокаТЧ.ID;
СтрокаТЧ.КаталогНастроек = КаталогНастроекИнфобаз + "\" + СтрокаТЧ.ID;
Если ЛиИдентификацияБазыВСпискеПоНаименованиюЛкс() Тогда
СтрокаТЧ.КлючСтроки = НРег(СтрокаТЧ.Наименование);
Иначе
СтрокаТЧ.КлючСтроки = НРег(СтрокаТЧ.Connect);
КонецЕсли;
СтрокаТЧ.НСтрокаСоединения = НРег(СтрокаТЧ.Connect);
СтрокаСоединенияКластера = НСтр(СтрокаТЧ.Connect, "Srvr");
//СтруктураURI = СтруктураURIЛкс(СтрокаСоединенияКластера); // Здесь может быть строка одновременно нескольких кластеров - tcp://rocket:1541,tcp://rocket1:1741
//СтрокаТЧ.ИмяКомпьютера = ПервыйФрагментЛкс(СтруктураURI.ИмяСервера, ":");
Если ВычислятьПоследнегоПользователя Тогда
ИмяФайлаПоследнегоПользователя = СтрокаТЧ.КаталогНастроек + "\def.usr";
ФайлПоследнегоПользователя = Новый Файл(ИмяФайлаПоследнегоПользователя);
Если ФайлПоследнегоПользователя.Существует() Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ФайлПоследнегоПользователя.ПолноеИмя);
СтрокаТЧ.ПоследнийПользователь = СтрокаМеждуМаркерамиЛкс(ТекстовыйДокумент.ПолучитьТекст(), "{""", """}");
КонецЕсли;
КонецЕсли;
Если ВычислятьРазмерыКаталогов Тогда
СтрокаТЧ.РазмерКэшаКБ = ВычислитьРазмерКаталогаЛкс(СтрокаТЧ.КаталогКэша) / 1024;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ЛиИдентификацияБазыВСпискеПоНаименованиюЛкс() Экспорт
Результат = ирКэш.НомерВерсииПлатформыЛкс() > 803000;
Возврат Результат;
КонецФункции
Функция КлючБазыВСпискеПользователяЛкс(выхКлючомЯвляетсяСтрокаСоединения = Ложь) Экспорт
выхКлючомЯвляетсяСтрокаСоединения = Не ЛиИдентификацияБазыВСпискеПоНаименованиюЛкс();
КлючБазыВСпискеПользователя = ирКэш.КлючБазыВСпискеПользователяИзКоманднойСтрокиЛкс();
Если Не ЗначениеЗаполнено(КлючБазыВСпискеПользователя) Тогда
КлючБазыВСпискеПользователя = СтрокаСоединенияИнформационнойБазы();
выхКлючомЯвляетсяСтрокаСоединения = Истина;
КонецЕсли;
Возврат КлючБазыВСпискеПользователя;
КонецФункции
Функция ИмяФайлаОбщегоСпискаИнфобазТекущегоПользователяОСЛкс(ИмяКонфигФайла = "") Экспорт
ShellApplication = Новый COMobject("Shell.Application");
ВсеЮзеры = ShellApplication.NameSpace(26).Self.Path;
ИмяКонфигФайла = ВсеЮзеры + "\1C\1CEStart\1CEStart.cfg";
Текст = Новый ТекстовыйДокумент;
Текст.Прочитать(ИмяКонфигФайла);
СписокИмен = "";
Для Счетчик = 1 По СтрЧислоСтрок(Текст.ПолучитьТекст()) Цикл
СтрокаТекста = СокрЛ(Текст.ПолучитьСтроку(Счетчик));
Если Найти(СтрокаТекста, "CommonInfoBases") = 1 Тогда
Результат = Сред(СтрокаТекста, Найти(СтрокаТекста, "=") + 1);
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ИмяФайлаОбщегоСпискаИнфобазВсехПользователейОСЛкс(ИмяКонфигФайла = "") Экспорт
ShellApplication = Новый COMobject("Shell.Application");
ВсеЮзеры = ShellApplication.NameSpace(35).Self.Path;
ИмяКонфигФайла = ВсеЮзеры + "\1C\1CEStart\1CEStart.cfg";
Текст = Новый ТекстовыйДокумент;
Текст.Прочитать(ИмяКонфигФайла);
СписокИмен = "";
Для Счетчик = 1 По СтрЧислоСтрок(Текст.ПолучитьТекст()) Цикл
СтрокаТекста = СокрЛ(Текст.ПолучитьСтроку(Счетчик));
Если Найти(СтрокаТекста, "CommonInfoBases") = 1 Тогда
Результат = Сред(СтрокаТекста, Найти(СтрокаТекста, "=") + 1);
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
// Получает строку для установки порядка. Пример "Контрагент убыв, Номенклатура.Код возр".
//
// Параметры:
// Порядок – Порядок.
//
// Возвращаемое значение:
// Строка - для установки порядка.
//
Функция ПолучитьСтрокуПорядкаЛкс(Порядок) Экспорт
Строка = "";
Для Каждого ЭлементПорядка Из Порядок Цикл
Строка = Строка + ", " + ЭлементПорядка.ПутьКДанным + " ";
Если ЭлементПорядка.Направление = НаправлениеСортировки.Возр Тогда
Строка = Строка + "возр";
Иначе
Строка = Строка + "убыв";
КонецЕсли;
КонецЦикла;
Возврат Сред(Строка, 2);
КонецФункции // ПолучитьСтрокуПорядкаЛкс()
// Выполняет текст на внутреннем языке. Применяется для безопасного выполнения произвольного кода.
// Безопасность заключается в том, что нет свойств локального контекста
// и недоступны доопределенные Свойства глобального контекста.
//
// Параметры:
// ТекстДляВыполнения – Строка;
// *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля.
//
Процедура ВыполнитьВКонтекстеОбщегоМодуляЛкс(ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт
Выполнить(ТекстДляВыполнения);
КонецПроцедуры // ВыполнитьВКонтекстеОбщегоМодуляЛкс()
// Получает копию произвольного объекта. Копирование производится через сериализацию.
//
// Параметры:
// пОбъект – Произвольное – сохраняемое значение;
// ИспользоватьXDTO - Булево - выполнять через ОбъектXDTO, для типов компоновки данных работает быстрее в 2 раза, но не у всех типов есть XDTO отображение, позволяет обходить платформенные ошибки десериализации компоновки
// Истина - не делает глубокого копирования! Применять в основном имеет смысл только для объектов системы компоновки данных
//
// Возвращаемое значение:
// Произвольный - копия объекта.
//
Функция КопияОбъектаЛкс(пОбъект, ИспользоватьXDTO = Ложь) Экспорт
Если ИспользоватьXDTO Тогда
// Быстрее в 2 раза
Попытка
НовыйОбъект = СериализаторXDTO.ПрочитатьXDTO(СериализаторXDTO.ЗаписатьXDTO(пОбъект));
Исключение
// 7ы78аывраы0ав8
// https://partners.v8.1c.ru/forum/t/1918496/m/1918496
// Антибаг платформы 8.3.17-+ В настройках компоновки в элементах отбора с видом сравнения "ВСписке" в правых значениях поля компоновки при десериализации возникает ошибка.
// Чтобы ее обойти оборачиваем каждое такое поле в массив
СтрокаХмл = ирОбщий.СохранитьОбъектВВидеСтрокиXMLЛкс(пОбъект);
ДокументДом = ирОбщий.ПрочитатьТекстВДокументDOMЛкс(СтрокаХмл);
#Если Сервер И Не Сервер Тогда
ДокументДом = Новый ДокументDOM;
#КонецЕсли
РазыменовательПИ = Новый РазыменовательПространствИменDOM("w", "http://v8.1c.ru/8.1/data-composition-system/settings");
РезультатХПути = ДокументДом.ВычислитьВыражениеXPath("//w:comparisonType[text()='InList' or text()='NotInList']/following-sibling::w:right[@xsi:type='dcscor:Field']", ДокументДом,
РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
Пока Истина Цикл
УзелПравогоЗначенияОтбора = РезультатХПути.ПолучитьСледующий();
Если УзелПравогоЗначенияОтбора = Неопределено Тогда
Прервать;
КонецЕсли;
ПрефиксЯдра = УзелПравогоЗначенияОтбора.НайтиПрефикс("http://v8.1c.ru/8.1/data/core");
ПрефиксТипов = УзелПравогоЗначенияОтбора.НайтиПрефикс("http://www.w3.org/2001/XMLSchema-instance");
ПрефиксКомпоновки = УзелПравогоЗначенияОтбора.НайтиПрефикс("http://v8.1c.ru/8.1/data-composition-system/core");
НовыйВложенныйУзел = ДокументДом.СоздатьЭлемент("http://v8.1c.ru/8.1/data/core", ПрефиксЯдра + ":Value");
НовыйВложенныйУзел.УстановитьАтрибут("http://www.w3.org/2001/XMLSchema-instance", ПрефиксТипов + ":type", ПрефиксКомпоновки + ":Field");
НовыйВложенныйУзел.ТекстовоеСодержимое = УзелПравогоЗначенияОтбора.ПервыйДочерний.ТекстовоеСодержимое;
УзелПравогоЗначенияОтбора.УдалитьДочерний(УзелПравогоЗначенияОтбора.ПервыйДочерний);
УзелПравогоЗначенияОтбора.УдалитьУзелАтрибута(УзелПравогоЗначенияОтбора.Атрибуты[0]);
УзелПравогоЗначенияОтбора.ДобавитьДочерний(НовыйВложенныйУзел);
УзелПравогоЗначенияОтбора.УстановитьАтрибут("http://www.w3.org/2001/XMLSchema-instance", ПрефиксТипов + ":type", ПрефиксЯдра + ":Array");
КонецЦикла;
СтрокаХМЛ = ирОбщий.ЗаписатьДокументDOMВСтрокуЛкс(ДокументДом);
НовыйОбъект = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаХМЛ);
КонецПопытки;
Иначе
НовыйОбъект = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(пОбъект));
КонецЕсли;
Возврат НовыйОбъект;
КонецФункции
Процедура ВосстановитьОтборыКомпоновкиПослеДесериализацииЛкс(Знач НастройкаИлиГруппаОтбора) Экспорт
Если ТипЗнч(НастройкаИлиГруппаОтбора) = Тип("НастройкиКомпоновкиДанных") Тогда
#Если Сервер И Не Сервер Тогда
НастройкаИлиГруппаОтбора = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
ГруппаОтбора = НастройкаИлиГруппаОтбора.Отбор;
Иначе
ГруппаОтбора = НастройкаИлиГруппаОтбора;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ГруппаОтбора = Новый НастройкиКомпоновкиДанных;
ГруппаОтбора = НастройкаИлиГруппаОтбора.Отбор;
#КонецЕсли
// https://partners.v8.1c.ru/forum/t/1623191/m/1623191
Для Каждого ЭлементОтбора Из ГруппаОтбора.Элементы Цикл
Если ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
ВосстановитьОтборыКомпоновкиПослеДесериализацииЛкс(ЭлементОтбора);
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("Массив") Тогда
МассивЗначенияОтбора = ЭлементОтбора.ПравоеЗначение;
ИначеЕсли Истина
И ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("СписокЗначений")
И ЭлементОтбора.ПравоеЗначение.Количество() = 1
И ТипЗнч(ЭлементОтбора.ПравоеЗначение[0].Значение) = Тип("Массив")
Тогда
МассивЗначенияОтбора = ЭлементОтбора.ПравоеЗначение[0].Значение;
Иначе
МассивЗначенияОтбора = Неопределено;
КонецЕсли;
Если МассивЗначенияОтбора <> Неопределено Тогда
СписокЗначений = Новый СписокЗначений;
Для Каждого ЭлементМассива Из МассивЗначенияОтбора Цикл
Если ТипЗнч(ЭлементМассива) = Тип("ПолеКомпоновкиДанных") Тогда
// 7ы78аывраы0ав8
// https://partners.v8.1c.ru/forum/t/1918496/m/1918496
СписокЗначений = ЭлементМассива;
Прервать;
КонецЕсли;
СписокЗначений.Добавить(ЭлементМассива);
КонецЦикла;
ЭлементОтбора.ПравоеЗначение = СписокЗначений;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Находит элемент коллекции по свойству "ПутьКДанным".
//
// Параметры:
// пКоллекция – Коллекция – все элементы которой имеют свойство "ПутьКДанным";
// пПутьКДанным – Строка – искомое значение.
//
// Возвращаемое значение:
// – ЭлементКоллекции;
// Неопределено - не найден.
//
Функция НайтиЭлементКоллекцииПоПутиКДаннымЛкс(пКоллекция, пПутьКДанным) Экспорт
СуществующаяСтрока = Неопределено;
Для Каждого ЭлементКоллеции Из пКоллекция Цикл
Если ЭлементКоллеции.ПутьКДанным = пПутьКДанным Тогда
СуществующаяСтрока = ЭлементКоллеции;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат СуществующаяСтрока;
КонецФункции // НайтиЭлементКоллекцииПоПутиКДаннымЛкс()
// Находит поле настройки по пути к данным.
//
// Параметры:
// пПоляНастройки – ПоляНастройки;
// пПутьКДанным – Строка – путь к данным поля в виде разыменовывания;
// *пПутьКТекущемуПолю - Строка, "" - путь к текущему полю.
//
// Возвращаемое значение:
// ПолеНастройки – найденное поле;
// Неопределено - иначе.
//
Функция НайтиПолеНастройкиПоПутиКДаннымЛкс(пПоляНастройки, пПутьКДанным, пПутьКТекущемуПолю = "") Экспорт
ПоляНастройки = пПоляНастройки;
МассивФрагментов = СтрРазделитьЛкс(пПутьКДанным);
ТекущееПоле = Неопределено;
Для Каждого Фрагмент Из МассивФрагментов Цикл
пПутьКТекущемуПолю = пПутьКТекущемуПолю + ?(пПутьКТекущемуПолю = "", "", ".") + Фрагмент;
ТекущееПоле = НайтиЭлементКоллекцииПоПутиКДаннымЛкс(ПоляНастройки, пПутьКТекущемуПолю);
Если ТекущееПоле = Неопределено Тогда
Прервать;
КонецЕсли;
ПоляНастройки = ТекущееПоле.Поля;
КонецЦикла;
Возврат ТекущееПоле;
КонецФункции // НайтиПолеНастройкиПоПутиКДаннымЛкс()
// Копирует один элемент отбора в другой. Если Использование = Ложь, то копируется только оно.
//
// Параметры:
// пЭлементОтбораПриемник – ЭлементОтбора – куда копируем;
// пЭлементОтбораИсточник - ЭлементОтбора - откуда копируем.
//
Процедура СкопироватьЭлементОтбораЛкс(пЭлементОтбораПриемник, пЭлементОтбораИсточник) Экспорт
ЗаполнитьЗначенияСвойств(пЭлементОтбораПриемник, пЭлементОтбораИсточник, "Представление, Использование");
МассивСвойствЭлементаОтбора = Новый Массив;
МассивСвойствЭлементаОтбора.Добавить("ВидСравнения");
МассивСвойствЭлементаОтбора.Добавить("Значение");
МассивСвойствЭлементаОтбора.Добавить("ЗначениеС");
МассивСвойствЭлементаОтбора.Добавить("ЗначениеПо");
Для Каждого Свойство Из МассивСвойствЭлементаОтбора Цикл
Значение = пЭлементОтбораИсточник[Свойство];
Если пЭлементОтбораПриемник[Свойство] <> Значение Тогда
пЭлементОтбораПриемник[Свойство] = Значение;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // СкопироватьЭлементОтбораЛкс()
Функция ТрансформироватьОтборВОтборКомпоновкиЛкс(Знач ОтборКомпоновкиДанных, Знач ЭлементыОтбора, Знач СоответствиеИмен = Неопределено,
Знач ПроверятьДоступностьПолей = Ложь, Знач ДоступныеПоляОтбора = Неопределено, ТолькоИспользуемые = Истина, ОчищатьПриемник = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый НастройкиКомпоновкиДанных;
ОтборКомпоновкиДанных = Пустышка.Отбор;
#КонецЕсли
Если СоответствиеИмен = Неопределено Тогда
СоответствиеИмен = Новый ТаблицаЗначений();
СоответствиеИмен.Колонки.Добавить("Источник");
//СоответствиеИмен.Колонки.Добавить("Приемник");
КонецЕсли;
Если ДоступныеПоляОтбора = Неопределено Тогда
ДоступныеПоляОтбора = ОтборКомпоновкиДанных.ДоступныеПоляОтбора;
КонецЕсли;
Если ОчищатьПриемник Тогда
ОтборКомпоновкиДанных.Элементы.Очистить();
КонецЕсли;
ИндексГраницы = ЭлементыОтбора.Количество() - 1;
ИзмененныеЭлементыОтбора = Новый Массив;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Для Каждого ЭлементОтбора Из ЭлементыОтбора Цикл
Если Истина
И ТолькоИспользуемые
И Не ЭлементОтбора.Использование
Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
ПриемникОтбора = ОтборКомпоновкиДанных.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ЗаполнитьЗначенияСвойств(ПриемникОтбора, ЭлементОтбора);
ТрансформироватьОтборВОтборКомпоновкиЛкс(ПриемникОтбора, ЭлементОтбора.Элементы, СоответствиеИмен, ПроверятьДоступностьПолей, ДоступныеПоляОтбора, ТолькоИспользуемые);
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
Если ТипЗнч(ЭлементОтбора.ЛевоеЗначение) <> Тип("ПолеКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
//ПутьКДаннымЛевый = Неопределено;
//Если ТипЗнч(ЭлементОтбора.ЛевоеЗначение) = Тип("ПолеКомпоновкиДанных") Тогда
ПутьКДаннымЛевый = "" + ЭлементОтбора.ЛевоеЗначение;
//Иначе
// ЛевоеЗначение = ЭлементОтбора.ЛевоеЗначение;
//КонецЕсли;
ПутьКДаннымПравый = Неопределено;
Если ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("ПолеКомпоновкиДанных") Тогда
ПутьКДаннымПравый = "" + ЭлементОтбора.ПравоеЗначение;
Иначе
ПравоеЗначение = ЭлементОтбора.ПравоеЗначение;
КонецЕсли;
Иначе
ПутьКДаннымЛевый = ЭлементОтбора.ПутьКДанным;
ПутьКДаннымПравый = Неопределено;
ПравоеЗначение = ЭлементОтбора.Значение;
КонецЕсли;
//Если ПутьКДаннымЛевый <> Неопределено Тогда
МассивФрагментов = СтрРазделитьЛкс(ПутьКДаннымЛевый);
СтрокаИсточника = СоответствиеИмен.Найти(НРег(МассивФрагментов[0]), "Источник");
Если СтрокаИсточника <> Неопределено Тогда
МассивФрагментов[0] = СтрокаИсточника.Приемник;
КонецЕсли;
ПутьКДанным = СтрСоединитьЛкс(МассивФрагментов, ".");
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
лВидСравнения = ЭлементОтбора.ВидСравнения;
Иначе
СтрокаВидаСравнения = мПлатформа.СоответствиеВидовСравнения.Найти(ЭлементОтбора.ВидСравнения, "Построитель");
Если СтрокаВидаСравнения = Неопределено Тогда
Если ЭлементОтбора.ВидСравнения = ВидСравнения.Интервал Тогда
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеС, ВидСравненияКомпоновкиДанных.Больше,, Ложь, ЭлементОтбора.Использование);
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеПо, ВидСравненияКомпоновкиДанных.Меньше,, Ложь, ЭлементОтбора.Использование);
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяГраницы Тогда
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеС, ВидСравненияКомпоновкиДанных.БольшеИлиРавно,, Ложь, ЭлементОтбора.Использование);
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеПо, ВидСравненияКомпоновкиДанных.МеньшеИлиРавно,, Ложь, ЭлементОтбора.Использование);
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяНачало Тогда
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеС, ВидСравненияКомпоновкиДанных.БольшеИлиРавно,, Ложь, ЭлементОтбора.Использование);
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеПо, ВидСравненияКомпоновкиДанных.Меньше,, Ложь, ЭлементОтбора.Использование);
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяОкончание Тогда
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеС, ВидСравненияКомпоновкиДанных.Больше,, Ложь, ЭлементОтбора.Использование);
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеПо, ВидСравненияКомпоновкиДанных.МеньшеИлиРавно,, Ложь, ЭлементОтбора.Использование);
КонецЕсли;
Продолжить;
КонецЕсли;
лВидСравнения = СтрокаВидаСравнения.Компоновка;
КонецЕсли;
ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ПутьКДанным);
ПолеОтбора = Неопределено;
Для Каждого лЭлементОтбора Из ОтборКомпоновкиДанных.Элементы Цикл
Если Истина
И ТипЗнч(лЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных")
И лЭлементОтбора.ЛевоеЗначение = ПолеКомпоновки
И ИзмененныеЭлементыОтбора.Найти(лЭлементОтбора) = Неопределено
Тогда
ПолеОтбора = лЭлементОтбора;
ИзмененныеЭлементыОтбора.Добавить(ПолеОтбора);
Прервать;
КонецЕсли;
КонецЦикла;
Если ПолеОтбора = Неопределено Тогда
ДоступноеПоле = ДоступныеПоляОтбора.НайтиПоле(ПолеКомпоновки);
Если Истина
И ПроверятьДоступностьПолей
И ДоступноеПоле = Неопределено
Тогда
Продолжить;
КонецЕсли;
ПолеОтбора = ОтборКомпоновкиДанных.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ПолеОтбора.ЛевоеЗначение = ПолеКомпоновки;
КонецЕсли;
//Иначе
// ПолеОтбора.ПравоеЗначение = ЛевоеЗначение;
//КонецЕсли;
Если ПутьКДаннымПравый <> Неопределено Тогда
МассивФрагментов = СтрРазделитьЛкс(ПутьКДаннымПравый);
СтрокаИсточника = СоответствиеИмен.Найти(НРег(МассивФрагментов[0]), "Источник");
Если СтрокаИсточника <> Неопределено Тогда
МассивФрагментов[0] = СтрокаИсточника.Приемник;
КонецЕсли;
ПутьКДанным = СтрСоединитьЛкс(МассивФрагментов, ".");
ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ПутьКДанным);
ПолеОтбора.ПравоеЗначение = ПолеКомпоновки;
Иначе
ПолеОтбора.ПравоеЗначение = ПравоеЗначение;
КонецЕсли;
ПолеОтбора.ВидСравнения = лВидСравнения;
ПолеОтбора.Использование = ЭлементОтбора.Использование;
КонецЦикла;
КонецФункции
// Порт СкопироватьОтборЛкс.
Процедура СкопироватьОтборЛюбойЛкс(пОтборПриемник, пОтборИсточник, ТолькоИспользуемые = Ложь, ПроверятьДоступность = Ложь, ОчищатьПриемник = Истина) Экспорт
Если Истина
И ТипЗнч(пОтборИсточник) = Тип("Отбор")
И ТипЗнч(пОтборПриемник) = Тип("Отбор")
Тогда
СкопироватьОтборПостроителяЛкс(пОтборПриемник, пОтборИсточник, , ТолькоИспользуемые, ОчищатьПриемник);
ИначеЕсли Истина
И ТипЗнч(пОтборИсточник) = Тип("Структура")
И ТипЗнч(пОтборПриемник) = Тип("Отбор")
Тогда
Для Каждого КлючИЗначение Из пОтборИсточник Цикл
ЭлементОтбора = пОтборПриемник.Найти(КлючИЗначение.Ключ);
Если ЭлементОтбора <> Неопределено Тогда
УстановитьЭлементОтбораЛкс(ЭлементОтбора,, КлючИЗначение.Значение);
КонецЕсли;
КонецЦикла;
ИначеЕсли Истина
И ТипЗнч(пОтборИсточник) = Тип("ОтборКомпоновкиДанных")
И ТипЗнч(пОтборПриемник) = Тип("ОтборКомпоновкиДанных")
Тогда
СкопироватьЭлементыКомпоновкиЛкс(пОтборПриемник, пОтборИсточник, ПроверятьДоступность, ОчищатьПриемник);
ИначеЕсли Истина
И ТипЗнч(пОтборИсточник) = Тип("Структура")
И ТипЗнч(пОтборПриемник) = Тип("ОтборКомпоновкиДанных")
Тогда
Для Каждого КлючИЗначение Из пОтборИсточник Цикл
ЭлементОтбора = НайтиДобавитьЭлементОтбораКомпоновкиЛкс(пОтборПриемник, КлючИЗначение.Ключ, КлючИЗначение.Значение);
#Если Сервер И Не Сервер Тогда
ЭлементОтбора = Новый НастройкиКомпоновкиДанных;
ЭлементОтбора = ЭлементОтбора.Отбор.Элементы.Добавить();
#КонецЕсли
ПроверитьВключитьЭлементНастроекКомпоновкиВПользовательскиеНастройки(ЭлементОтбора);
КонецЦикла;
ИначеЕсли Истина
И ТипЗнч(пОтборИсточник) = Тип("Отбор")
И ТипЗнч(пОтборПриемник) = Тип("ОтборКомпоновкиДанных")
Тогда
ТрансформироватьОтборВОтборКомпоновкиЛкс(пОтборПриемник, пОтборИсточник,, ПроверятьДоступность,, ТолькоИспользуемые, ОчищатьПриемник);
КонецЕсли;
КонецПроцедуры // СкопироватьОтборДинамическогоСпискаЛкс()
// Важно: установка идентификатора должна выполняться в конце настройки элемента,
// иначе он будет скопирован в пользовательские настройки частично заполненным.
Процедура ПроверитьВключитьЭлементНастроекКомпоновкиВПользовательскиеНастройки(ЭлементНастроек, ИД = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый НастройкиКомпоновкиДанных;
ЭлементНастроек = Пустышка.Отбор;
#КонецЕсли
Представление = "" + ЭлементНастроек;
Если ТипЗнч(ЭлементНастроек) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
Если ЗначениеЗаполнено(ЭлементНастроек.Представление) Тогда
Представление = ЭлементНастроек.Представление;
Иначе
Представление = ЭлементНастроек.ЛевоеЗначение;
КонецЕсли;
КонецЕсли;
Попытка
ЭлементНастроек.ПредставлениеПользовательскойНастройки = Представление;
Исключение
// Это ОтборКомпоновкиДанных внутри пользовательских настроек
КонецПопытки;
Если ЗначениеЗаполнено(ИД) Тогда
УИД = Новый УникальныйИдентификатор(ИД);
Иначе
УИД = Новый УникальныйИдентификатор;
КонецЕсли;
ЭлементНастроек.ИдентификаторПользовательскойНастройки = УИД;
КонецПроцедуры
// Копирует элементы из одной коллекции в другую
//
Процедура СкопироватьЭлементыКомпоновкиЛкс(ПриемникЗначения, ИсточникЗначения, ПроверятьДоступность = Ложь, ОчищатьПриемник = Истина) Экспорт
Если Ложь
Или ТипЗнч(ИсточникЗначения) = Тип("УсловноеОформлениеКомпоновкиДанных")
ИЛИ ТипЗнч(ИсточникЗначения) = Тип("ВариантыПользовательскогоПоляВыборКомпоновкиДанных")
ИЛИ ТипЗнч(ИсточникЗначения) = Тип("ОформляемыеПоляКомпоновкиДанных")
ИЛИ ТипЗнч(ИсточникЗначения) = Тип("ЗначенияПараметровДанныхКомпоновкиДанных")
Тогда
СоздаватьПоТипу = Ложь;
Иначе
СоздаватьПоТипу = Истина;
КонецЕсли;
ПриемникЭлементов = ПриемникЗначения.Элементы;
ИсточникЭлементов = ИсточникЗначения.Элементы;
Если ОчищатьПриемник Тогда
ПриемникЭлементов.Очистить();
КонецЕсли;
Для каждого ЭлементИсточник Из ИсточникЭлементов Цикл
Если ТипЗнч(ЭлементИсточник) = Тип("ЭлементПорядкаКомпоновкиДанных") Тогда
// Элементы порядка добавляем в начало
Индекс = ИсточникЭлементов.Индекс(ЭлементИсточник);
ЭлементПриемник = ПриемникЭлементов.Вставить(Индекс, ТипЗнч(ЭлементИсточник));
Иначе
Если СоздаватьПоТипу Тогда
ЭлементПриемник = ПриемникЭлементов.Добавить(ТипЗнч(ЭлементИсточник));
Иначе
ЭлементПриемник = ПриемникЭлементов.Добавить();
КонецЕсли;
КонецЕсли;
ЗаполнитьЗначенияСвойств(ЭлементПриемник, ЭлементИсточник);
// В некоторых коллекциях необходимо заполнить другие коллекции
Если ТипЗнч(ИсточникЭлементов) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда
СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник.Поля, ЭлементИсточник.Поля);
СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник.Отбор, ЭлементИсточник.Отбор);
ЗаполнитьЭлементыКомпоновкиЛкс(ЭлементПриемник.Оформление, ЭлементИсточник.Оформление);
ИначеЕсли ТипЗнч(ИсточникЭлементов) = Тип("КоллекцияВариантовПользовательскогоПоляВыборКомпоновкиДанных") Тогда
СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник.Отбор, ЭлементИсточник.Отбор);
КонецЕсли;
// В некоторых элементах коллекции необходимо заполнить другие коллекции
Если ТипЗнч(ЭлементИсточник) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник, ЭлементИсточник);
ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ГруппаВыбранныхПолейКомпоновкиДанных") Тогда
СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник, ЭлементИсточник);
ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ПользовательскоеПолеВыборКомпоновкиДанных") Тогда
СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник.Варианты, ЭлементИсточник.Варианты);
ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ПользовательскоеПолеВыражениеКомпоновкиДанных") Тогда
ЭлементПриемник.УстановитьВыражениеДетальныхЗаписей (ЭлементИсточник.ПолучитьВыражениеДетальныхЗаписей());
ЭлементПриемник.УстановитьВыражениеИтоговыхЗаписей(ЭлементИсточник.ПолучитьВыражениеИтоговыхЗаписей());
ЭлементПриемник.УстановитьПредставлениеВыраженияДетальныхЗаписей(ЭлементИсточник.ПолучитьПредставлениеВыраженияДетальныхЗаписей ());
ЭлементПриемник.УстановитьПредставлениеВыраженияИтоговыхЗаписей(ЭлементИсточник.ПолучитьПредставлениеВыраженияИтоговыхЗаписей ());
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Заполняет элементы одной коллекции из другой
//
Процедура ЗаполнитьЭлементыКомпоновкиЛкс(ПриемникЗначения, ИсточникЗначения, ПервыйУровень = Неопределено) Экспорт
Если ТипЗнч(ПриемникЗначения) = Тип("КоллекцияЗначенийПараметровКомпоновкиДанных") Тогда
КоллекцияЗначений = ИсточникЗначения;
Иначе
КоллекцияЗначений = ИсточникЗначения.Элементы;
КонецЕсли;
Для каждого ЭлементИсточник Из КоллекцияЗначений Цикл
Если ПервыйУровень = Неопределено Тогда
ЭлементПриемник = ПриемникЗначения.НайтиЗначениеПараметра(ЭлементИсточник.Параметр);
Иначе
ЭлементПриемник = ПервыйУровень.НайтиЗначениеПараметра(ЭлементИсточник.Параметр);
КонецЕсли;
Если ЭлементПриемник = Неопределено Тогда
Продолжить;
КонецЕсли;
ЗаполнитьЗначенияСвойств(ЭлементПриемник, ЭлементИсточник);
Если ТипЗнч(ЭлементИсточник) = Тип("ЗначениеПараметраКомпоновкиДанных") Тогда
Если ЭлементИсточник.ЗначенияВложенныхПараметров.Количество() <> 0 Тогда
ЗаполнитьЭлементыКомпоновкиЛкс(ЭлементПриемник.ЗначенияВложенныхПараметров, ЭлементИсточник.ЗначенияВложенныхПараметров, ПриемникЗначения);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Копирует объект Отбор в другой объект Отбор.
// Если нужно, в приемнике создаются отсутствующие элементы отбора.
//
// Параметры:
// пОтборПриемник – Отбор – куда копируем;
// пОтборИсточник - Отбор, Структура - откуда копируем;
// пСоздаватьОтсутствующие - Булево, *Ложь - признак создания отсутствующих элементов отбора в приемнике.
//
Процедура СкопироватьОтборПостроителяЛкс(ОтборПриемник, ОтборИсточник, СоздаватьОтсутствующие = Истина, ТолькоИспользуемые = Ложь, ОчищатьПриемник = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый ПостроительЗапроса;
ОтборПриемник = Пустышка.Отбор;
#КонецЕсли
Если ОчищатьПриемник Тогда
ОтборПриемник.Сбросить();
КонецЕсли;
//Если пСоздаватьОтсутствующие Тогда
// ДоступныеПоля = пОтборПриемник.ПолучитьДоступныеПоля();
//КонецЕсли;
Для Каждого ЭлементОтбораИсточника Из ОтборИсточник Цикл
Если Истина
И ТолькоИспользуемые
И Не ЭлементОтбораИсточника.Использование
Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементОтбораИсточника) = Тип("КлючИЗначение") Тогда
ЭлементОтбораИсточника = ЭлементОтбораИсточника.Значение;
КонецЕсли;
//Если ЭлементОтбораИсточника.Имя = "" Тогда
// СообщитьЛкс("Невозможно определить элемент отбора приемника при копировании отбора.",
// СтатусСообщения.Внимание);
// Продолжить;
//КонецЕсли;
ЭлементОтбораПриемника = ОтборПриемник.Найти(ЭлементОтбораИсточника.Имя);
Если ЭлементОтбораПриемника = Неопределено Тогда
Если Истина
И СоздаватьОтсутствующие
//И НайтиПолеНастройкиПоПутиКДаннымЛкс(ДоступныеПоля, ЭлементОтбораИсточника.ПутьКДанным) <> Неопределено
Тогда
Попытка
ЭлементОтбораПриемника = ОтборПриемник.Добавить(ЭлементОтбораИсточника.ПутьКДанным, ЭлементОтбораИсточника.Имя);
Исключение
Продолжить;
КонецПопытки;
Иначе
Продолжить;
КонецЕсли;
КонецЕсли;
СкопироватьЭлементОтбораЛкс(ЭлементОтбораПриемника, ЭлементОтбораИсточника);
КонецЦикла;
КонецПроцедуры
// Получает инвертированный вид сравнения.
//
// Параметры:
// ВидСравнения – ВидСравнения.
//
// Возвращаемое значение:
// ВидСравнения;
//
Функция ИнвертированныйВидСравненияЛкс(ВидСравненияП) Экспорт
МассивИнвертируемыхТиповСравнения = Новый Массив;
МассивИнвертируемыхТиповСравнения.Добавить("ВИерархии");
МассивИнвертируемыхТиповСравнения.Добавить("ВСписке");
МассивИнвертируемыхТиповСравнения.Добавить("Равно");
МассивИнвертируемыхТиповСравнения.Добавить("Содержит");
МассивИнвертируемыхТиповСравнения.Добавить("ВСпискеПоИерархии");
Для Каждого ТипСравнения Из МассивИнвертируемыхТиповСравнения Цикл
ПрямойТипСравнения = Вычислить("ВидСравнения." + ТипСравнения);
Если ПрямойТипСравнения = ВидСравненияП Тогда
Возврат Вычислить("ВидСравнения.Не" + ТипСравнения);
КонецЕсли;
ОбратныйТипСравнения = Вычислить("ВидСравнения.Не" + ТипСравнения);
Если ОбратныйТипСравнения = ВидСравненияП Тогда
Возврат Вычислить("ВидСравнения." + ТипСравнения);
КонецЕсли;
КонецЦикла;
Возврат ВидСравненияП;
КонецФункции
// Копирует один порядок в другой. Приемник перед копированием очищается.
//
// Параметры:
// пПорядокПриемник – Порядок – куда копируем;
// пПорядокИсточник - Порядок - откуда копируем.
//
Процедура СкопироватьПорядокПостроителяЛкс(пПорядокПриемник, пПорядокИсточник) Экспорт
пПорядокПриемник.Очистить();
Для Каждого ЭлементПорядка Из пПорядокИсточник Цикл
пПорядокПриемник.Добавить(ЭлементПорядка.ПутьКДанным, ЭлементПорядка.Имя, , ЭлементПорядка.Направление);
КонецЦикла;
КонецПроцедуры // СкопироватьПорядокЛкс()
// Трансформирует порядок в порядок компоновки.
//
// Параметры:
// ПорядокКомпоновки – ПорядокКомпоновкиДанных;
// Порядок - Порядок.
//
Процедура ТрансформироватьПорядокВПорядокКомпоновкиЛкс(ПорядокКомпоновки, Порядок) Экспорт
ЭлементыКомпоновки = ПорядокКомпоновки.Элементы;
ЭлементыКомпоновки.Очистить();
Для Каждого Элемент Из Порядок Цикл
ЭлементКомпоновки = ЭлементыКомпоновки.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
ЭлементКомпоновки.Использование = Истина;
ЭлементКомпоновки.Поле = Новый ПолеКомпоновкиДанных(Элемент.ПутьКДанным);
Если Элемент.Направление = НаправлениеСортировки.Возр Тогда
ЭлементКомпоновки.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр;
Иначе//Если Элемент.Направление = НаправлениеСортировки.Убыв Тогда
ЭлементКомпоновки.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ТрансформироватьПорядокВПорядокКомпоновкиЛкс()
Процедура СкопироватьПорядокЛюбойЛкс(ПорядокПриемник, ПорядокИсточник, ТолькоИспользуемые = Ложь, ПроверятьДоступность = Ложь, ОчищатьПриемник = Истина) Экспорт
Если Истина
И ТипЗнч(ПорядокИсточник) = Тип("Порядок")
И ТипЗнч(ПорядокПриемник) = Тип("Порядок")
Тогда
СкопироватьПорядокПостроителяЛкс(ПорядокПриемник, ПорядокИсточник);
ИначеЕсли Истина
И ТипЗнч(ПорядокИсточник) = Тип("ПорядокКомпоновкиДанных")
И ТипЗнч(ПорядокПриемник) = Тип("ПорядокКомпоновкиДанных")
Тогда
СкопироватьЭлементыКомпоновкиЛкс(ПорядокПриемник, ПорядокИсточник,, ОчищатьПриемник);
ИначеЕсли Истина
И ТипЗнч(ПорядокИсточник) = Тип("Порядок")
И ТипЗнч(ПорядокПриемник) = Тип("ПорядокКомпоновкиДанных")
Тогда
ТрансформироватьПорядокВПорядокКомпоновкиЛкс(ПорядокПриемник, ПорядокИсточник);
КонецЕсли;
КонецПроцедуры // СкопироватьПорядокЛкс()
// Возвращает текущее время в миллисекундах.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Число.
//
Функция ТекущееВремяВМиллисекундахЛкс() Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Результат = мПлатформа.ПолучитьТекущееВремяВМиллисекундах();
Возврат Результат;
КонецФункции
// Выполняет запрос. Опционально сообщает его текст и время выполнения.
// Удобно для оптимизации.
//
// Параметры:
// Запрос – Запрос;
// *ЛиОтладка - Булево, *Ложь - показывать тексты запросов и время выполнения.
// *Заголовок - Строка, *"" - название запроса.
//
// Возвращаемое значение:
// РезультатЗапроса.
//
Функция ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка = Ложь, Заголовок = "") Экспорт
Если ЛиОтладка Тогда
ВремяНачала = ТекущееВремяВМиллисекундахЛкс();
КонецЕсли;
Результат = Запрос.Выполнить();
Если ЛиОтладка Тогда
Текст = Новый ТекстовыйДокумент;
Текст.УстановитьТекст(Запрос.Текст);
Текст.Показать(Заголовок + " - " + Строка(ТекущееВремяВМиллисекундахЛкс() - ВремяНачала) + " мс");
КонецЕсли;
Возврат Результат;
КонецФункции // ВыполнитьЗамеритьЗапросЛкс()
// Получает константу языка запросов заданного типа с учетом квалификаторов описания типов.
//
// Параметры:
// ТипПоля – Тип;
// ОписаниеТипов - ОписаниеТипов - для обращения к квалификаторам.
//
// Возвращаемое значение:
// Строка.
//
Функция ПустоеЗначениеПоТипуНаЯзыкеЗапросовЛкс(ТипПоля, ОписаниеТипов = Неопределено) Экспорт
Если ТипПоля = Тип("Строка") Тогда
Результат = "ВЫРАЗИТЬ("""" КАК СТРОКА(" + Формат(ОписаниеТипов.КвалификаторыСтроки.Длина, "ЧН=; ЧГ=") + "))";
ИначеЕсли ТипПоля = Тип("Число") Тогда
Результат = "ВЫРАЗИТЬ(0 КАК ЧИСЛО(" + Формат(ОписаниеТипов.КвалификаторыЧисла.Разрядность, "ЧН=; ЧГ=") + ", "
+ Формат(ОписаниеТипов.КвалификаторыЧисла.РазрядностьДробнойЧасти, "ЧН=; ЧГ=") + "))";
ИначеЕсли ТипПоля = Тип("Дата") Тогда
Если ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Дата Тогда
Результат = "ДАТАВРЕМЯ(1,1,1)";
Иначе
Результат = "ДАТАВРЕМЯ(1,1,1,0,0,0)";
КонецЕсли;
ИначеЕсли ТипПоля = Тип("Булево") Тогда
Результат = "ЛОЖЬ";
ИначеЕсли ТипПоля = Тип("NULL") Тогда
Результат = "NULL";
ИначеЕсли ТипПоля = Тип("НЕОПРЕДЕЛЕНО") Тогда
Результат = "НЕОПРЕДЕЛЕНО";
ИначеЕсли ТипПоля = Тип("ВидДвиженияНакопления") Тогда
Результат = "ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)";
ИначеЕсли ТипПоля = Тип("ВидДвиженияБухгалтерии") Тогда
Результат = "ЗНАЧЕНИЕ(ВидДвиженияБухгалтерии.Дебет)";
ИначеЕсли ТипПоля = Тип("ВидСчета") Тогда
Результат = "ЗНАЧЕНИЕ(ВидСчета.Активный)";
Иначе
МетаданныеТипаПоля = Метаданные.НайтиПоТипу(ТипПоля);
Если МетаданныеТипаПоля <> Неопределено Тогда
// Антибаг платформы 8.1.10.50
Если ПолучитьКорневойТипКонфигурацииЛкс(МетаданныеТипаПоля) = "ПланОбмена" Тогда
Результат = "НЕОПРЕДЕЛЕНО";
Возврат Результат;
КонецЕсли;
Результат = "ЗНАЧЕНИЕ(" + МетаданныеТипаПоля.ПолноеИмя() + ".ПустаяСсылка)";
Иначе
//СообщитьЛкс("Неизвестный тип поля при формировании имитатора результата: " + ТипПоля, СтатусСообщения.Важное);
Результат = "NULL";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьКонстантуТипаЗапроса()
// Возвращает текст запроса только из констант, дающий идентичный переданному набор колонок.
//
// Параметры:
// КоллекцияПолей – КоллекцияКолонокТаблицыЗначений, КоллекцияКолонокДереваЗначений, КоллекцияКолонокРезультатаЗапроса.
//
// Возвращаемое значение:
// Текст.
//
Функция ПолучитьЗапросИмитаторКоллекцииПолейЛкс(КоллекцияПолей) Экспорт
// Формирование запроса-имитатора
ОписаниеПолей = "";
Для Каждого Колонка Из КоллекцияПолей Цикл
ОписаниеПолей = ОписаниеПолей + ", ";
МассивТипов = Колонка.ТипЗначения.Типы();
НачальноеКоличество = МассивТипов.Количество();
Для СчетчикМассивТипов = 1 По НачальноеКоличество Цикл
ТипПоля = МассивТипов[НачальноеКоличество - СчетчикМассивТипов];
Если ТипПоля = Тип("NULL") Тогда
МассивТипов.Удалить(НачальноеКоличество - СчетчикМассивТипов);
КонецЕсли;
КонецЦикла;
// Этот стиль строго фиксирован и0ие90цаун787
ОписаниеПолей = ОписаниеПолей + "ВЫБОР";
ЭтоПервыйТип = Истина;
Для Каждого ТипПоля Из МассивТипов Цикл
Если ЭтоПервыйТип Тогда
УсловиеТипа = " КОГДА ""!ИмяПоля!""=""" + Колонка.Имя + """";
ЭтоПервыйТип = Ложь;
Иначе
УсловиеТипа = " КОГДА ЛОЖЬ";
КонецЕсли;
ОписаниеПолей = ОписаниеПолей + УсловиеТипа + " ТОГДА " + ПустоеЗначениеПоТипуНаЯзыкеЗапросовЛкс(ТипПоля, Колонка.ТипЗначения);
КонецЦикла;
ОписаниеПолей = ОписаниеПолей + " КОНЕЦ КАК " + Колонка.Имя; // запрещенные имена например "Соединение" так вызывают ошибку?
КонецЦикла;
Результат = "ВЫБРАТЬ " + Сред(ОписаниеПолей, 3);
Возврат Результат;
КонецФункции
// Присваивает первому параметру второй в случае их неравенства.
// Удобно использовать для избежания установки признака модифицированности
// объекта в случае присвоения реквизиту объекта его же значения.
//
// Параметры:
// Переменная – Произвольный – переменная, которой нужно присвоить значение;
// Значение – Произвольный – присваиваемое значение;
// выхМодифицированность - Булево - в эту переменную записывается Истина, если значение было изменено в этом методе
//
// Возвращаемое значение:
// Переменная – Произвольный - конечное значение переменной.
//
Функция ПрисвоитьЕслиНеРавноЛкс(Переменная, Значение, выхМодифицированность = Неопределено) Экспорт
Если Переменная <> Значение Тогда
Переменная = Значение;
выхМодифицированность = Истина;
КонецЕсли;
Возврат Переменная;
КонецФункции
// Получает индекс картинки отражающей корневой тип и статус ссылки.
// Индекс потом используется с общей картинкой ЛксСостояниеСсылки.
//
// Параметры:
// пСсылка – Ссылка – целевая;
// *пЛиОпределятьСтатусСсылки - Булево, *Неопределено - признак необходимости определения статуса.
//
// Возвращаемое значение:
// – Число – индекс картинки.
//
Функция ПолучитьИндексКартинкиСсылкиЛкс(Ссылка, ЛиОпределятьСтатусСсылки = Неопределено, ЗначенияРеквизитов = Неопределено) Экспорт
Если ЛиОпределятьСтатусСсылки = Неопределено Тогда
//пЛиОпределятьСтатусСсылки = ПараметрыСеанса.ЛксОпределятьСтатусСсылкиПриВыводе;
ЛиОпределятьСтатусСсылки = Ложь;
КонецЕсли;
Если ЗначенияРеквизитов = Неопределено Тогда
ЗначенияРеквизитов = Ссылка;
КонецЕсли;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(Ссылка);
ИндексКартинки = -1;
Если КорневойТип = "Документ" Тогда
ИндексКартинки = 0;
Если ЛиОпределятьСтатусСсылки Тогда
Попытка
Проведен = ЗначенияРеквизитов.Проведен;
Исключение
Проведен = Ложь;
КонецПопытки;
Попытка
ПометкаУдаления = ЗначенияРеквизитов.ПометкаУдаления;
Исключение
ПометкаУдаления = Ложь;
КонецПопытки;
Если Проведен = Истина Тогда
ИндексКартинки = 0;
ИначеЕсли ПометкаУдаления = Истина Тогда
ИндексКартинки = 1;
Иначе
ИндексКартинки = 2;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "Справочник" Тогда
ИндексКартинки = 3;
Если ЛиОпределятьСтатусСсылки Тогда
Попытка
ЭтоГруппа = ЗначенияРеквизитов.ЭтоГруппа;
Исключение
ЭтоГруппа = Ложь;
КонецПопытки;
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = ?(ЭтоГруппа = Истина, 6, 4);
Иначе
ИндексКартинки = ?(ЭтоГруппа = Истина, 5, 3);
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "Задача" Тогда
ИндексКартинки = 7;
Если ЛиОпределятьСтатусСсылки Тогда
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = 8;
Иначе
ИндексКартинки = 7;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "ПланВидовХарактеристик" Тогда
ИндексКартинки = 9;
Если ЛиОпределятьСтатусСсылки Тогда
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = 10;
Иначе
ИндексКартинки = 9;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "ПланОбмена" Тогда
ИндексКартинки = 15;
Если ЛиОпределятьСтатусСсылки Тогда
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = 16;
Иначе
ИндексКартинки = 15;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "БизнесПроцесс" Тогда
ИндексКартинки = 19;
//Если пЛиОпределятьСтатусСсылки Тогда
// Если ЗначенияРеквизитов.ПометкаУдаления Тогда
// ИндексКартинки = 20;
// Иначе
// ИндексКартинки = 19;
// КонецЕсли;
//КонецЕсли;
ИначеЕсли КорневойТип = "ПланВидовРасчета" Тогда
ИндексКартинки = 17;
Если ЛиОпределятьСтатусСсылки Тогда
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = 18;
Иначе
ИндексКартинки = 17;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "Перечисление" Тогда
ИндексКартинки = 11;
ИначеЕсли КорневойТип = "РегистрСведений" Тогда
ИндексКартинки = 12;
ИначеЕсли КорневойТип = "Константа" Тогда
ИндексКартинки = 14;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции // ПолучитьИндексКартинкиСсылкиЛкс()
// Добавляет в таблицу строки из другой таблицы и в них значения колонок с совпадающими наименованиями.
//
// Параметры:
// ТаблицаИсточник - ТаблицаЗначений, ТабличнаяЧасть - откуда берутся значения;
// ТаблицаПриемник - ТаблицаЗначений, ТабличнаяЧасть - куда добавляются строки;
// *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк;
// *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет.
//
Процедура ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИсточник, ТаблицаПриемник, СтруктураЗначенийПоУмолчанию = Неопределено, СтруктураНовыхЗначений = Неопределено, ОчиститьПередЗагрузкой = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаПриемник = Новый ТаблицаЗначений;
ТаблицаИсточник = Новый ТаблицаЗначений;
СтруктураЗначенийПоУмолчанию = Новый Структура;
СтруктураНовыхЗначений = Новый Структура;
#КонецЕсли
Если ТаблицаИсточник = ТаблицаПриемник Тогда
ВызватьИсключение "Нельзя загружать коллекцию в саму себя";
КонецЕсли;
Если ОчиститьПередЗагрузкой Тогда
ТаблицаПриемник.Очистить();
КонецЕсли;
СтрокаСовпадающихКолонок = "";
Если ТипЗнч(ТаблицаИсточник) = Тип("ТаблицаЗначений") Тогда
КолонкиИсточника = ТаблицаИсточник.Колонки;
Иначе
КолонкиИсточника = ТаблицаИсточник.ВыгрузитьКолонки().Колонки;
КонецЕсли;
ЛиПриемникТаблицаЗначений = ТипЗнч(ТаблицаПриемник) = Тип("ТаблицаЗначений");
Если ЛиПриемникТаблицаЗначений Тогда
КолонкиПриемника = ТаблицаПриемник.Колонки;
Иначе
КолонкиПриемника = ТаблицаПриемник.ВыгрузитьКолонки().Колонки;
КонецЕсли;
ИмяПоляНомерСтроки = ПеревестиСтроку("НомерСтроки");
СовпадающиеКолонки = Новый Массив;
// Ранее применялась однострочная форма кода
Для каждого Колонка Из КолонкиПриемника Цикл
Если СтруктураНовыхЗначений <> Неопределено Тогда
Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если Истина
И (Ложь
Или ЛиПриемникТаблицаЗначений
Или Колонка.Имя <> ИмяПоляНомерСтроки)
И КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено
Тогда
СовпадающиеКолонки.Добавить(НРег(Колонка.Имя));
КонецЕсли;
КонецЦикла;
Если ЛиПриемникТаблицаЗначений И ТаблицаПриемник.Количество() = 0 Тогда
// Быстрый способ
Для Счетчик = 1 По ТаблицаИсточник.Количество() Цикл
ТаблицаПриемник.Добавить();
КонецЦикла;
Если СтруктураНовыхЗначений <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураНовыхЗначений Цикл
ТаблицаПриемник.ЗаполнитьЗначения(КлючИЗначение.Значение, КлючИЗначение.Ключ); // Несовместимо с ТЧ
КонецЦикла;
КонецЕсли;
Для Каждого ИмяКолонки Из СовпадающиеКолонки Цикл
Массив = ТаблицаИсточник.ВыгрузитьКолонку(ИмяКолонки);
ТаблицаПриемник.ЗагрузитьКолонку(Массив, ИмяКолонки);
КонецЦикла;
Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураЗначенийПоУмолчанию Цикл
Если СовпадающиеКолонки.Найти(НРег(КлючИЗначение.Ключ)) <> Неопределено Тогда
Продолжить;
КонецЕсли;
ТаблицаПриемник.ЗаполнитьЗначения(КлючИЗначение.Значение, КлючИЗначение.Ключ); // Несовместимо с ТЧ
КонецЦикла;
КонецЕсли;
Иначе
СтрокаСовпадающихКолонок = СтрСоединитьЛкс(СовпадающиеКолонки, ",");
Для каждого СтрокаТаблицыИсточника Из ТаблицаИсточник Цикл
СтрокаТаблицыПриемника = ТаблицаПриемник.Добавить();
Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураЗначенийПоУмолчанию);
КонецЕсли;
// Заполним значения в совпадающих колонках.
ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтрокаТаблицыИсточника, СтрокаСовпадающихКолонок);
//Для каждого ЭлементМассива Из МассивСовпадающихКолонок Цикл
// СтрокаТаблицыПриемника[ЭлементМассива] = СтрокаТаблицыИсточника[ЭлементМассива];
//КонецЦикла;
Если СтруктураНовыхЗначений <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураНовыхЗначений);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
// Непростетирована. Добавляет в дерево значений строки из другой таблицы значений и
// в них значения колонок с совпадающими наименованиями.
//
// Параметры:
// ТаблицаИсточник - таблица значений, откуда берутся значения;
// ТаблицаПриемник - таблица значений, куда добавляются строки;
// *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк;
// *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет.
//
Процедура ЗагрузитьВДеревоЗначенийЛкс(ДеревоИсточник, ДеревоПриемник, СтруктураЗначенийПоУмолчанию = Неопределено, СтруктураНовыхЗначений = Неопределено, ОчиститьПередЗагрузкой = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ДеревоИсточник = Новый ДеревоЗначений;
ДеревоПриемник = Новый ДеревоЗначений;
#КонецЕсли
СтрокаСовпадающихКолонок = "";
Разделитель = ",";
КолонкиИсточника = ДеревоИсточник.Колонки;
Для каждого Колонка Из ДеревоПриемник.Колонки Цикл
Если СтруктураНовыхЗначений <> Неопределено Тогда
Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено Тогда
СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя;
КонецЕсли;
КонецЦикла;
СтрокаСовпадающихКолонок = Сред(СтрокаСовпадающихКолонок, СтрДлина(Разделитель) + 1);
Если ОчиститьПередЗагрузкой Тогда
ДеревоПриемник.Строки.Очистить();
КонецЕсли;
ЗагрузитьВСтрокиДереваЗначенийЛкс(ДеревоИсточник, ДеревоПриемник, СтруктураЗначенийПоУмолчанию,
СтруктураНовыхЗначений, СтрокаСовпадающихКолонок);
КонецПроцедуры // ЗагрузитьВДеревоЗначенийЛкс()
// Непростетирована. Добавляет в дерево значений строки из другой таблицы значений и
// в них значения колонок с совпадающими наименованиями.
//
// Параметры:
// ТаблицаИсточник - таблица значений, откуда берутся значения;
// ТаблицаПриемник - таблица значений, куда добавляются строки;
// *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк;
// *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет.
//
Процедура ЗагрузитьВСтрокиДереваЗначенийЛкс(СтрокаРодительИсточника, СтрокаРодительПриемника,
СтруктураЗначенийПоУмолчанию, СтруктураНовыхЗначений, СтрокаСовпадающихКолонок) Экспорт
СтрокиПриемника = СтрокаРодительПриемника.Строки;
Для каждого СтрокаИсточника Из СтрокаРодительИсточника.Строки Цикл
СтрокаПриемника = СтрокиПриемника.Добавить();
Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтруктураЗначенийПоУмолчанию);
КонецЕсли;
// Заполним значения в совпадающих колонках.
ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтрокаИсточника, СтрокаСовпадающихКолонок);
Если СтруктураНовыхЗначений <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтруктураНовыхЗначений);
КонецЕсли;
ЗагрузитьВСтрокиДереваЗначенийЛкс(СтрокаИсточника, СтрокаПриемника, СтруктураЗначенийПоУмолчанию,
СтруктураНовыхЗначений, СтрокаСовпадающихКолонок);
КонецЦикла;
КонецПроцедуры // ЗагрузитьВДеревоЗначенийЛкс()
// Выводит сообщение пользователю. Способ вывода определяется модальным режимом.
// В модальном режиме используется Предупреждение(), в немодальном СообщитьЛкс().
//
// Параметры:
// ТекстСообщения – Строка;
// МодальныйРежим – Булево, *Ложь;
// *Статус - СтатусСообщения, *Неопределено.
//
Процедура СообщитьСУчетомМодальностиЛкс(ТекстСообщения, МодальныйРежим = Ложь, Статус = Неопределено) Экспорт
Если Статус = Неопределено Тогда
Статус = СтатусСообщения.Обычное;
КонецЕсли;;
#Если Клиент Тогда
Если МодальныйРежим Тогда
Предупреждение(ТекстСообщения);
Иначе
#КонецЕсли
СообщитьЛкс(ТекстСообщения, Статус);
#Если Клиент Тогда
КонецЕсли;
#КонецЕсли
КонецПроцедуры
// Сообщает итог индикации (длительность).
//
// Параметры:
// Индикатор – Структура – индикатора, полученная методом ПолучитьИндикаторПроцессаЛкс.
//
Процедура СообщитьИтогИндикацииЛкс(Индикатор) Экспорт
ТекущаяДата = ТекущаяДата();
ПрошлоВремени = ТекущаяДата - Индикатор.ДатаНачалаПроцесса;
//Часов = Цел(ПрошлоВремени / 3600);
//Осталось = ПрошлоВремени - (Часов * 3600);
//Минут = Цел(ПрошлоВремени / 60);
//Секунд = Цел(Цел(ПрошлоВремени - (Минут * 60)));
//ПрошлоВремениСтрока = Формат(Часов, "ЧЦ=2; ЧН=00; ЧВН=") + ":"
// + Формат(Минут, "ЧЦ=2; ЧН=00; ЧВН=") + ":"
// + Формат(Секунд, "ЧЦ=2; ЧН=00; ЧВН=");
ПрошлоВремениСтрока = формат(Дата(1,1,1) + ПрошлоВремени, "ДЛФ=T; ДП=");
ТекстСообщения = Индикатор.ПредставлениеПроцесса + " завершено, обработано " + Индикатор.Счетчик + " элементов за " + ПрошлоВремениСтрока + " (" + ПрошлоВремени + " сек).";
Если Индикатор.Счетчик > 0 Тогда
ТекстСообщения = ТекстСообщения + " Грубое среднее время обработки элемента - " + Формат(ПрошлоВремени / Индикатор.Счетчик * 1000, "ЧЦ=15; ЧДЦ=2; ЧН=") + " мс";
КонецЕсли;
СообщитьЛкс(ТекстСообщения);
КонецПроцедуры // ОбработатьИндикаторЛкс()
// Получает более подробное представление значения, чем штатное приведение к строковому типу.
//
// Параметры:
// Значение – Произвольный – что нужно представить.
//
// Возвращаемое значение:
// Строка – представление.
//
Функция РасширенноеПредставлениеЗначенияЛкс(Значение, КолонкаТабличногоПоля = Неопределено, ДобавлятьПредставлениеТипа = Ложь, РасширенноеПредставлениеХранилищЗначений = Ложь, ВозвращатьПредставлениеСсылки = Истина) Экспорт
Результат = "";
Разделитель = ", ";
КоличествоЭлементов = ПолучитьКоличествоЭлементовКоллекцииЛкс(Значение);
Если КоличествоЭлементов <> Неопределено Тогда
Результат = "(" + КоличествоЭлементов + ")";
КонецЕсли;
МассивПредставлений = Новый Массив;
Если ТипЗнч(Значение) = Тип("Граница") Тогда
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + Значение.ВидГраницы + ", " + Значение.Значение;
ИначеЕсли ЛиТипСсылкиТочкиМаршрутаЛкс(ТипЗнч(Значение)) Тогда
Результат = "" + Значение;
Если Не ЗначениеЗаполнено(Результат) Тогда
Результат = "(" + Значение.Имя + ")";
КонецЕсли;
ИначеЕсли ТипЗнч(Значение) = Тип("ОписаниеТипов") Тогда
#Если Сервер И Не Сервер Тогда
Значение = Новый ОписаниеТипов;
#КонецЕсли
ПредставлениеКоллекции = "";
МаксимальноеЧислоДляПредставления = 10;
Коллекция = Значение.Типы();
Для Каждого Тип Из Коллекция Цикл
МассивПредставлений.Добавить(ПредставлениеТипаЛкс(Тип, Значение));
МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1;
Если МаксимальноеЧислоДляПредставления = 0 Тогда
МассивПредставлений.Добавить("...");
Прервать;
КонецЕсли;
КонецЦикла;
Если Коллекция.Количество() > 1 Тогда
Результат = "(" + XMLСтрока(Коллекция.Количество()) + ")";
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
КонецЕсли;
Результат = Результат + СтрСоединитьЛкс(МассивПредставлений, Разделитель);
ИначеЕсли Ложь
Или ТипЗнч(Значение) = Тип("Массив")
Или ТипЗнч(Значение) = Тип("ФиксированныйМассив")
Или ТипЗнч(Значение) = Тип("СписокЗначений")
Тогда
ПредставлениеКоллекции = "";
МаксимальноеЧислоДляПредставления = 10;
НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
Для Каждого ЭлементМассива Из Значение Цикл
Если Истина
И НомерВерсииПлатформы >= 803006
И ТипЗнч(ЭлементМассива) = Тип("РасширениеКонфигурации")
Тогда
// http://www.hostedredmine.com/issues/881633
ПредставлениеЭлемента = "" + ТипЗнч(ЭлементМассива);
Иначе
ПредставлениеЭлемента = "" + ЭлементМассива;
КонецЕсли;
МассивПредставлений.Добавить(ПредставлениеЭлемента);
МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1;
Если МаксимальноеЧислоДляПредставления = 0 Тогда
МассивПредставлений.Добавить("...");
Прервать;
КонецЕсли;
КонецЦикла;
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + СтрСоединитьЛкс(МассивПредставлений, Разделитель);
ИначеЕсли ТипЗнч(Значение) = Тип("ТабличныйДокумент") Тогда
#Если Сервер И Не Сервер Тогда
Значение = Новый ТабличныйДокумент;
#КонецЕсли
Результат = "" + ТипЗнч(Значение) + "(" + Значение.ВысотаТаблицы + ")";
ИначеЕсли Ложь
Или ТипЗнч(Значение) = Тип("Структура")
Или ТипЗнч(Значение) = Тип("Соответствие")
Или ТипЗнч(Значение) = Тип("ФиксированнаяСтруктура")
Или ТипЗнч(Значение) = Тип("ФиксированноеСоответствие")
Тогда
ПредставлениеКоллекции = "";
МаксимальноеЧислоДляПредставления = 10;
Для Каждого КлючИЗначение Из Значение Цикл
МассивПредставлений.Добавить("" + КлючИЗначение.Ключ + " = " + КлючИЗначение.Значение);
МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1;
Если МаксимальноеЧислоДляПредставления = 0 Тогда
МассивПредставлений.Добавить("...");
Прервать;
КонецЕсли;
КонецЦикла;
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + СтрСоединитьЛкс(МассивПредставлений, Разделитель);
ИначеЕсли ТипЗнч(Значение) = Тип("COMОбъект") Тогда
ирПлатформа = ирКэш.Получить();
ИмяОбщегоТипа = ирПлатформа.ПолноеИмяТипаCOMОбъекта(Значение);
ПолноеИмяОсновногоКласса = СтрокаМеждуМаркерамиЛкс(ИмяОбщегоТипа, "{", "}", Ложь);
ИмяОбщегоТипа = СтрЗаменить(ИмяОбщегоТипа, ".{" + ПолноеИмяОсновногоКласса + "}", "");
Результат = Результат + ИмяОбщегоТипа;
ИначеЕсли Истина
И РасширенноеПредставлениеХранилищЗначений
И ТипЗнч(Значение) = Тип("ХранилищеЗначения")
Тогда
Результат = Результат + ТипЗнч(Значение);
ВложенноеЗначение = Значение.Получить();
Результат = Результат + ": " + ВложенноеЗначение;
ИначеЕсли ТипЗнч(Значение) = Тип("Файл") Тогда
Результат = Результат + ТипЗнч(Значение);
Результат = Результат + ": " + Значение.ПолноеИмя;
ИначеЕсли ТипЗнч(Значение) = Тип("СочетаниеКлавиш") Тогда
Результат = Результат + ТипЗнч(Значение);
Результат = Результат + ": " + ПредставлениеСочетанияКлавишЛкс(Значение);
//ИначеЕсли ТипЗнч(Значение) = Тип("Строка") Тогда
// Результат = Результат + """" + Значение + """";
Иначе
СтрокаФормата = "";
Если КолонкаТабличногоПоля <> Неопределено Тогда
СтрокаФормата = КолонкаТабличногоПоля.Формат;
// Отключено из-за потери дробной части при 0,0. Зачем это было сделано изначально, пока не разобрался
//Если Истина
// И ПустаяСтрока(СтрокаФормата)
// И ТипЗнч(КолонкаТабличногоПоля.ЭлементУправления) = Тип("ПолеВвода")
//Тогда
// КвалификаторыЧисла = КолонкаТабличногоПоля.ЭлементУправления.ТипЗначения.КвалификаторыЧисла;
// СтрокаФормата = "ЧЦ = " + КвалификаторыЧисла.Разрядность + "; ЧДЦ = " + КвалификаторыЧисла.РазрядностьДробнойЧасти;
//КонецЕсли;
КонецЕсли;
Если ВозвращатьПредставлениеСсылки Или Не ЛиСсылкаНаОбъектБДЛкс(Значение) Тогда
Результат = Результат + Формат(Значение, СтрокаФормата);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПредставлениеСвязейПараметровВыбораЛкс(Связи) Экспорт
#Если Сервер И Не Сервер Тогда
Связи = Новый ФиксированныйМассив();
#КонецЕсли
Результат = "";
Для Каждого Связь Из Связи Цикл
#Если Сервер И Не Сервер Тогда
Связь = Новый СвязьПараметраВыбора;
#КонецЕсли
Если Результат <> "" Тогда
Результат = Результат + ", ";
КонецЕсли;
Результат = Результат + Связь.ПутьКДанным;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ПредставлениеТипаЛкс(Знач Тип, Знач ОписаниеТипов = Неопределено, ИспользоватьИмя = Ложь) Экспорт
Если ИспользоватьИмя Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
ОписаниеТипов = Новый ОписаниеТипов;
#КонецЕсли
СтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзКонкретногоТипа(Тип);
ПредставлениеТипа = мПлатформа.ПолучитьСтрокуКонкретногоТипа(СтруктураТипа);
Иначе
ПредставлениеТипа = "" + Тип;
КонецЕсли;
Если ОписаниеТипов <> Неопределено Тогда
Если Тип = Тип("Число") Тогда
ПредставлениеТипа = ПредставлениеТипа + "(" + ОписаниеТипов.КвалификаторыЧисла.Разрядность + "," + ОписаниеТипов.КвалификаторыЧисла.РазрядностьДробнойЧасти + ")";
ИначеЕсли Тип = Тип("Строка") Тогда
Если ОписаниеТипов.КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная Тогда
//ВариантДлины = "п";
Иначе
ВариантДлины = ",Ф";
КонецЕсли;
ПредставлениеТипа = ПредставлениеТипа + "(" + XMLСтрока(ОписаниеТипов.КвалификаторыСтроки.Длина) + ВариантДлины + ")";
ИначеЕсли Тип = Тип("Дата") Тогда
Если ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Время Тогда
ПредставлениеКвалификатора = "В";
ИначеЕсли ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда
ПредставлениеКвалификатора = "ДВ";
ИначеЕсли ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Дата Тогда
ПредставлениеКвалификатора = "Д";
КонецЕсли;
ПредставлениеТипа = ПредставлениеТипа + "(" + ПредставлениеКвалификатора + ")";
КонецЕсли;
КонецЕсли;
Возврат ПредставлениеТипа;
КонецФункции // ЛксПолучитьПредставлениеЗначение()
// Сравнивает значения свойств объекта <Первый> со значениями свойств объекта <Второй>. Сопоставление производится по именам свойств.
// Отсутствие свойства приравнивается к значению Неопределено.
//
// Параметры:
// Первый – Произвольный – первый объект для сравнения;
// Второй – Произвольный – первый объект для сравнения;
// СвойстваДляСравнения - Строка - перечисленные через запятую свойства для сравнения.
//
// Возвращаемое значение:
// Булево – Равны ли значения всех указанных свойств.
//
Функция СравнитьЗначенияСвойствЛкс(Первый, Второй, СвойстваДляСравнения) Экспорт
Структура1 = Новый Структура(СвойстваДляСравнения);
ЗаполнитьЗначенияСвойств(Структура1, Первый);
Структура2 = Новый Структура(СвойстваДляСравнения);
ЗаполнитьЗначенияСвойств(Структура2, Второй);
Результат = ЗначениеВСтрокуВнутр(Структура1) = ЗначениеВСтрокуВнутр(Структура2);
Возврат Результат;
КонецФункции // СравнитьЗначенияСвойствЛкс()
Функция КоличествоОшибокВЖурналеЛкс(Знач Начало, Знач Конец, Знач СтруктураОтбора, Знач МаксимальныйРазмерВыгрузки = Неопределено) Экспорт
АнализЖурналаРегистрации = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирАнализЖурналаРегистрации");
#Если Сервер И Не Сервер Тогда
АнализЖурналаРегистрации = Обработки.ирАнализЖурналаРегистрации.Создать();
#КонецЕсли
СобытияЗадания = АнализЖурналаРегистрации.ПолучитьДанные(Начало, Конец, СтруктураОтбора, МаксимальныйРазмерВыгрузки);
КоличествоОшибокВЖурнале = СобытияЗадания.Количество();
Возврат КоличествоОшибокВЖурнале;
КонецФункции
#Если Клиент Тогда
Процедура ИзменитьОтборКлиентаПоМетаданнымЛкс(ТабличноеПоле, Знач ИмяКолонкиСреднегоИмениМД = "Метаданные", ЭтоКолонкаПолногоИмениМД = Ложь) Экспорт
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
лСтруктураПараметров.Вставить("ОтображатьРегистры", Истина);
лСтруктураПараметров.Вставить("ОтображатьПерерасчеты", Истина);
лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина);
лСтруктураПараметров.Вставить("ОтображатьТабличныеЧасти", Истина);
лСтруктураПараметров.Вставить("ОтображатьКонстанты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", Истина);
лСтруктураПараметров.Вставить("ОтображатьРегламентныеЗадания", Истина);
лСтруктураПараметров.Вставить("ОтображатьОтчеты", Истина);
лСтруктураПараметров.Вставить("ОтображатьОбработки", Истина);
лСтруктураПараметров.Вставить("ОтображатьПоследовательности", Истина);
лСтруктураПараметров.Вставить("МножественныйВыбор", Истина);
лДоступныеОбъекты = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле);
лДоступныеОбъекты.Свернуть(ИмяКолонкиСреднегоИмениМД);
лДоступныеОбъекты = лДоступныеОбъекты.ВыгрузитьКолонку(ИмяКолонкиСреднегоИмениМД);
Если ЭтоКолонкаПолногоИмениМД Тогда
ДоступныеОбъекты = Новый Массив;
Для Каждого ПолноеИмяМД Из лДоступныеОбъекты Цикл
СреднееИмяМД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
ДоступныеОбъекты.Добавить(СреднееИмяМД);
КонецЦикла;
Иначе
//лСтруктураПараметров.Вставить("ОтображатьВиртуальныеТаблицы", Истина);
//лСтруктураПараметров.Вставить("ОтображатьТаблицыИзменений", Истина);
ДоступныеОбъекты = лДоступныеОбъекты;
КонецЕсли;
ЭлементОтбора = ТабличноеПоле.ОтборСтрок[ИмяКолонкиСреднегоИмениМД];
Если Истина
И ЭлементОтбора.Использование
И ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке
Тогда
лНачальноеЗначениеВыбора = ЭлементОтбора.Значение.ВыгрузитьЗначения();
Если ЭтоКолонкаПолногоИмениМД Тогда
НачальноеЗначениеВыбора = Новый Массив;
Для Каждого ПолноеИмяМД Из лНачальноеЗначениеВыбора Цикл
СреднееИмяМД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
НачальноеЗначениеВыбора.Добавить(СреднееИмяМД);
КонецЦикла;
Иначе
НачальноеЗначениеВыбора = лНачальноеЗначениеВыбора;
КонецЕсли;
Иначе
НачальноеЗначениеВыбора = ДоступныеОбъекты;
КонецЕсли;
мПлатформа = ирКэш.Получить();
Форма = мПлатформа.ПолучитьФорму("ВыборОбъектаМетаданных");
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора);
лСтруктураПараметров.Вставить("ДоступныеОбъекты", ДоступныеОбъекты);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
ЗначениеВыбора = Форма.ОткрытьМодально();
Если ЗначениеВыбора <> Неопределено Тогда
Если ЭтоКолонкаПолногоИмениМД Тогда
ТаблицаВсехТаблицБД = ирКэш.ТаблицаВсехТаблицБДЛкс();
МассивИменМД = Новый Массив;
Для Каждого СреднееИмяМД Из ЗначениеВыбора Цикл
СтрокаОписанияТаблицы = ТаблицаВсехТаблицБД.Найти(СреднееИмяМД, "ПолноеИмя");
Если СтрокаОписанияТаблицы <> Неопределено Тогда
МассивИменМД.Добавить(СтрокаОписанияТаблицы.ПолноеИмяМД);
Иначе
МассивИменМД.Добавить(СреднееИмяМД);
КонецЕсли;
КонецЦикла;
Иначе
МассивИменМД = ЗначениеВыбора;
КонецЕсли;
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(МассивИменМД);
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке;
ЭлементОтбора.Значение = СписокЗначений;
ЭлементОтбора.Использование = Истина;
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьДиалогЗаменыИдентификаторовОбъектовЛкс(Знач Объекты) Экспорт
ФормаОбработки = ирОбщий.ПолучитьФормуЛкс("Обработка.ирПоискДублейИЗаменаСсылок.Форма");
Дерево = Новый ДеревоЗначений;
Дерево.Колонки.Добавить("Объект");
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Объекты.Количество(), "Создание дублей объектов");
НачатьТранзакцию();
Попытка
Для Каждого Объект Из Объекты Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КопияОбъекта = Объект.Ссылка.ПолучитьОбъект();
ирОбщий.ЗаменитьИдентификаторОбъектаЛкс(КопияОбъекта);
Попытка
КопияОбъекта.ОбменДанными.Загрузка = Истина;
Исключение
СообщитьЛкс("Для узлов планов обмена групповая замена внутренних идентификаторов не поддерживается");
Возврат;
КонецПопытки;
КопияОбъекта.Записать();
СтрокаГруппы = Дерево.Строки.Добавить();
СтрокаЭлемента = СтрокаГруппы.Строки.Добавить();
СтрокаЭлемента[0] = КопияОбъекта.Ссылка;
СтрокаЭлемента = СтрокаГруппы.Строки.Добавить();
СтрокаЭлемента[0] = Объект;
КонецЦикла;
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
ЗафиксироватьТранзакцию();
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
ФормаОбработки.ОткрытьДляЗаменыПоДеревуСсылок(Дерево,, Ложь);
ФормаОбработки.ОтключатьКонтрольЗаписи = Истина;
ФормаОбработки.РазрешитьУдалениеСНарушениемСсылочнойЦелостности = Ложь;
КонецПроцедуры // ПередОткрытием()
// Оформляет ячейку табличного поля, допускающую значения, не имеющие стандартного отображения в платформе и хранимые отдельно.
// Иными словам колонка отображает данные, хранимые отдельно.
//
// Параметры:
// ОформлениеЯчейки – ОформлениеЯчейки
// Значение - Произвольный - значение для отображения.
//
Процедура ОформитьЯчейкуСРасширеннымЗначениемЛкс(ОформлениеЯчейки, Знач Значение = Неопределено, КолонкаТабличногоПоля = Неопределено, ВыводитьПиктограммуТипа = Истина) Экспорт
Если Значение = Неопределено Тогда
Значение = ОформлениеЯчейки.Значение;
КонецЕсли;
Если ВыводитьПиктограммуТипа Тогда
ТипЗначения = ТипЗнч(Значение);
Если Истина
И ТипЗначения = Тип("Булево")
И ОформлениеЯчейки.ОтображатьФлажок
Тогда
//
Иначе
КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения);
Если КартинкаТипа <> Неопределено Тогда
ОформлениеЯчейки.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
РасширенноеПредставление = РасширенноеПредставлениеЗначенияЛкс(Значение, КолонкаТабличногоПоля);
Если Ложь
Или ОформлениеЯчейки.Текст = РасширенноеПредставление
Тогда
Возврат;
КонецЕсли;
//ОформлениеЯчейки.ТолькоПросмотр = Истина;
//ОформлениеЯчейки.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаРасширенногоПредставленияЗначения");
ОформлениеЯчейки.УстановитьТекст(РасширенноеПредставление);
КонецПроцедуры
// Находит файлы в иерархии заданного каталога локальной файловой системы.
//
// Параметры:
// Путь – Строка;
// Маска – Строка.
//
// Возвращаемое значение:
// Массив – элементы типа Файл.
//
Функция НайтиФайлыВИерархииЛкс(Путь, Маска) Экспорт
НайденныеКаталоги = НайтиФайлы(Путь, "*.*");
МассивРезультатов = Новый Массив;
Для каждого НайденныйФайл Из НайденныеКаталоги Цикл
Если НайденныйФайл.ЭтоКаталог() Тогда
МассивРезультатов.Добавить(НайтиФайлыВИерархииЛкс(НайденныйФайл.ПолноеИмя, Маска));
КонецЕсли;
КонецЦикла;
МассивРезультатов.Добавить(НайтиФайлы(Путь, Маска));
Результат = Новый Массив;
Для Каждого ЭлементРезультат Из МассивРезультатов Цикл
Для Каждого Файл Из ЭлементРезультат Цикл
Результат.Добавить(Файл);
КонецЦикла;
КонецЦикла;
Возврат Результат;
КонецФункции
// Проверяет, является ли тип типом элемента формы.
//
// Параметры:
// пТип – Тип – проверяемый тип.
//
// Возвращаемое значение:
// Истина – тип элемента формы подтвержден;
// Ложь – тип элемента формы не подтвержден.
//
Функция ЛиТипЭлементаФормыЛкс(пТип) Экспорт
Если Ложь
ИЛИ пТип = Тип("Индикатор")
ИЛИ пТип = Тип("Кнопка")
ИЛИ пТип = Тип("КоманднаяПанель")
ИЛИ пТип = Тип("Надпись")
ИЛИ пТип = Тип("Панель")
ИЛИ пТип = Тип("Переключатель")
ИЛИ пТип = Тип("ПолеВвода")
ИЛИ пТип = Тип("ПолеВыбора")
ИЛИ пТип = Тип("ПолеСписка")
ИЛИ пТип = Тип("ПолеТекстовогоДокумента")
ИЛИ пТип = Тип("ПолеТабличногоДокумента")
ИЛИ пТип = Тип("ПолосаРегулирования")
ИЛИ пТип = Тип("ТабличноеПоле")
ИЛИ пТип = Тип("РамкаГруппы")
ИЛИ пТип = Тип("Флажок")
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиТипЭлементаФормыЛкс()
// Сообщает об ошибке в тексте запроса и устанавливает выделение на ошибочную строку, если это возможно.
//
// Параметры:
// *ПолеТекстовогоДокумента - ПолеТекстовогоДокумента, *Неопределено;
// *СтартоваяСтрока - Число, *0 - стартовое смещение строки;
// *СтартоваяКолонка - Число, *0 - стартовое смещение колонки;
// *ЯзыкПрограммы - Число, *0 - признак обработки ошибки при установке текста запроса;
// *ЛиМодально - Булево, *Ложь - модальный режим формы - будет использовано Предупреждение() вместо СообщитьЛкс().
// *ИнформацияОбОшибке - ИнформацияОбОшибке, *Неопределено;
// *ИмяМодуля - Строка, *Неопределено - имя модуля в котором произошла ошибка.
//
// Возвращаемое значение:
// Строка – истинное описание ошибки.
//
Функция ПоказатьОшибкуВЗапросеИлиПрограммномКодеЛкс(ПолеТекстовогоДокумента = Неопределено,
СтартоваяСтрока = 0, СтартоваяКолонка = 0, ЯзыкПрограммы = 0, ЛиМодально = Ложь, ИнформацияОбОшибке = Неопределено,
ИмяМодуля = Неопределено, ПредставлениеКонтекста = "") Экспорт
НомерСтроки = 0;
Если ИмяМодуля <> Неопределено Тогда
Вступление = Символы.Таб;
Иначе
Вступление = "";
КонецЕсли;
Если ИнформацияОбОшибке = Неопределено Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецЕсли;
ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(ОписаниеОшибки, Истина, ЛиМодально);
Если Истина
И ЯзыкПрограммы = 0
И ИмяМодуля <> Неопределено
И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля
Тогда
ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке);
Возврат ОписаниеОшибки;
КонецЕсли;
Если ЯзыкПрограммы = 2 Тогда
Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
Выражение = "";
Если Выражение = "" Тогда
Маркер = "Ошибка в выражении """;
Если Найти(НРег(ИнформацияОбОшибке.Описание), Нрег(Маркер)) = 1 Тогда
Выражение = Сред(ИнформацияОбОшибке.Описание, СтрДлина(Маркер) + 2, СтрДлина(ИнформацияОбОшибке.Описание) - СтрДлина(Маркер) - 3);
КонецЕсли;
КонецЕсли;
Если Выражение = "" Тогда
Маркер = "Поле не найдено """;
Если Найти(НРег(ИнформацияОбОшибке.Описание), Нрег(Маркер)) = 1 Тогда
МаркерНайден = Истина;
Выражение = Сред(ИнформацияОбОшибке.Описание, СтрДлина(Маркер) + 1, СтрДлина(ИнформацияОбОшибке.Описание) - СтрДлина(Маркер) - 1);
КонецЕсли;
КонецЕсли;
Если Выражение <> "" Тогда
ТекстПоля = ПолеТекстовогоДокумента.ПолучитьТекст();
ПозицияВыражения = Найти(ТекстПоля, Выражение);
Если ПозицияВыражения > 0 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(ПозицияВыражения, ПозицияВыражения + СтрДлина(Выражение));
Пустышка = 0;
НомерСтроки = 0;
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НомерСтроки, Пустышка, Пустышка, Пустышка);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И ИнформацияОбОшибке.Причина <> Неопределено
И ИнформацияОбОшибке.ИмяМодуля <> ""
И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля
Тогда
ФигурноеОписаниеОшибки = СтрокаМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "{", "}", Ложь);
Если ФигурноеОписаниеОшибки <> Неопределено Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЕсли;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 0
И ИнформацияОбОшибке.ИмяМодуля <> ""
И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля
Тогда
ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке);
Возврат ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
КонецЕсли;
МаксимальныйНомерСтроки = 100000;
Если ПолеТекстовогоДокумента <> Неопределено Тогда
МаксимальныйНомерСтроки = ПолеТекстовогоДокумента.КоличествоСтрок();
КонецЕсли;
ФигурноеОписаниеОшибки = СтрокаМеждуМаркерамиЛкс(ИнформацияОбОшибке.Описание, "{", "}", Ложь);
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если НомерСтроки = 0 Тогда
НомерСтроки = Мин(ИнформацияОбОшибке.НомерСтроки + СтартоваяСтрока, МаксимальныйНомерСтроки);
Если ИнформацияОбОшибке.ИсходнаяСтрока = "" Тогда
СтрокаКоординатыОшибки = СтрокаМеждуМаркерамиЛкс(ФигурноеОписаниеОшибки, "(", ")", Ложь);
Если СтрокаКоординатыОшибки <> Неопределено Тогда
НомерКолонки = 0;
МассивФрагментов = СтрРазделитьЛкс(СтрокаКоординатыОшибки, ",");
СтрокаНомерСтроки = МассивФрагментов[0];
Попытка
НомерСтроки = Число(СтрокаНомерСтроки);
Исключение
КонецПопытки;
НомерСтроки = Мин(НомерСтроки + СтартоваяСтрока, МаксимальныйНомерСтроки);
Если МассивФрагментов.Количество() > 1 Тогда
СтрокаНомерКолонки = МассивФрагментов[1];
Попытка
НомерКолонки = Число(СтрокаНомерКолонки);
Исключение
КонецПопытки;
НомерКолонки = НомерКолонки + СтартоваяКолонка;
КонецЕсли;
Если НомерСтроки = 0 Тогда
НомерКолонки = 1;
НомерСтроки = 1;
КонецЕсли;
ОписаниеОшибки = СтрЗаменить(ОписаниеОшибки, ФигурноеОписаниеОшибки, "(" + НомерСтроки + "," + НомерКолонки + ")");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 0
И НомерСтроки <= 0
Тогда
Если ЗначениеЗаполнено(ОписаниеОшибки) Тогда
ОписаниеОшибки = "Ошибка передачи переменной: " + ОписаниеОшибки;
Иначе
ОписаниеОшибки = "Ошибка без описания";
КонецЕсли;
Иначе
ОписаниеОшибки = "Строка кода " + НомерСтроки + ": " + ОписаниеОшибки;
КонецЕсли;
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
КонецЕсли;
ТекстСообщения = "";
Если ПолеТекстовогоДокумента <> Неопределено Тогда
Если НомерСтроки > 0 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НомерСтроки, 1, НомерСтроки, 150);
КонецЕсли;
ТекстСообщения = ТекстСообщения + ПолучитьПредставлениеИзИдентификатораЛкс(ПолеТекстовогоДокумента.Имя) + ПредставлениеКонтекста;
ТекстСообщения = ТекстСообщения + ": " + ОписаниеОшибки;
ПолныйТекстСообщения = Вступление + ТекстСообщения;
Если ЛиМодально Тогда
Предупреждение(ТекстСообщения);
Иначе
СообщитьЛкс(ПолныйТекстСообщения, СтатусСообщения.Важное);
КонецЕсли;
Иначе
ПолныйТекстСообщения = Вступление + ТекстСообщения;
Если ЛиМодально Тогда
Предупреждение(ОписаниеОшибки);
Иначе
СообщитьЛкс(ПолныйТекстСообщения, СтатусСообщения.Важное);
КонецЕсли;
КонецЕсли;
Возврат ПолныйТекстСообщения;
КонецФункции
Функция ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(Знач ОписаниеОшибки, ЭтоПроизвольныйАлгоритм = Ложь, Знач ЛиМодально = Ложь) Экспорт
Результат = Ложь;
Если Истина
//И (Ложь
// Или Не ирКэш.ЛиПортативныйРежимЛкс()
// Или ирПортативный.ЛиСерверныйМодульДоступенЛкс())
И Найти(ОписаниеОшибки, "мутабельн") > 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, "Создать одну группу дублей из значений текущей колонки выделенных строк");
//СписокВыбора.Добавить(2, "Создать правила замены значений из текущей колонки на значения следующей колонки");
ВыбранныйВариант = СписокВыбора.ВыбратьЭлемент("Выберите вариант");
Если ВыбранныйВариант = Неопределено Тогда
Возврат;
КонецЕсли;
Если ВыбранныйВариант.Значение = 1 Тогда
Если ВыделенныеСтроки.Количество() = 0 Тогда
Возврат ;
КонецЕсли;
ИмяКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Возврат;
КонецЕсли;
МассивСсылок = Новый Массив;
Для Каждого Строка Из ВыделенныеСтроки Цикл
ЗначениеСтроки = Строка[ИмяКолонки];
ТипЗначения = ТипЗнч(ЗначениеСтроки);
Если Метаданные.НайтиПоТипу(ТипЗначения) = Неопределено Тогда
Продолжить;
КонецЕсли;
МассивСсылок.Добавить(ЗначениеСтроки);
КонецЦикла;
ФормаОбработки.ОткрытьДляЗаменыПоСпискуСсылок(МассивСсылок,, 0);
ИначеЕсли ВыбранныйВариант.Значение = 0 Тогда
ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка;
Если Ложь
Или ТекущаяКолонка = Неопределено
Или ТекущаяКолонка.Данные = ""
Тогда
Возврат;
КонецЕсли;
ИндексКолонки = ТабличноеПоле.Колонки.Индекс(ТекущаяКолонка);
Если ТабличноеПоле.Колонки.Количество() = ИндексКолонки + 1 Тогда
Возврат;
КонецЕсли;
СледующаяКолонка = ТабличноеПоле.Колонки[ИндексКолонки + 1];
Если СледующаяКолонка.Данные = "" Тогда
Возврат;
КонецЕсли;
ФормаОбработки.ОткрытьСЗаполнениемГруппДублейПоТаблицеПар(ТабличноеПоле.Значение, ТекущаяКолонка.Данные, СледующаяКолонка.Данные);
КонецЕсли;
ИначеЕсли ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда
ФормаОбработки.ОткрытьДляЗаменыПоДеревуСсылок(ТабличноеПоле.Значение, ТабличноеПоле.ТекущаяКолонка.Имя);
КонецЕсли;
КонецПроцедуры // ОткрытьФормуЗаменыСсылокИзТабличногоПоляЛкс()
////////////////////////////////////////////////////////////////////////////////
// ТЕХНОЛОГИЯ КОМПОНЕНТ
// Возвращает кнопку командной панели компоненты по ее имени из макета.
//
// Параметры:
// ОбъектКомпоненты - ОбработкаОбъект - компонента;
// КраткоеИмяКнопки – Строка - имя кнопки из макета компоненты;
// *КоманднаяПанель - КоманднаяПанель, *Неопределено - на случай, если у компоненты несколько командных панелей.
//
// Возвращаемое значение:
// Кнопка.
//
Функция КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ОбъектКомпоненты, КраткоеИмяКнопки,
Знач КоманднаяПанель = Неопределено) Экспорт
Если КоманднаяПанель = Неопределено Тогда
КоманднаяПанель = ОбъектКомпоненты.КоманднаяПанель;
КонецЕсли;
Если КоманднаяПанель = Неопределено Тогда
// Был вызван деструктор
Возврат Неопределено;
КонецЕсли;
ПолноеИмяКнопки = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КраткоеИмяКнопки);
Кнопка = КоманднаяПанель.Кнопки.Найти(ПолноеИмяКнопки);
Если Кнопка = Неопределено Тогда
Для Каждого Подменю Из КоманднаяПанель.Кнопки Цикл
Если Подменю.ТипКнопки <> ТипКнопкиКоманднойПанели.Подменю Тогда
Продолжить;
КонецЕсли;
Кнопка = КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ОбъектКомпоненты, КраткоеИмяКнопки, Подменю);
Если Кнопка <> Неопределено Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Кнопка;
КонецФункции
// Формирует имя элемента управления экземпляра компоненты.
//
// Параметры:
// ИмяКласса – Строка;
// ИмяЭкземпляра - Строка;
// КраткоеИмяЭлементаУправления – Строка.
//
// Возвращаемое значение:
// Строка - имя.
//
Функция СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КраткоеИмяЭлементаУправления) Экспорт
Возврат ПрефиксИменЭлементовЭкземпляраКомпонентыЛкс(ОбъектКомпоненты) + КраткоеИмяЭлементаУправления;
КонецФункции
Функция ПрефиксИменЭлементовЭкземпляраКомпонентыЛкс(ОбъектКомпоненты) Экспорт
Возврат ОбъектКомпоненты.ИмяКласса + "_" + ОбъектКомпоненты.Имя + "_";
КонецФункции // СформироватьИмяЭлементаУправленияЭкземпляраЛкс()
// <Описание функции>
//
// Параметры:
// <Параметр1> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// – <Тип.Вид> – <описание значения>
// <продолжение описания значения>;
// <Значение2> – <Тип.Вид> – <описание значения>
// <продолжение описания значения>.
//
Функция ПолучитьНовуюТаблицуСобытийЭлементаУправленияКомпонентыЛкс() Экспорт
ТаблицаСобытий = Новый ТаблицаЗначений;
ТаблицаСобытий.Колонки.Добавить("СобытиеОбъекта");
ТаблицаСобытий.Колонки.Добавить("БлижайшийВидАлгоритма");
ТаблицаСобытий.Колонки.Добавить("ИмяСобытия");
ТаблицаСобытий.Колонки.Добавить("Компонента");
ТаблицаСобытий.Колонки.Добавить("ВызовОбработчика");
Возврат ТаблицаСобытий;
КонецФункции // ПолучитьНовуюТаблицуСобытийЭлементаУправленияКомпонентыЛкс()
// Добавляет в кнопки командной панели приемника коллекцию кнопок командной панели источника.
//
// Параметры:
// ОбъектКомпоненты - ОбработкаОбъект - компонента;
// КнопкиМакета – КоллекцияКнопокКоманднойПанели – источник;
// КнопкиПриемника – КоллекцияКнопокКоманднойПанели – приемник;
// *ДействияКнопокКомпонент - ТаблицаЗначений, *Неопределено;
//
Процедура ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ОбъектКомпоненты, КнопкиМакета, КнопкаПриемника,
ДействияКнопокКомпонент = Неопределено, ОбщийПриемник = Неопределено) Экспорт
КнопкиПриемника = КнопкаПриемника.Кнопки;
ИмяКласса = ОбъектКомпоненты.ИмяКласса;
Если ДействияКнопокКомпонент = Неопределено Тогда
ДействиеТранслятор = Новый Действие("Клс" + ИмяКласса + "Нажатие");
Иначе
ЭтоКоманднаяПанель = (ТипЗнч(КнопкаПриемника) = Тип("КоманднаяПанель"));
ДопКнопкиКомандныхПанелей = ОбъектКомпоненты.ДопКнопкиКомандныхПанелей;
ДопКнопкиКоманднойПанели = Новый Массив;
ДопКнопкиКомандныхПанелей.Вставить(КнопкаПриемника.Имя, ДопКнопкиКоманднойПанели);
ДействиеТранслятор = Новый Действие("КнопкаКоманднойПанели_Действие")
КонецЕсли;
ИмяЭкземпляра = ОбъектКомпоненты.Имя;
Для Каждого КнопкаМакета Из КнопкиМакета Цикл
Кнопка = Неопределено;
Если КнопкаМакета.ТипКнопки = ТипКнопкиКоманднойПанели.Действие Тогда
Если Истина
И Строка(КнопкаМакета.Действие) = ""
Тогда
// Это пустое действие
Кнопка = КнопкиПриемника.Добавить(, КнопкаМакета.ТипКнопки);
ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Действие, Имя");
Кнопка.Имя = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КнопкаМакета.Имя);
//Попытка
Кнопка.Действие = ДействиеТранслятор;
//Исключение
// ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
// Возврат;
//КонецПопытки;
Если ДействияКнопокКомпонент <> Неопределено Тогда
СтрокаДействия = ДействияКнопокКомпонент.Добавить();
СтрокаДействия.Кнопка = Кнопка;
СтрокаДействия.Компонента = ОбъектКомпоненты;
ВызовОбработчика = "Действие_";
Если ОбщийПриемник = Неопределено Тогда
ВызовОбработчика = ВызовОбработчика + КнопкаМакета.Имя;
Иначе
ВызовОбработчика = ВызовОбработчика + ОбщийПриемник;
КонецЕсли;
СтрокаДействия.ВызовОбработчика = ВызовОбработчика + "(П0, П1)";
КонецЕсли;
Иначе
Кнопка = КнопкиПриемника.Добавить(КнопкаМакета.Имя, КнопкаМакета.ТипКнопки, , КнопкаМакета.Действие);
// Автокартинки предопределенных действий платформа подключает до вызова ПередОткрытием, а потом они уже пустые
Если КнопкаМакета.Картинка.Вид <> ВидКартинки.Пустая Тогда
Кнопка.Картинка = КнопкаМакета.Картинка;
КонецЕсли;
ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Имя, ТипКнопки, Картинка");
КонецЕсли;
КонецЕсли;
Если Кнопка = Неопределено Тогда
Кнопка = КнопкиПриемника.Добавить();
ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Действие, Имя");
Кнопка.Имя = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КнопкаМакета.Имя);
Если КнопкаМакета.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда
ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ОбъектКомпоненты, КнопкаМакета.Кнопки, Кнопка, ДействияКнопокКомпонент, ОбщийПриемник);
КонецЕсли;
КонецЕсли;
Если Истина
И ДействияКнопокКомпонент <> Неопределено
И ЭтоКоманднаяПанель
Тогда
ДопКнопкиКоманднойПанели.Добавить(Кнопка.Имя);
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс()
// Возвращает имя экземпляра компоненты, которой принадлежит элемент управления.
//
// Параметры:
// ЭлементУправления – ЭлементУправления.
//
// Возвращаемое значение:
// Строка - имя.
//
Функция ПолучитьИмяЭкземпляраЛкс(ЭлементУправления) Экспорт
Результат = СтрРазделитьЛкс(ЭлементУправления.Имя, "_")[1];
Возврат Результат;
КонецФункции // ПолучитьИмяЭкземпляраЛкс()
// Устанавливает свойство у элементов именованной коллекции.
//
// Параметры:
// Коллекция – Любая индексированная коллекция;
// МассивИлиСтрока – Массив (индексов), Строка (имена элементов, разделенные запятыми), *Неопределено - фильтр;
// Свойство – Строка - имя Свойства которое нужно установить;
// ЗначениеСвойства – Произвольный.
//
Процедура УстановитьСвойствоВКоллекцииЛкс(Коллекция, МассивИлиСтрока = Неопределено, Свойство, ЗначениеСвойства) Экспорт
ДоступенИндексСвойств = Лев(Свойство, 1) <> "-";
Если МассивИлиСтрока <> Неопределено Тогда
Если ТипЗнч(МассивИлиСтрока) = Тип("Строка") Тогда
МассивИндексов = СтрРазделитьЛкс(МассивИлиСтрока, ",", Истина);
Иначе
МассивИндексов = МассивИлиСтрока;
КонецЕсли;
Для Каждого ИмяЭлемента Из МассивИндексов Цикл
ЭлементКоллекции = Коллекция[ИмяЭлемента];
Если ДоступенИндексСвойств Тогда
ЭлементКоллекции[Свойство] = ЗначениеСвойства;
Иначе
Выполнить("ЭлементКоллекции." + Сред(Свойство, 2) + " = ЗначениеСвойства");
КонецЕсли;
КонецЦикла;
Иначе
Для Каждого ЭлементКоллекции Из Коллекция Цикл
Если ДоступенИндексСвойств Тогда
ЭлементКоллекции[Свойство] = ЗначениеСвойства;
Иначе
Выполнить("ЭлементКоллекции." + Сред(Свойство, 2) + " = ЗначениеСвойства");
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры // УстановитьСвойствоВКоллекцииЛкс()
Процедура ТабличноеПолеКолонокПриВыводеСтрокиЛкс(Знач ОформлениеСтроки, Знач ДанныеСтроки, Знач ИмяКолонкиОписанияТипов = "ТипЗначения") Экспорт
ИндексКартинки = ПолучитьИндексКартинкиТипаЛкс(ДанныеСтроки[ИмяКолонкиОписанияТипов]);
Если ИндексКартинки <> Неопределено Тогда
ОформлениеСтроки.Ячейки[ИмяКолонкиОписанияТипов].ОтображатьКартинку = Истина;
ОформлениеСтроки.Ячейки[ИмяКолонкиОписанияТипов].ИндексКартинки = ИндексКартинки;
КонецЕсли;
КонецПроцедуры
// Глобальный обработчик события ПриПолученииДанных для табличных полей доступных полей компоновки.
//
// Параметры:
// ОформленияСтрок – ОформленияСтрок.
//
Процедура ПриПолученииДанныхДоступныхПолейКомпоновкиЛкс(ЭтаФорма, Элемент, ОформленияСтрок, ТабличноеПолеВыбранныхПолей = Неопределено) Экспорт
//СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
//ОбработчикиПриВыводеСтроки = СлужебныеДанныеФормы.ОбработчикиПриВыводеСтроки;
//ОбработчикПриВыводеСтроки = ОбработчикиПриВыводеСтроки[Элемент.Имя];
//Если Истина
// И ОбработчикПриВыводеСтроки <> Неопределено
// И Не МетодРеализованЛкс(ЭтаФорма, ОбработчикПриВыводеСтроки) // Сообщение о его отсутствии выдаем в общем обработчике Форма_ПриОткрытии
//Тогда
// ОбработчикПриВыводеСтроки = Неопределено;
//КонецЕсли;
Если Истина
И ТабличноеПолеВыбранныхПолей <> Неопределено
И ОформленияСтрок[0].Ячейки.Найти("Использовано") <> Неопределено
Тогда
ВсеПоляВыбранныхПолей = ирОбщий.ВсеВыбранныеПоляГруппировкиКомпоновкиЛкс(ТабличноеПолеВыбранныхПолей.Значение,,, Истина);
КонецЕсли;
КартинкаРеквизита = ирКэш.КартинкаПоИмениЛкс("ирРеквизит");
Для каждого ОформлениеСтроки Из ОформленияСтрок Цикл
ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
Если ДанныеСтроки = Неопределено Тогда
Продолжить;
КонецЕсли;
Ячейки = ОформлениеСтроки.Ячейки;
ЯчейкаТипа = Ячейки.Найти("Тип");
Если ЯчейкаТипа <> Неопределено Тогда
Ячейки.Тип.УстановитьТекст(ДанныеСтроки.ТипЗначения);
КонецЕсли;
ИндексКартинки = Неопределено;
Попытка
ЭтоПапка = ДанныеСтроки.Папка;
ЭтоРесурс = ДанныеСтроки.Ресурс;
Исключение
ЭтоПапка = Ложь;
ЭтоРесурс = Ложь;
КонецПопытки;
Если ЭтоПапка Тогда
ПапкаСРесурсами = ДанныеСтроки.Элементы.Количество() > 0;
Для каждого ДоступноеПоле Из ДанныеСтроки.Элементы Цикл
Если Не ДоступноеПоле.Ресурс Тогда
ПапкаСРесурсами = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПапкаСРесурсами Тогда
ИндексКартинки = 17;
КонецЕсли;
КонецЕсли;
Если Не ЭтоРесурс И Не ЭтоПапка Тогда
ИндексКартинки = ПолучитьИндексКартинкиТипаЛкс(ДанныеСтроки.ТипЗначения);
КонецЕсли;
Если ИндексКартинки <> Неопределено Тогда
Ячейки[0].ОтображатьКартинку = Истина;
Ячейки[0].ИндексКартинки = ИндексКартинки;
КонецЕсли;
Если Истина
И ВсеПоляВыбранныхПолей <> Неопределено
И ВсеПоляВыбранныхПолей.Найти(ДанныеСтроки.Поле) <> Неопределено
Тогда
Ячейки.Использовано.УстановитьКартинку(КартинкаРеквизита);
КонецЕсли;
Если Ячейки.Найти("Заголовок") <> Неопределено Тогда
Типы = ДанныеСтроки.ТипЗначения.Типы();
Если Типы.Количество() > 1 Тогда
Ячейки.Заголовок.УстановитьТекст(Ячейки.Заголовок.Текст + " (" + XMLСтрока(Типы.Количество()) + "т)");
КонецЕсли;
КонецЕсли;
//Если ОбработчикПриВыводеСтроки = Неопределено Тогда
ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки);
//Иначе
// Выполнить("ЭтаФорма." + ОбработчикПриВыводеСтроки + "(Элемент, ОформлениеСтроки, ДанныеСтроки);");
//КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ОформитьСтрокуДоступногоПоляЛкс(ОформлениеСтроки, СтрокаПоля, Знач СтрокаДоступнойТаблицы = Неопределено, ИмяКолонки = "Заголовок", Знач ЭтоИндекс = Ложь, Использовано = Ложь) Экспорт
Ячейки = ОформлениеСтроки.Ячейки;
ЭтоСистемное = Истина
И СтрокаПоля <> Неопределено
И СтрокаПоля.Метаданные = Неопределено
И Не СтрокаПоля.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений"))
И (Ложь
Или СтрокаДоступнойТаблицы = Неопределено
Или (Истина
И СтрокаДоступнойТаблицы.Тип <> "ВиртуальнаяТаблица"
И СтрокаДоступнойТаблицы.Тип <> "ВременнаяТаблица"
И СтрокаДоступнойТаблицы.Тип <> "Параметр"
И СтрокаДоступнойТаблицы.Тип <> "Константы"));
ТекстВСкобках = "";
ЭтоИзмерение = Истина
И СтрокаПоля <> Неопределено
И СтрокаПоля.Метаданные <> Неопределено
И Найти(СтрокаПоля.Метаданные.ПолноеИмя(), ".Измерение.") > 0;
Если Истина
И СтрокаПоля <> Неопределено
И ИмяКолонки <> "Заголовок"
Тогда
Типы = СтрокаПоля.ТипЗначения.Типы();
Если Типы.Количество() > 1 Тогда
ТекстВСкобках = ТекстВСкобках + "," + XMLСтрока(Типы.Количество()) + "т";
КонецЕсли;
КонецЕсли;
Если ЭтоИзмерение Тогда
ТекстВСкобках = ТекстВСкобках + ",Измер";
ОформлениеСтроки.ЦветФона = Новый Цвет(255, 245, 240);
КонецЕсли;
Если ЭтоСистемное Тогда
ТекстВСкобках = ТекстВСкобках + ",Систем";
ОформлениеСтроки.ЦветФона = Новый Цвет(250, 250, 255);
КонецЕсли;
Если ЭтоИндекс Тогда
ТекстВСкобках = ТекстВСкобках + ",Индек";
КонецЕсли;
Если ЗначениеЗаполнено(ТекстВСкобках) Тогда
ТекстВСкобках = " (" + Сред(ТекстВСкобках, 2) + ")";
Ячейки[ИмяКолонки].УстановитьТекст(Ячейки[ИмяКолонки].Текст + ТекстВСкобках);
КонецЕсли;
Если Использовано И Ячейки.Найти("Использовано") <> Неопределено Тогда
Ячейки.Использовано.УстановитьКартинку(ирКэш.КартинкаПоИмениЛкс("ирРеквизит"));
КонецЕсли;
КонецПроцедуры
// Подключает обработчики событий для табличного поля отбора компоновки данных.
//
// Параметры:
// ТабличноеПоле – ТабличноеПоле – отбора компоновки.
//
Процедура ПодключитьОбработчикиСобытийДоступныхПолейКомпоновкиЛкс(ТабличноеПоле) Экспорт
Обработчик = ТабличноеПоле.ПолучитьДействие("ПриПолученииДанных");
Если Истина
И Обработчик <> Неопределено
И Не СтрокиРавныЛкс(Обработчик, "ТабличноеПолеПриПолученииДанных")
Тогда
СообщитьЛкс("Обнаружено переопределение обработчика ПриПолученииДанных табличного поля " + ТабличноеПоле.Имя);
КонецЕсли;
ТабличноеПоле.УстановитьДействие("ПриПолученииДанных", Новый Действие("ПриПолученииДанныхДоступныхПолей"));
ТабличноеПоле.Колонки[0].КартинкиСтрок = ирКэш.КартинкаПоИмениЛкс("ирТипыДоступныхПолейКомпоновки");
КонецПроцедуры
Процедура УстановитьПолеВПравомЗначенииЭлементаОтбораЛкс(Знач ТабличноеПолеОтбора, Знач ТабличноеПолеДоступныхПолей = Неопределено) Экспорт
Если ТабличноеПолеДоступныхПолей <> Неопределено И ТабличноеПолеДоступныхПолей.ТекущаяСтрока <> Неопределено Тогда
ПолеКомпоновки = ТабличноеПолеДоступныхПолей.ТекущаяСтрока.Поле;
Иначе
ПолеКомпоновки = Новый ПолеКомпоновкиДанных("");
КонецЕсли;
ТекущаяСтрока = ТабличноеПолеОтбора.ТекущаяСтрока;
Если ТипЗнч(ТекущаяСтрока) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
Если ТипЗнч(ТекущаяСтрока.ПравоеЗначение) <> Тип("ПолеКомпоновкиДанных") Или ЗначениеЗаполнено("" + ПолеКомпоновки) Тогда
ТекущаяСтрока.ПравоеЗначение = ПолеКомпоновки;
КонецЕсли;
ТабличноеПолеОтбора.ТекущаяКолонка = ТабличноеПолеОтбора.Колонки.ПравоеЗначениеДляКраткогоОтображенияЭлемента;
КонецЕсли;
КонецПроцедуры
// Получает макет компоновки данных по схеме с использованием временных таблиц.
//
// Параметры:
// Схема – СхемаКомпоновкиДанных;
// Настройки - НастройкиКомпоновкиДанных;
// *ВнешниеНаборыДанных – Структура, *Неопределено - туда добавляются временные таблицы;
// *ДанныеРасшифровки - ДанныеРасшифровкиКомпоновкиДанных, *Неопределено;
// *ЛиОтладка - Булево, *Ложь - показывать тексты запросов и время выполнения этапов.
//
// Возвращаемое значение:
// МакетКомпоновкиДанных.
//
Функция ПолучитьМакетКомпоновкиДанныхСВременнымиТаблицамиЛкс(Схема, Настройки, ВнешниеНаборыДанных = Неопределено,
ДанныеРасшифровки = Неопределено, ЛиОтладка = Ложь, СвойМакетОформления = Неопределено, ПроверятьДоступностьПолей = Ложь) Экспорт
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");
РезультатЗапроса = ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Предварительный запрос - " + НаборДанных.Имя);
ВнешниеНаборыДанных.Вставить(НаборДанных.Имя, РезультатЗапроса);
КонецЦикла;
// Получение конечного макета
Для Каждого ЭлементНаборДанных Из СтруктураНаборовДанныхЗапросовМакета Цикл
КоллекцияВладелец = ЭлементНаборДанных.Значение.КоллекцияВладелец;
НаборДанныхЗапрос = ЭлементНаборДанных.Значение.НаборДанных;
НаборДанныхОбъект = КоллекцияВладелец.Добавить(Тип("НаборДанныхОбъектМакетаКомпоновкиДанных"));
// Копируем Свойства набора данных запроса в набор данных объекта
ЗаполнитьЗначенияСвойств(НаборДанныхОбъект, НаборДанныхЗапрос);
НаборДанныхОбъект.ИмяОбъекта = НаборДанныхЗапрос.Имя;
Для Каждого ПолеНабораДанныхОригинала Из НаборДанныхЗапрос.Поля Цикл
ПолеРезультата = НаборДанныхОбъект.Поля.Добавить();
ЗаполнитьЗначенияСвойств(ПолеРезультата, ПолеНабораДанныхОригинала);
ЗаполнитьЗначенияСвойств(ПолеРезультата.Роль, ПолеНабораДанныхОригинала.Роль);
КонецЦикла;
КоллекцияВладелец.Удалить(НаборДанныхЗапрос);
КонецЦикла;
КонецЕсли;
// Баг платформы. Пустая дата превращается в Неопределено.
Для Каждого ПараметрСхемы Из ПредварительнаяСхема.Параметры Цикл
Если ПараметрСхемы.ОграничениеИспользования Тогда
Если Не ПараметрСхемы.ДоступенСписокЗначений Тогда
ЗначениеПараметра = МакетКомпоновкиДанных.ЗначенияПараметров.Найти(ПараметрСхемы.Имя);
ЗначениеПараметра.Значение = ПараметрСхемы.ТипЗначения.ПривестиЗначение(ЗначениеПараметра.Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат МакетКомпоновкиДанных;
КонецФункции // ПолучитьМакетКомпоновкиДанныхСВременнымиТаблицамиЛкс()
#КонецЕсли
Функция ПолучитьКоличествоИзмененийПоУзлуЛкс(Узел, МассивМетаданных = Неопределено) Экспорт
#Если Клиент Тогда
СостояниеЛкс("Вычисление количества изменений на узле...");
#КонецЕсли
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Узел", Узел);
МетаПланОбмена = Узел.Метаданные();
ТекстЗапроса = "";
Для Каждого ЭлементСОстава Из МетаПланОбмена.Состав Цикл
МетаОбъект = ЭлементСОстава.Метаданные;
Если Ложь
Или МетаОбъект = Неопределено
Или (Истина
И МассивМетаданных <> Неопределено
И МассивМетаданных.Найти(МетаОбъект) = Неопределено)
Тогда
Продолжить;
КонецЕсли;
Если ТекстЗапроса <> "" Тогда
ТекстЗапроса = ТекстЗапроса + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС;
КонецЕсли;
ИмяТаблицыДляПоискаЗарегистрированных = СтрЗаменить(МетаОбъект.ПолноеИмя(), ".Перерасчет.", ".") + ".Изменения";
ТекстЗапроса = ТекстЗапроса + "ВЫБРАТЬ Количество(*) КАК Количество
|ИЗ
| " + ИмяТаблицыДляПоискаЗарегистрированных + " КАК РегистрацияИзменений
|ГДЕ
| РегистрацияИзменений.Узел = &Узел
|";
КонецЦикла;
Если ТекстЗапроса <> "" Тогда
Запрос.Текст = ТекстЗапроса;
ТаблицаКоличестваИзменений = Запрос.Выполнить().Выгрузить();
КоличествоИзменений = ТаблицаКоличестваИзменений.Итог("Количество");
Иначе
КоличествоИзменений = 0;
КонецЕсли;
#Если Клиент Тогда
СостояниеЛкс("");
#КонецЕсли
Возврат КоличествоИзменений;
КонецФункции
// Параметры:
// СтрокаТаблицыИлиДерева - СтрокаТаблицыЗначений, СтрокаДереваЗначений, ВыборкаИзРезультатаЗапроса
// Результат - Структура
Функция СтруктураИзСтрокиТаблицыИлиДереваИлиВыборкиЛкс(СтрокаТаблицыИлиДереваИлиВыборки) Экспорт
Результат = Новый Структура;
Для Каждого МетаРеквизит Из СтрокаТаблицыИлиДереваИлиВыборки.Владелец().Колонки Цикл
Результат.Вставить(МетаРеквизит.Имя, СтрокаТаблицыИлиДереваИлиВыборки[МетаРеквизит.Имя]);
КонецЦикла;
Возврат Результат;
КонецФункции
// Получает структуру свойств объекта по имени типа или объекту.
// Свойства должны располагаться в порядке:
// - общие,
// - ролевые в порядке невлияния на предшествующие.
//
// Параметры:
// пОбъект - Произвольный - имя типа или сам объект;
// пЛиДляСохранения - Булево, *Ложь - признак получения свойств для сохранения.
//
// Возвращаемое значение:
// – Структура – свойств.
//
Функция ПолучитьСтруктуруСвойствОбъектаЛкс(пОбъект, пЛиДляСохранения = Ложь) Экспорт
СтруктураСвойств = Новый Структура;
ТипОбъекта = ТипЗнч(пОбъект);
МетаОбъект = ПолучитьМетаданныеЛкс(ТипОбъекта);
Если МетаОбъект <> Неопределено Тогда
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(МетаОбъект, Истина);
Если Ложь
ИЛИ КорневойТип = "Обработка"
ИЛИ КорневойТип = "Отчет"
Тогда
Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
Для Каждого МетаРеквизит Из МетаОбъект.ТабличныеЧасти Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
КонецЕсли;
Если ПолучитьКорневойТипСтрокиТабличнойЧастиЛкс(ТипОбъекта) <> Неопределено Тогда
Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
КонецЕсли;
Если Истина
И ТипОбъекта <> Тип("Тип")
И ТипОбъекта <> Тип("ОписаниеТипов")
И ТипОбъекта <> Тип("ОбъектМетаданных")
Тогда
Если ПолучитьКорневойТипСпискаЛкс(ТипОбъекта) <> Неопределено Тогда
СтруктураСвойств.Вставить("Колонки");
СтруктураСвойств.Вставить("Порядок");
СтруктураСвойств.Вставить("Отбор");
ИначеЕсли ЛиНаборЗаписейРегистраЛкс(ТипОбъекта) Тогда
СтруктураСвойств.Вставить("Отбор");
КонецЕсли;
КонецЕсли;
//ИначеЕсли Ложь
// ИЛИ ТипОбъекта = Тип("КнопкиКоманднойПанели")
// ИЛИ ТипОбъекта = Тип("КолонкиТабличногоПоля")
// ИЛИ ТипОбъекта = Тип("СтраницыПанели")
// ИЛИ ТипОбъекта = Тип("ЭлементыФормы")
// ИЛИ ТипОбъекта = Тип("ПоляНастройки")
//Тогда
// Для Каждого Элемент Из пОбъект Цикл
// СтруктураСвойств.Вставить(Элемент.Имя);
// КонецЦикла;
//
ИначеЕсли Ложь
Или ТипОбъекта = Тип("СтрокаТаблицыЗначений")
Или ТипОбъекта = Тип("СтрокаДереваЗначений")
Тогда
Для Каждого МетаРеквизит Из пОбъект.Владелец().Колонки Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
#Если Клиент Тогда
ИначеЕсли ЛиТипЭлементаФормыЛкс(ТипОбъекта) Тогда
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("Видимость");
СтруктураСвойств.Вставить("ИзменяетДанные");
СтруктураСвойств.Вставить("ПервыйВГруппе");
СтруктураСвойств.Вставить("ПропускатьПриВводе");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("КонтекстноеМеню");
Если НЕ пЛиДляСохранения Тогда
СтруктураСвойств.Вставить("Лево");
СтруктураСвойств.Вставить("Верх");
СтруктураСвойств.Вставить("Высота");
СтруктураСвойств.Вставить("Ширина");
КонецЕсли;
СтруктураСвойств.Вставить("Подсказка");
СтруктураСвойств.Вставить("ПорядокОбхода");
СтруктураСвойств.Вставить("ПорядокОтображения");
СтруктураСвойств.Вставить("ПрозрачныйФон");
СтруктураСвойств.Вставить("Рамка");
Если ТипОбъекта = Тип("Кнопка") Тогда
СтруктураСвойств.Вставить("РежимМеню");
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("МногострочныйРежим");
СтруктураСвойств.Вставить("ПоложениеКартинки");
СтруктураСвойств.Вставить("РазмерКартинки");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаКнопки");
СтруктураСвойств.Вставить("ЦветФонаКнопки");
СтруктураСвойств.Вставить("Шрифт");
СтруктураСвойств.Вставить("Кнопки");
ИначеЕсли ТипОбъекта = Тип("КоманднаяПанель") Тогда
СтруктураСвойств.Вставить("АвтоЗаполнение");
СтруктураСвойств.Вставить("Вспомогательная");
СтруктураСвойств.Вставить("ВыравниваниеКнопок");
СтруктураСвойств.Вставить("ИсточникДействий");
СтруктураСвойств.Вставить("Кнопки");
СтруктураСвойств.Вставить("Ориентация");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаКнопки");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("ЦветФонаКнопки");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Надпись") Тогда
СтруктураСвойств.Вставить("БегущаяСтрока");
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("ВыделятьОтрицательные");
СтруктураСвойств.Вставить("ГиперСсылка");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("ПоложениеКартинкиНадписи");
СтруктураСвойств.Вставить("РазмерКартинки");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("Формат");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Панель") Тогда
СтруктураСвойств.Вставить("Страницы");
СтруктураСвойств.Вставить("АвтоПорядокОбхода");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("ОтображениеЗакладок");
СтруктураСвойств.Вставить("ПорядокОбхода");
СтруктураСвойств.Вставить("РазмерКартинки");
СтруктураСвойств.Вставить("РаспределятьПоСтраницам");
СтруктураСвойств.Вставить("РежимПрокручиваемыхСтраниц");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("ТекущаяСтраница");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Переключатель") Тогда
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("ВыбираемоеЗначение");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("ПоложениеЗаголовка");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("ПолеВвода") Тогда
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ОграничениеТипа");
СтруктураСвойств.Вставить("КнопкаВыбора");
СтруктураСвойств.Вставить("РежимВыбораИзСписка");
СтруктураСвойств.Вставить("КнопкаСпискаВыбора");
СтруктураСвойств.Вставить("СписокВыбора");
СтруктураСвойств.Вставить("АвтоВыборНезаполненного");
СтруктураСвойств.Вставить("АвтоОтметкаНезаполненного");
СтруктураСвойств.Вставить("АвтоПереносСтрок");
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("БыстрыйВыбор");
СтруктураСвойств.Вставить("ВыбиратьТип");
СтруктураСвойств.Вставить("ВыборГруппИЭлементов");
СтруктураСвойств.Вставить("ВыборНезаполненного");
СтруктураСвойств.Вставить("ВыборПоВладельцу");
СтруктураСвойств.Вставить("ВыделенныйТекст");
СтруктураСвойств.Вставить("ВыделятьОтрицательные");
СтруктураСвойств.Вставить("ВысотаСпискаВыбора");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("КартинкаКнопкиВыбора");
СтруктураСвойств.Вставить("КнопкаОткрытия");
СтруктураСвойств.Вставить("КнопкаОчистки");
СтруктураСвойств.Вставить("КнопкаРегулирования");
СтруктураСвойств.Вставить("МаксимальноеЗначение");
СтруктураСвойств.Вставить("Маска");
СтруктураСвойств.Вставить("МинимальноеЗначение");
СтруктураСвойств.Вставить("МногострочныйРежим");
СтруктураСвойств.Вставить("ОтметкаНезаполненного");
СтруктураСвойств.Вставить("РасширенноеРедактирование");
СтруктураСвойств.Вставить("РедактированиеТекста");
СтруктураСвойств.Вставить("РежимВыбораНезаполненного");
СтруктураСвойств.Вставить("РежимПароля");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("Формат");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаКнопки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаКнопки");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("ШиринаСпискаВыбора");
СтруктураСвойств.Вставить("Шрифт");
СтруктураСвойств.Вставить("ЭлементСвязиПоТипу");
СтруктураСвойств.Вставить("Значение");
ИначеЕсли ТипОбъекта = Тип("ПолеВыбора") Тогда
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ВысотаСпискаВыбора");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("КартинкаКнопкиВыбора");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("КнопкаВыбора");
СтруктураСвойств.Вставить("КнопкаОткрытия");
СтруктураСвойств.Вставить("КнопкаОчистки");
СтруктураСвойств.Вставить("КнопкаРегулирования");
СтруктураСвойств.Вставить("СписокВыбора");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("ШиринаСпискаВыбора");
СтруктураСвойств.Вставить("Значение");
ИначеЕсли ТипОбъекта = Тип("ПолеСписка") Тогда
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ОтображатьКартинку");
СтруктураСвойств.Вставить("ОтображатьПометку");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ТекущаяСтрока");
ИначеЕсли ТипОбъекта = Тип("ТабличноеПоле") Тогда
// **** Доделать
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("АвтоВводНовойСтроки");
СтруктураСвойств.Вставить("АвтоКонтекстноеМеню");
СтруктураСвойств.Вставить("АвтоОбновление");
СтруктураСвойств.Вставить("АктивизироватьПоУмолчанию");
СтруктураСвойств.Вставить("ВосстанавливатьТекущуюСтроку");
СтруктураСвойств.Вставить("Дерево");
СтруктураСвойств.Вставить("ИерархическийПросмотр");
СтруктураСвойств.Вставить("ИзменятьАвтоОбновление");
СтруктураСвойств.Вставить("ИзменятьИерархическийПросмотр");
СтруктураСвойств.Вставить("ИзменятьСпособРедактирования");
СтруктураСвойств.Вставить("ИзменятьТекущегоРодителя");
СтруктураСвойств.Вставить("ПериодАвтоОбновления");
СтруктураСвойств.Вставить("ПроверкаОтображенияНовойСтроки");
СтруктураСвойств.Вставить("РодительВерхнегоУровня");
СтруктураСвойств.Вставить("РежимВыбора");
СтруктураСвойств.Вставить("РежимВыделения");
СтруктураСвойств.Вставить("РежимВыделенияСтроки");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("СпособРедактирования");
СтруктураСвойств.Вставить("ТекущийРодитель");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("Колонки");
СтруктураСвойств.Вставить("НастройкаОтбора");
СтруктураСвойств.Вставить("НастройкаПорядка");
СтруктураСвойств.Вставить("ТекущаяКолонка");
СтруктураСвойств.Вставить("ТекущаяСтрока");
СтруктураСвойств.Вставить("ТекущиеДанные");
СтруктураСвойств.Вставить("ВыделенныеСтроки");
// ****
//ВертикальнаяПолосаПрокрутки
//ВертикальныеЛинии
//Вывод
//ВысотаПодвала
//ВысотаШапки
//ГоризонтальнаяПолосаПрокрутки
//ГоризонтальныеЛинии
//ИзменятьНастройкуКолонок
//ИзменятьПозициюКолонок
//ИзменятьПорядокСтрок
//ИзменятьСоставСтрок
//НачальноеОтображениеДерева
//НачальноеОтображениеСписка
//Подвал
//ПропускатьПриВводе
//РазрешитьНачалоПеретаскивания
//РазрешитьПеретаскивание
//РежимВводаСтрок
//ФиксацияСлева
//ФиксацияСправа
//ЦветТекста
//ЦветТекстаВыделения
//ЦветТекстаКнопки
//ЦветТекстаПодвала
//ЦветТекстаШапки
//ЦветФона
//ЦветФонаВыделения
//ЦветФонаКнопки
//ЦветФонаПодвала
//ЦветФонаЧередованияСтрок
//ЦветФонаШапки
//ЧередованиеЦветовСтрок
//Шапка
//Ширина
//Шрифт
//ШрифтПодвала
//ШрифтШапки
ИначеЕсли ТипОбъекта = Тип("ПолеТабличногоДокумента") Тогда
СтруктураСвойств.Вставить("ВертикальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("ГоризонтальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ОтображатьВыделение");
СтруктураСвойств.Вставить("РазрешитьНачалоПеретаскивания");
СтруктураСвойств.Вставить("РазрешитьПеретаскивание");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("ЦветРамки");
ИначеЕсли ТипОбъекта = Тип("РамкаГруппы") Тогда
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Флажок") Тогда
СтруктураСвойств.Вставить("ТриСостояния");
СтруктураСвойств.Вставить("ВертикальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("ГоризонтальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ПоложениеЗаголовка");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("ЦветФонаПоля");
КонецЕсли;
ИначеЕсли ТипОбъекта = Тип("КнопкаКоманднойПанели") Тогда
СтруктураСвойств.Вставить("ТипКнопки");
СтруктураСвойств.Вставить("Действие");
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("ИзменяетДанные");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("КнопкаПоУмолчанию");
СтруктураСвойств.Вставить("Кнопки");
СтруктураСвойств.Вставить("Отображение");
СтруктураСвойств.Вставить("Подсказка");
СтруктураСвойств.Вставить("Пометка");
СтруктураСвойств.Вставить("ПорядокКнопок");
СтруктураСвойств.Вставить("Пояснение");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("Текст");
ИначеЕсли ТипОбъекта = Тип("СтраницаПанели") Тогда
СтруктураСвойств.Вставить("Видимость");
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("КартинкаЗаголовка");
СтруктураСвойств.Вставить("Раскрыта");
ИначеЕсли ТипОбъекта = Тип("КолонкаТабличногоПоля") Тогда
СтруктураСвойств.Вставить("АвтоВысотаЯчейки");
СтруктураСвойств.Вставить("АвтоОтметкаНезаполненного");
СтруктураСвойств.Вставить("Видимость");
СтруктураСвойств.Вставить("ВыделятьОтрицательные");
СтруктураСвойств.Вставить("ВысотаЯчейки");
СтруктураСвойств.Вставить("ГиперСсылка");
СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВКолонке");
СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВПодвале");
СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВШапке");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ДанныеФлажка");
СтруктураСвойств.Вставить("ДополнительнаяКартинкаШапки");
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("КартинкаПодвала");
СтруктураСвойств.Вставить("КартинкаШапки");
СтруктураСвойств.Вставить("КартинкиСтрок");
СтруктураСвойств.Вставить("ОтображатьВПодвале");
СтруктураСвойств.Вставить("ОтображатьВШапке");
СтруктураСвойств.Вставить("ОтображатьИерархию");
СтруктураСвойств.Вставить("ПодсказкаВШапке");
СтруктураСвойств.Вставить("Положение");
СтруктураСвойств.Вставить("ПропускатьПриВводе");
СтруктураСвойств.Вставить("РежимРедактирования");
СтруктураСвойств.Вставить("ТекстПодвала");
СтруктураСвойств.Вставить("ТекстШапки");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("ТриСостоянияФлажка");
СтруктураСвойств.Вставить("Формат");
СтруктураСвойств.Вставить("ЦветТекстаПодвала");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветТекстаШапки");
СтруктураСвойств.Вставить("ЦветФонаПодвала");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("ЦветФонаШапки");
СтруктураСвойств.Вставить("Ширина");
СтруктураСвойств.Вставить("ШрифтПодвала");
СтруктураСвойств.Вставить("ШрифтТекста");
СтруктураСвойств.Вставить("ШрифтШапки");
СтруктураСвойств.Вставить("ЭлементУправления");
СтруктураСвойств.Вставить("ИзменениеРазмера");
СтруктураСвойств.Вставить("ИзменятьВидимость");
СтруктураСвойств.Вставить("ИзменятьНастройку");
СтруктураСвойств.Вставить("ИзменятьПозицию");
ИначеЕсли ТипОбъекта = Тип("Форма") Тогда
СтруктураСвойств.Вставить("АвтоЗаголовок");
СтруктураСвойств.Вставить("Высота");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("ЗакрыватьПриВыборе");
СтруктураСвойств.Вставить("ЗакрыватьПриЗакрытииВладельца");
СтруктураСвойств.Вставить("ИзменениеРазмера");
СтруктураСвойств.Вставить("ИзменятьСпособОтображенияОкна");
СтруктураСвойств.Вставить("ИмяСохраненияПоложенияОкна");
СтруктураСвойств.Вставить("КартинкаЗаголовка");
СтруктураСвойств.Вставить("КлючУникальности");
СтруктураСвойств.Вставить("МножественныйВыбор");
СтруктураСвойств.Вставить("Модифицированность");
СтруктураСвойств.Вставить("НачальноеЗначениеВыбора");
СтруктураСвойств.Вставить("Панель");
СтруктураСвойств.Вставить("ПоведениеКлавишиEnter");
СтруктураСвойств.Вставить("ПоложениеОкна");
СтруктураСвойств.Вставить("ПоложениеПрикрепленногоОкна");
СтруктураСвойств.Вставить("РазрешитьСоединятьОкно");
СтруктураСвойств.Вставить("РазрешитьСостояниеОбычное");
СтруктураСвойств.Вставить("РазрешитьСостояниеПрикрепленное");
СтруктураСвойств.Вставить("РазрешитьСостояниеПрячущееся");
СтруктураСвойств.Вставить("РазрешитьСостояниеСвободное");
СтруктураСвойств.Вставить("РежимВыбора");
СтруктураСвойств.Вставить("РежимРабочегоСтола");
СтруктураСвойств.Вставить("СоединяемоеОкно");
СтруктураСвойств.Вставить("СостояниеОкна");
СтруктураСвойств.Вставить("СпособОтображенияОкна");
СтруктураСвойств.Вставить("Стиль");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("Ширина");
СтруктураСвойств.Вставить("ЭлементыФормы");
СтруктураСвойств.Вставить("ТекущийЭлемент");
Если НЕ пЛиДляСохранения Тогда
СтруктураСвойств.Вставить("ВладелецФормы");
СтруктураСвойств.Вставить("МодальныйРежим");
КонецЕсли;
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ПостроительОтчета")
ИЛИ пОбъект = "ПостроительОтчета"
Тогда
СтруктураСвойств.Вставить("Текст");
СтруктураСвойств.Вставить("ДоступныеПоля");
СтруктураСвойств.Вставить("ВыбранныеПоля");
СтруктураСвойств.Вставить("ИзмеренияКолонки");
СтруктураСвойств.Вставить("ИзмеренияСтроки");
СтруктураСвойств.Вставить("Отбор");
СтруктураСвойств.Вставить("Параметры");
// не все
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ИзмерениеПостроителяОтчета")
ИЛИ пОбъект = "ИзмерениеПостроителяОтчета"
Тогда
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
СтруктураСвойств.Вставить("ТипИзмерения");
// не все
#КонецЕсли
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ПолеНастройки")
ИЛИ пОбъект = "ПолеНастройки"
Тогда
СтруктураСвойств.Вставить("Измерение");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Отбор");
СтруктураСвойств.Вставить("Поле");
СтруктураСвойств.Вставить("Порядок");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
СтруктураСвойств.Вставить("СписокЗначений");
СтруктураСвойств.Вставить("ТипЗначения");
Если НЕ пЛиДляСохранения Тогда
СтруктураСвойств.Вставить("Поля");
СтруктураСвойств.Вставить("Родитель");
КонецЕсли;
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ПолеПостроителяОтчета")
ИЛИ пОбъект = "ПолеПостроителяОтчета"
Тогда
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ЭлементОтбора")
ИЛИ пОбъект = "ЭлементОтбора"
Тогда
СтруктураСвойств.Вставить("ВидСравнения");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ЗначениеПо");
СтруктураСвойств.Вставить("ЗначениеС");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Использование");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
СтруктураСвойств.Вставить("ТипЗначения");
КонецЕсли;
Возврат СтруктураСвойств;
КонецФункции // ПолучитьСтруктуруСвойствОбъектаЛкс()
// Переустанавливает значения недоступных параметров из схемы (антибаг платформы).
//
// Параметры:
// СхемаКомпоновкиДанных – СхемаКомпоновкиДанных;
// КомпоновщикНастроек – КомпоновщикНастроекКомпоновкиДанных.
//
Процедура ОбновитьЗначенияНедоступныхПараметровИзСхемыЛкс(КомпоновщикНастроек, СхемаКомпоновкиДанных) Экспорт
#Если Сервер И Не Сервер Тогда
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
#КонецЕсли
Для Каждого ЗначениеПараметра Из КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы Цикл
ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти("" + ЗначениеПараметра.Параметр);
Если Истина
И ПараметрСхемы <> Неопределено
И ПараметрСхемы.ОграничениеИспользования
Тогда
//Если ЗначениеЗаполнено(ЗначениеПараметра.Выражение) Тогда
// Попытка
// ЗначениеПараметра.Значение = Вычислить();
// Исключение
// КонецПопытки;
//Иначе
ЗначениеПараметра.Значение = ПараметрСхемы.Значение;
//КонецЕсли;
//ЗначениеПараметра.Использование = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновкиДанных) Экспорт
ПолеКоличества = "КоличествоСтрокАвто";
ВычисляемоеПоле = СхемаКомпоновкиДанных.ВычисляемыеПоля.Добавить();
ВычисляемоеПоле.Выражение = "1";
ВычисляемоеПоле.Заголовок = "Количество строк (авто)";
ВычисляемоеПоле.ПутьКДанным = ПолеКоличества;
РесурсКоличествоЗаписей = СхемаКомпоновкиДанных.ПоляИтога.Добавить();
РесурсКоличествоЗаписей.ПутьКДанным = ПолеКоличества;
РесурсКоличествоЗаписей.Выражение = "Сумма(1)";
КонецПроцедуры
// Создает новую или добавляет в существующую схему компоновки наборы данных объекты из структуры таблиц значений.
//
// Параметры:
// СтруктураТаблиц – Структура – <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>.
//
Функция СоздатьСхемуПоТаблицамЗначенийЛкс(СтруктураТаблиц, СхемаКомпоновкиДанных = Неопределено, СоздаватьПапкиПолей = Ложь, СоздаватьРесурсыЧисловыхПолей = Ложь,
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок = Истина) Экспорт
Если СхемаКомпоновкиДанных = Неопределено Тогда
СхемаКомпоновкиДанных = СоздатьСхемуКомпоновкиЛкс();
КонецЕсли;
Для Каждого КлючИЗначение Из СтруктураТаблиц Цикл
КолонкиНабора = КолонкиИсточникаДанныхЛкс(КлючИЗначение.Значение);
СоздатьИлиОбновитьНаборДанныхОбъектПоМетаданнымЛкс(СхемаКомпоновкиДанных, КолонкиНабора, КлючИЗначение.Ключ, СоздаватьПапкиПолей, СоздаватьРесурсыЧисловыхПолей);
КонецЦикла;
Если ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок Тогда
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновкиДанных);
КонецЕсли;
Возврат СхемаКомпоновкиДанных;
КонецФункции
Функция СоздатьСхемуКомпоновкиЛкс() Экспорт
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных);
Возврат СхемаКомпоновкиДанных;
КонецФункции
Функция КолонкиИсточникаДанныхЛкс(Знач ИсточникДанных)
Если Ложь
Или ТипЗнч(ИсточникДанных) = Тип("ДеревоЗначений")
Или ТипЗнч(ИсточникДанных) = Тип("ТаблицаЗначений")
Тогда
КолонкиНабора = ИсточникДанных.Колонки;
Иначе
КолонкиНабора = ИсточникДанных.ВыгрузитьКолонки().Колонки;
КонецЕсли;
Возврат КолонкиНабора;
КонецФункции
// Создает новую или добавляет в существующую схему компоновки набор данных объект из полей настройки.
//
// Параметры:
// ПоляНастройки – ПоляНастройки – <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>.
//
Функция СоздатьСхемуПоПолямНастройкиЛкс(ПоляНастройки, СхемаКомпоновкиДанных = Неопределено, ИмяНабора = "Основной") Экспорт
Если СхемаКомпоновкиДанных = Неопределено Тогда
СхемаКомпоновкиДанных = СоздатьСхемуКомпоновкиЛкс();
КонецЕсли;
#Если Сервер И Не Сервер Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
НаборДанных.Имя = ИмяНабора;
НаборДанных.ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных[0].Имя;
НаборДанных.ИмяОбъекта = ИмяНабора;
Для Каждого ПолеНастройки Из ПоляНастройки Цикл
Поле = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
Поле.ПутьКДанным = ПолеНастройки.Имя;
Поле.Поле = ПолеНастройки.ПутьКДанным;
Поле.Заголовок = ПолеНастройки.Представление;
Поле.ТипЗначения = ПолеНастройки.ТипЗначения;
ОграничениеИспользования = Поле.ОграничениеИспользования;
ОграничениеИспользования.Поле = Не ПолеНастройки.Поле;
ОграничениеИспользования.Условие = Не ПолеНастройки.Отбор;
ОграничениеИспользования.Порядок = Не ПолеНастройки.Порядок;
ОграничениеИспользования.Группировка = Не ПолеНастройки.Измерение;
ЗначениеОграничения = ПолеНастройки.Поля.Количество() = 0;
ОграничениеИспользованияРеквизитов = Поле.ОграничениеИспользованияРеквизитов;
ОграничениеИспользованияРеквизитов.Поле = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Условие = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Порядок = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Группировка = ЗначениеОграничения;
КонецЦикла;
Возврат СхемаКомпоновкиДанных;
КонецФункции // СоздатьСхемуПоПолямНастройкиЛкс()
// Параметры:
// Поле -
// Доступность -
// ПрименитьГруппировка -
// ПрименитьПоле -
// ПрименитьПорядок -
// ПрименитьУсловие -
// Возвращаемое значение:
//
Функция УстановитьОграниченияИспользованияПоляНабораДанныхСхемыКомпоновкиЛкс(Знач ПолеИлиОграничениеИспользования, Знач Ограничивать = Ложь, Знач ПрименитьГруппировка = Истина,
Знач ПрименитьПоле = Истина, Знач ПрименитьПорядок = Истина, Знач ПрименитьУсловие = Истина) Экспорт
МассивГруппОграничений = Новый Массив;
Если ТипЗнч(ПолеИлиОграничениеИспользования) = Тип("ОграничениеИспользованияПоляСхемыКомпоновкиДанных") Тогда
МассивГруппОграничений.Добавить(ПолеИлиОграничениеИспользования);
Иначе
Поле = ПолеИлиОграничениеИспользования;
МассивГруппОграничений.Добавить(Поле.ОграничениеИспользования);
Попытка
МассивГруппОграничений.Добавить(Поле.ОграничениеИспользованияРеквизитов);
Исключение
КонецПопытки;
КонецЕсли;
Для Каждого ОграничениеИспользования Из МассивГруппОграничений Цикл
Если ПрименитьГруппировка Тогда
ОграничениеИспользования.Группировка = Ограничивать;
КонецЕсли;
Если ПрименитьПоле Тогда
ОграничениеИспользования.Поле = Ограничивать;
КонецЕсли;
Если ПрименитьПорядок Тогда
ОграничениеИспользования.Порядок = Ограничивать;
КонецЕсли;
Если ПрименитьУсловие Тогда
ОграничениеИспользования.Условие = Ограничивать;
КонецЕсли;
КонецЦикла;
КонецФункции
// Функция добавляет в схему компоновки источник данных с типом "Local"
Функция ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных) Экспорт
ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить();
ИсточникДанных.Имя = "ИсточникДанных1";
ИсточникДанных.ТипИсточникаДанных = "Local";
Возврат ИсточникДанных;
КонецФункции
// Функция добавляет набор данных - запрос в указанную в параметре коллекцию наборов данных
Функция ДобавитьНаборДанныхЗапросЛкс(НаборыДанных, ИсточникДанных, ИмяНабораДанных = "Основной") Экспорт
НаборДанных = НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
НаборДанных.Имя = ИмяНабораДанных;
НаборДанных.ИсточникДанных = ИсточникДанных.Имя;
Возврат НаборДанных;
КонецФункции
// Конструктор массива через Параметры.
//
// Параметры:
// *п... – Произвольный – элементы массива.
//
// Возвращаемое значение:
// Массив - полученный массив.
//
Функция БыстрыйМассивЛкс(
п1 = Неопределено, п2 = Неопределено, п3 = Неопределено, п4 = Неопределено, п5 = Неопределено,
п6 = Неопределено, п7 = Неопределено, п8 = Неопределено, п9 = Неопределено, п10= Неопределено,
п11= Неопределено, п12= Неопределено, п13= Неопределено, п14= Неопределено, п15= Неопределено,
п16= Неопределено, п17= Неопределено, п18= Неопределено, п19= Неопределено, п20= Неопределено
) Экспорт
Перем М;
М = Новый Массив();
Если п1 = Неопределено Тогда Возврат М; Иначе М.Добавить(п1 ); КонецЕсли;
Если п2 = Неопределено Тогда Возврат М; Иначе М.Добавить(п2 ); КонецЕсли;
Если п3 = Неопределено Тогда Возврат М; Иначе М.Добавить(п3 ); КонецЕсли;
Если п4 = Неопределено Тогда Возврат М; Иначе М.Добавить(п4 ); КонецЕсли;
Если п5 = Неопределено Тогда Возврат М; Иначе М.Добавить(п5 ); КонецЕсли;
Если п6 = Неопределено Тогда Возврат М; Иначе М.Добавить(п6 ); КонецЕсли;
Если п7 = Неопределено Тогда Возврат М; Иначе М.Добавить(п7 ); КонецЕсли;
Если п8 = Неопределено Тогда Возврат М; Иначе М.Добавить(п8 ); КонецЕсли;
Если п9 = Неопределено Тогда Возврат М; Иначе М.Добавить(п9 ); КонецЕсли;
Если п10= Неопределено Тогда Возврат М; Иначе М.Добавить(п10); КонецЕсли;
Если п11= Неопределено Тогда Возврат М; Иначе М.Добавить(п11); КонецЕсли;
Если п12= Неопределено Тогда Возврат М; Иначе М.Добавить(п12); КонецЕсли;
Если п13= Неопределено Тогда Возврат М; Иначе М.Добавить(п13); КонецЕсли;
Если п14= Неопределено Тогда Возврат М; Иначе М.Добавить(п14); КонецЕсли;
Если п15= Неопределено Тогда Возврат М; Иначе М.Добавить(п15); КонецЕсли;
Если п16= Неопределено Тогда Возврат М; Иначе М.Добавить(п16); КонецЕсли;
Если п17= Неопределено Тогда Возврат М; Иначе М.Добавить(п17); КонецЕсли;
Если п18= Неопределено Тогда Возврат М; Иначе М.Добавить(п18); КонецЕсли;
Если п19= Неопределено Тогда Возврат М; Иначе М.Добавить(п19); КонецЕсли;
Если п20= Неопределено Тогда Возврат М; Иначе М.Добавить(п20); КонецЕсли;
Возврат М;
КонецФункции // БыстрыйМассивЛкс()
Функция ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение, Название, ПолучатьXMLПредставлениеДляНеизвестныхТипов = Истина) Экспорт
Если Ложь
Или ТипЗнч(Значение) = Тип("ТабличныйДокумент")
Или ТипЗнч(Значение) = Тип("ТекстовыйДокумент")
Тогда
Документ = Значение;
Иначе
Документ = Новый ТекстовыйДокумент;
Если ТипЗнч(Значение) = Тип("ХранилищеЗначения") Тогда
Значение = Значение.Получить();
КонецЕсли;
Если ТипЗнч(Значение) <> Тип("Строка") И ПолучатьXMLПредставлениеДляНеизвестныхТипов Тогда
Представление = СохранитьОбъектВВидеСтрокиXMLЛкс(Значение);
Представление = ДекодироватьТекстИзXMLЛкс(Представление);
Иначе
Представление = Значение;
КонецЕсли;
Документ.УстановитьТекст(Представление);
КонецЕсли;
Путь = ПолучитьИмяВременногоФайла(Название);
Документ.Записать(Путь);
Возврат Путь;
КонецФункции
// Получает строку путем отсечения заданного числа последних символов.
//
// Параметры:
// пСтрока – Строка – исходная;
// пДлинаКонца - Число, *1 - количество отсекаемых символов;
//
// Возвращаемое значение:
// – Строка.
//
Функция СтрокаБезКонцаЛкс(пСтрока, пДлинаКонца = 1) Экспорт
Если СтрДлина(пСтрока) < пДлинаКонца Тогда
Возврат "";
Иначе
Возврат Лев(пСтрока, СтрДлина(пСтрока) - пДлинаКонца);
КонецЕсли;
КонецФункции
Функция СтрокаБезПоследнегоФрагментаЛкс(Знач Строка, Знач Разделитель = ".") Экспорт
Фрагменты = СтрРазделитьЛкс(Строка, Разделитель);
#Если Сервер И Не Сервер Тогда
Фрагменты = Новый Массив;
#КонецЕсли
Фрагменты.Удалить(Фрагменты.ВГраница());
Результат = СтрСоединитьЛкс(Фрагменты, Разделитель);
Возврат Результат;
КонецФункции
// Получает значения параметров из строки.
//
// Параметры:
// СтрокаПараметров - Строка - строка, содержащая параметры, каждый из которых представляет собой
// фрагмент вида <Имя параметра>=<Значение>, где:
// Имя параметра - имя параметра;
// Значение - его значение.
// Фрагменты отделяются друг от друга символами ';'.
// Если значение содержит пробельные символы, то оно должно быть заключено в двойные
// кавычки (").
// Например:
// "File=""c:\InfoBases\Trade""; Usr=""Director"";"
// Разделитель - Строка - символ, которым фрагменты отделяются друг от друга.
//
// Возвращаемое значение:
// Структура - значения параметров, где ключ - имя параметра, значение - значение параметра.
//
// Пример:
// Результат = СтроковыеФункцииКлиентСервер.ПараметрыИзСтроки("File=""c:\InfoBases\Trade""; Usr=""Director"";""", ";");
// - вернет структуру:
// ключ "File" и значение "c:\InfoBases\Trade"
// ключ "Usr" и значение "Director".
//
Функция ЗначенияПараметровИзСтрокиЛкс(Знач СтрокаПараметров, Знач Разделитель = ";") Экспорт
Результат = Новый Структура;
ОписаниеПараметра = "";
НайденоНачалоСтроки = Ложь;
НомерПоследнегоСимвола = СтрДлина(СтрокаПараметров);
Для НомерСимвола = 1 По НомерПоследнегоСимвола Цикл
Символ = Сред(СтрокаПараметров, НомерСимвола, 1);
Если Символ = """" Тогда
НайденоНачалоСтроки = Не НайденоНачалоСтроки;
КонецЕсли;
Если Символ <> Разделитель Или НайденоНачалоСтроки Тогда
ОписаниеПараметра = ОписаниеПараметра + Символ;
КонецЕсли;
Если Символ = Разделитель И Не НайденоНачалоСтроки Или НомерСимвола = НомерПоследнегоСимвола Тогда
Позиция = Найти(ОписаниеПараметра, "=");
Если Позиция > 0 Тогда
ИмяПараметра = СокрЛП(Лев(ОписаниеПараметра, Позиция - 1));
ЗначениеПараметра = СокрЛП(Сред(ОписаниеПараметра, Позиция + 1));
ЗначениеПараметра = СтрокаИзВыраженияВстроенногоЯзыкаЛкс(ЗначениеПараметра);
Результат.Вставить(ИмяПараметра, ЗначениеПараметра);
КонецЕсли;
ОписаниеПараметра = "";
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
// Получает представление из идентификатора по правилу
// "Дебиторка_По_контрагентамСИнтерваламиСНГДля__Руководства" => "Дебиторка По контрагентам с интервалами СНГ для Руководства".
// После символа "_" регистр не меняется, а сам символ заменяется на " ".
//
// Параметры:
// ИсходнаяСтрока – Строка – идентификатор.
//
// Возвращаемое значение:
// – Строка – представление.
//
Функция ПолучитьПредставлениеИзИдентификатораЛкс(ИсходнаяСтрока) Экспорт
СтрокаВозврата = Сред(ИсходнаяСтрока, 1, 1);
Для Сч = 2 По СтрДлина(ИсходнаяСтрока) Цикл
ПредыдущийСимвол = Сред(ИсходнаяСтрока, Сч - 1, 1);
ТекущийСимвол = Сред(ИсходнаяСтрока, Сч, 1);
СледующийСимвол = Сред(ИсходнаяСтрока, Сч + 1, 1);
ПослеследующийСимвол = Сред(ИсходнаяСтрока, Сч + 2, 1);
Если ТекущийСимвол = "_" Тогда
СтрокаВозврата = СтрокаВозврата + " ";
Продолжить;
ИначеЕсли Истина
И ВРЕГ(ТекущийСимвол) = ТекущийСимвол
// В идентификаторе не должны встречаться пробелы. Поэтому было решено закомментировать следующую строку.
//И ПредыдущийСимвол <> " "
Тогда
Если Ложь
ИЛИ ВРЕГ(ПредыдущийСимвол) <> ПредыдущийСимвол
ИЛИ (Истина
И ПредыдущийСимвол <> "_"
И ВРЕГ(ПредыдущийСимвол) = ПредыдущийСимвол
И ВРЕГ(СледующийСимвол) <> СледующийСимвол)
Тогда
СтрокаВозврата = СтрокаВозврата + " ";
Если Ложь
ИЛИ ВРЕГ(СледующийСимвол) <> СледующийСимвол
ИЛИ ВРЕГ(ПослеследующийСимвол) <> ПослеследующийСимвол
Тогда
ТекущийСимвол = НРЕГ(ТекущийСимвол);
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтрокаВозврата = СтрокаВозврата + ТекущийСимвол;
КонецЦикла;
Возврат СтрокаВозврата;
КонецФункции
// Преобразует строку для использования в регулярных выражениях.
// Производится
//
// Параметры:
// пТекст – Строка.
//
// Возвращаемое значение:
// Строка – для вставки в регулярные выражения.
//
Функция ПреобразоватьТекстДляРегулярныхВыраженийЛкс(пТекст) Экспорт
Текст = пТекст;
СтрокаСлужебныхСимволов = "\[]^$()?*+.|"; // "\" должен быть первым
Для Счетчик = 1 По СтрДлина(СтрокаСлужебныхСимволов) Цикл
СпецСимвол = Сред(СтрокаСлужебныхСимволов, Счетчик, 1);
Текст = СтрЗаменить(Текст, СпецСимвол, "\" + СпецСимвол);
КонецЦикла;
Возврат Текст;
КонецФункции // ПреобразоватьТекстДляРегулярныхВыраженийЛкс()
// Шаблон для вызова
//Вхождения = ирОбщий.НайтиРегулярноеВыражениеЛкс(Текст, Шаблон);
//#Если Сервер И Не Сервер Тогда
// Вхождения = Обработки.ирПлатформа.Создать().ВхожденияРегулярногоВыражения;
//#КонецЕсли
//Для каждого Вхождение Из Вхождения Цикл
//КонецЦикла;
Функция НайтиРегулярноеВыражениеЛкс(Знач Текст, Знач Шаблон, Знач ИменаПодгрупп = "", Знач ИскатьВсеВхождения = Истина, Знач ИгнорироватьРегистрБукв = Истина,
Знач МногострочныйРежим = Ложь, ВызыватьИсключение = Истина, БезПодгрупп = Ложь) Экспорт
//Вычислитель = Новый COMОбъект("VBScript.RegExp");
Вычислитель = ирКэш.ВычислительРегулярныхВыраженийЛкс();
Вычислитель.IgnoreCase = ИгнорироватьРегистрБукв;
Вычислитель.Global = ИскатьВсеВхождения;
Вычислитель.Multiline = МногострочныйРежим;
Вычислитель.Pattern = Шаблон;
Попытка
Вхождения = Вычислитель.Execute(Текст);
Исключение
Если Не ВызыватьИсключение Тогда
Возврат ОписаниеОшибки();
Иначе
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("ТекстВхождения");
Результат.Колонки.Добавить("ПозицияВхождения");
Результат.Колонки.Добавить("ДлинаВхождения");
Результат.Колонки.Добавить("Подгруппы");
#Если Сервер И Не Сервер Тогда
Результат = Обработки.ирПлатформа.Создать().ВхожденияРегулярногоВыражения;
#КонецЕсли
ИндексПервойКолонкиПодгруппы = Результат.Колонки.Количество();
Если Не БезПодгрупп Тогда
ИменаПодгруппМассив = СтрРазделитьЛкс(ИменаПодгрупп, ",", Истина, Ложь);
Для Каждого ИмяПодгруппы Из ИменаПодгруппМассив Цикл
Если Результат.Колонки.Найти(ИмяПодгруппы) <> Неопределено Тогда
ВызватьИсключение "Имя """ + ИмяПодгруппы + """ добавляемой колонки подгруппы результатов поиска не уникально";
КонецЕсли;
Результат.Колонки.Добавить(ИмяПодгруппы);
КонецЦикла;
КоличествоИменПодгрупп = ИменаПодгруппМассив.Количество();
КонецЕсли;
ДобавитьКолонкиПодгрупп = КоличествоИменПодгрупп = 0;
Для Каждого Вхождение Из Вхождения Цикл
//Если Результат.Количество() = 0 Тогда
// Для ИндексПодгруппы = ИменаПодгруппМассив.Количество() По Вхождение.SubMatches.Count - 1 Цикл
// Результат.Колонки.Добавить("Подгруппа" + XMLСтрока(ИндексПодгруппы));
// КонецЦикла;
//КонецЕсли;
СтрокаРезультата = Результат.Добавить();
СтрокаРезультата.ТекстВхождения = Вхождение.Value;
СтрокаРезультата.ПозицияВхождения = Вхождение.FirstIndex;
СтрокаРезультата.ДлинаВхождения = Вхождение.Length;
Если Не БезПодгрупп Тогда
Подгруппы = Новый Массив;
Для ИндексПодгруппы = 0 По Вхождение.SubMatches.Count - 1 Цикл
Если ДобавитьКолонкиПодгрупп Тогда
Результат.Колонки.Добавить("Подгруппа" + ИндексПодгруппы);
КоличествоИменПодгрупп = КоличествоИменПодгрупп + 1;
КонецЕсли;
Если ИндексПодгруппы < КоличествоИменПодгрупп Тогда
СтрокаРезультата[ИндексПервойКолонкиПодгруппы + ИндексПодгруппы] = Вхождение.SubMatches(ИндексПодгруппы);
КонецЕсли;
Подгруппы.Добавить(Вхождение.SubMatches(ИндексПодгруппы));
КонецЦикла;
СтрокаРезультата.Подгруппы = Подгруппы;
Если ДобавитьКолонкиПодгрупп Тогда
ДобавитьКолонкиПодгрупп = Ложь;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
// Преобразует строку для правого операнда оператора ПОДОБНО языка запросов.
//
// Параметры:
// пТекст – Строка.
//
// Возвращаемое значение:
// Строка.
//
Функция ПреобразоватьСтрокуДляПОДОБНОЛкс(Знач Результат, Спецсимвол = "~") Экспорт
ЗарезервированныеСимволы = Новый Массив;
ЗарезервированныеСимволы.Добавить("~");
//ЗарезервированныеСимволы.Добавить("%");
ЗарезервированныеСимволы.Добавить("_");
ЗарезервированныеСимволы.Добавить("[");
ЗарезервированныеСимволы.Добавить("-");
ЗарезервированныеСимволы.Добавить("]");
Для Каждого ЗарезервированныйСимвол Из ЗарезервированныеСимволы Цикл
Результат = СтрЗаменить(Результат, ЗарезервированныйСимвол, Спецсимвол + ЗарезервированныйСимвол);
КонецЦикла;
Возврат Результат;
КонецФункции // ПреобразоватьСтрокуДляПОДОБНОЛкс()
// Получает строку путем повтора переданной строки заданное количество раз.
//
// Параметры:
// СтрокаДляПовтора – Строка;
// ЧислоПовторов – Число.
//
// Возвращаемое значение:
// Строка.
//
Функция СтрокаПовторомЛкс(СтрокаДляПовтора, ЧислоПовторов) Экспорт
Результат = "";
Для Счетчик = 1 По ЧислоПовторов Цикл
Результат = Результат + СтрокаДляПовтора;
КонецЦикла;
Возврат Результат;
КонецФункции // СтрокаПовторомЛкс()
// Обновляет в строковом свойстве объекта часть, которая следует за маркером.
// Если маркер не находится, то он добавляется.
//
// Параметры:
// пОбъект – Объект, Строка - объект, строковое свойство которого будем обновлять, или само свойство по ссылке;
// *пИмяСвойства – Строка, *"" – имя строкового Свойства объекта, указывается в случае, если свойство не передается по ссылке;
// пНовыйТекст - Строка - новая часть, которая следует за разделителем;
// *пМаркер - Строка, *"," - маркер.
//
Процедура ОбновитьТекстПослеМаркераВСтрокеЛкс(пОбъектИлиСвойство, Знач пИмяСвойства = "", Знач НовыйТекст, Знач пМаркер = ", ", Знач ОбрезатьПосле = 100) Экспорт
Если пИмяСвойства <> "" Тогда
СтараяСтрока = пОбъектИлиСвойство[пИмяСвойства];
Иначе
СтараяСтрока = пОбъектИлиСвойство;
КонецЕсли;
ПозицияРазделителя = Найти(СтараяСтрока, пМаркер);
Если ПозицияРазделителя = 0 Тогда
ПозицияРазделителя = СтрДлина(СтараяСтрока) + 1;
КонецЕсли;
Если ЗначениеЗаполнено(ОбрезатьПосле) Тогда
НовыйТекст = ПредставлениеЗначенияСОграничениемДлиныЛкс(НовыйТекст, ОбрезатьПосле);
КонецЕсли;
НоваяСтрока = Лев(СтараяСтрока, ПозицияРазделителя - 1) + пМаркер + НовыйТекст;
Если пИмяСвойства <> "" Тогда
ПрисвоитьЕслиНеРавноЛкс(пОбъектИлиСвойство[пИмяСвойства], НоваяСтрока);
Иначе
ПрисвоитьЕслиНеРавноЛкс(пОбъектИлиСвойство, НоваяСтрока);
КонецЕсли;
КонецПроцедуры
// Результат - Строка - длинна не более ПорогДлины
Функция ПредставлениеЗначенияСОграничениемДлиныЛкс(Знач Значение, Знач ПорогДлины = 100, МаркерОтрезки = "...") Экспорт
ПредставлениеЗначения = "" + Значение;
Если СтрДлина(ПредставлениеЗначения) > ПорогДлины Тогда
ПредставлениеЗначения = Лев(ПредставлениеЗначения, ПорогДлины - СтрДлина(МаркерОтрезки)) + МаркерОтрезки;
КонецЕсли;
Возврат ПредставлениеЗначения;
КонецФункции
// Заменяет текущее выделение в поле текстового документа новым текстом.
// После этого устанавливает выделение на вставленный фрагмент.
//
// Параметры:
// ПолеТекстовогоДокумента - ПолеТекстовогоДокумента;
// НовыйТекст – Строка.
//
Процедура ЗаменитьВыделенныйТекстСохраняяГраницыВыделенияЛкс(ПолеТекстовогоДокумента, НовыйТекст) Экспорт
Перем НачальнаяСтрока;
Перем НачальнаяКолонка;
Перем КонечнаяСтрока;
Перем КонечнаяКолонка;
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка);
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(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:ExchangePlanRef
|");
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Если ВключаяТипыРасширений И ирКэш.НомерРежимаСовместимостиЛкс() >= 803011 И ПравоДоступа("АдминистрированиеРасширенийКонфигурации", Метаданные) Тогда
ТипыРасширений = ирКэш.ТипыРасширенийКонфигурацииЛкс("ПланОбмена");
Результат = Новый ОписаниеТипов(Результат, ТипыРасширений);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОписаниеТиповВсеСсылкиЛкс(ВключаяТипыРасширений = Истина) Экспорт
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(
"
| cc:AnyRef
|");
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Если ВключаяТипыРасширений И ирКэш.НомерРежимаСовместимостиЛкс() >= 803011 И ПравоДоступа("АдминистрированиеРасширенийКонфигурации", Метаданные) Тогда
ТипыРасширений = ирКэш.ТипыРасширенийКонфигурацииЛкс();
Результат = Новый ОписаниеТипов(Результат, ТипыРасширений);
КонецЕсли;
Если ирКэш.НомерРежимаСовместимостиЛкс() >= 803001 Тогда
Для Каждого ВнешнийИсточникДанных Из Вычислить("ВнешниеИсточникиДанных") Цикл // Для компиляции на платформе 8.2.13-
Результат = Новый ОписаниеТипов(Результат, ВнешнийИсточникДанных.Таблицы.ТипВсеСсылки().Типы());
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОписаниеТиповВсеРедактируемыеТипыЛкс() Экспорт
ОписаниеТипов = ОписаниеТиповВсеСсылкиЛкс();
ДополнительныеТипы = Новый Массив();
ДополнительныеТипы.Добавить(Тип("Строка"));
ДополнительныеТипы.Добавить(Тип("Число"));
ДополнительныеТипы.Добавить(Тип("Дата"));
ДополнительныеТипы.Добавить(Тип("Булево"));
ДополнительныеТипы.Добавить(Тип("СписокЗначений"));
ДополнительныеТипы.Добавить(Тип("Массив"));
ДополнительныеТипы.Добавить(Тип("ОписаниеТипов"));
ДополнительныеТипы.Добавить(Тип("МоментВремени"));
ДополнительныеТипы.Добавить(Тип("Граница"));
ДополнительныеТипы.Добавить(Тип("СтандартнаяДатаНачала"));
ДополнительныеТипы.Добавить(Тип("СтандартныйПериод"));
ДополнительныеТипы.Добавить(Тип("ТаблицаЗначений"));
ДополнительныеТипы.Добавить(Тип("ДеревоЗначений"));
ДополнительныеТипы.Добавить(Тип("ТабличныйДокумент"));
ДополнительныеТипы.Добавить(Тип("ВидДвиженияНакопления"));
ДополнительныеТипы.Добавить(Тип("ВидДвиженияБухгалтерии"));
ДополнительныеТипы.Добавить(Тип("ВидСчета"));
ДополнительныеТипы.Добавить(Тип("Тип"));
ДополнительныеТипы.Добавить(Тип("Null"));
ДополнительныеТипы.Добавить(Тип("ПолеКомпоновкиДанных"));
//ДополнительныеТипы.Добавить(Тип("ВидТочкиМаршрутаБизнесПроцесса")); // нельзя добавить, т.к. для этого типа не поддерживается сериализация
//ДополнительныеТипы.Добавить(Тип("ВидПериодаРегистраРасчета")); // нельзя добавить, т.к. для этого типа не поддерживается сериализация
ДополнительныеТипы.Добавить(Тип("УникальныйИдентификатор"));
ДополнительныеТипы.Добавить(Тип("ХранилищеЗначения"));
ДополнительныеТипы.Добавить(Тип("ДвоичныеДанные"));
// Из-за бага платформы отключены
//ДополнительныеТипы.Добавить(Тип("ПериодичностьАгрегатаРегистраНакопления"));
//ДополнительныеТипы.Добавить(Тип("ИспользованиеАгрегатаРегистраНакопления"));
КвалификаторыЧисла = Новый КвалификаторыЧисла; //(25, 5); // Важно!
ОписаниеТипов = Новый ОписаниеТипов(ОписаниеТипов, ДополнительныеТипы, , КвалификаторыЧисла);
Возврат ОписаниеТипов;
КонецФункции
Функция ОписаниеТиповИзТипаЛкс(Тип) Экспорт
Массив = Новый Массив;
Массив.Добавить(Тип);
Результат = Новый ОписаниеТипов(Массив);
Возврат Результат;
КонецФункции
Функция ЭтоОписаниеТиповПростогоСсылочногоТипаЛкс(Знач ОписаниеТипов, БезУчетаNULL = Истина) Экспорт
Если БезУчетаNULL Тогда
ОписаниеТипов = Новый ОписаниеТипов(ОписаниеТипов, , "NULL");
КонецЕсли;
ЭтоОписаниеТиповПростогоСсылочногоТипа = ОписаниеТипов.Типы().Количество() = 1 И ирОбщий.ЛиТипСсылкиБДЛкс(ОписаниеТипов.Типы()[0]);
Возврат ЭтоОписаниеТиповПростогоСсылочногоТипа;
КонецФункции
Функция РежимСовместимостиМеньше8_3_4Лкс() Экспорт
Возврат ирКэш.НомерРежимаСовместимостиЛкс() < 803004;
КонецФункции
Процедура ДобавитьКолонкуЕслиНетЛкс(КолонкиДереваИлиТаблицы, ИмяКолонки, ОписаниеТипов = Неопределено,
Заголовок = Неопределено, Ширина = 0) Экспорт
Если КолонкиДереваИлиТаблицы.Найти(ИмяКолонки) <> Неопределено Тогда
Возврат;
КонецЕсли;
КолонкиДереваИлиТаблицы.Добавить(ИмяКолонки, ОписаниеТипов, Заголовок, Ширина);
КонецПроцедуры // ДобавитьКолонкуЕслиНетЛкс()
Функция Дерево_ПутьМассивомЛкс(СтрокаДерева, ИмяКлючевойКолонки = "") Экспорт
Координаты = Новый Массив();
Родитель = СтрокаДерева;
Пока Родитель <> Неопределено Цикл
Если ЗначениеЗаполнено(ИмяКлючевойКолонки) Тогда
Координата = Родитель[ИмяКлючевойКолонки];
Иначе
Координата = ПолучитьРодителяСтрокиДереваЛкс(Родитель).Строки.Индекс(Родитель);
КонецЕсли;
Координаты.Вставить(0, Координата);
Родитель = Родитель.Родитель;
КонецЦикла;
Возврат Координаты;
КонецФункции
Функция Дерево_НайтиПоПутиМассивомЛкс(Дерево, Координаты, ИмяКлючевойКолонки = "") Экспорт
#Если Сервер И Не Сервер Тогда
Дерево = Новый ДеревоЗначений;
#КонецЕсли
СтрокаДерева = Дерево;
Для Каждого Координата Из Координаты Цикл
Если ЗначениеЗаполнено(ИмяКлючевойКолонки) Тогда
СтрокаДерева = СтрокаДерева.Строки.Найти(Координата, ИмяКлючевойКолонки);
Иначе
СтрокаДерева = СтрокаДерева.Строки[Координата];
КонецЕсли;
КонецЦикла;
Возврат СтрокаДерева;
КонецФункции
// Результат - Массив
Функция ПолучитьАдресСтрокиДереваЗначенийЛкс(Знач СтрокаДерева, Знач ИмяКлючевойКолонки = "Ссылка") Экспорт
КлючиУровней = Новый Массив();
ТекущаяСтрока = СтрокаДерева;
Пока ТекущаяСтрока <> Неопределено Цикл
КлючиУровней.Вставить(0, ТекущаяСтрока[ИмяКлючевойКолонки]);
ТекущаяСтрока = ТекущаяСтрока.Родитель;
КонецЦикла;
Возврат КлючиУровней;
КонецФункции
// Результат - Массив
Функция ПолучитьАдресСтрокиДереваФормыЛкс(Знач СтрокаДерева, Знач ИмяКлючевойКолонки = "Ссылка") Экспорт
КлючиУровней = Новый Массив();
ТекущаяСтрока = СтрокаДерева;
Пока ТекущаяСтрока <> Неопределено Цикл
КлючиУровней.Вставить(0, ТекущаяСтрока[ИмяКлючевойКолонки]);
ТекущаяСтрока = ТекущаяСтрока.ПолучитьРодителя();
КонецЦикла;
Возврат КлючиУровней;
КонецФункции
// Параметры:
// ИмяКолонки - Строка - если задать пустое значение, то будет использован индекс строк дерева
// ИгнорироватьПростойПервыйУровень - Булево - если на первом уровне только одна строка, то игнорировать ее
Функция Дерево_ПутьСтрокойЛкс(СтрокаДерева, ИмяКолонки = "Имя", ИгнорироватьПростойПервыйУровень = Ложь, Разделитель = ".", Дерево = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Родитель = ПолучитьРодителяСтрокиДереваЛкс(СтрокаДерева, Дерево);
Если Ложь
Или ТипЗнч(Родитель) = Тип("ДеревоЗначений")
Или ТипЗнч(Родитель) = Тип("СтрокаДереваЗначений")
Тогда
Результат = Родитель.Строки.Индекс(СтрокаДерева);
ИначеЕсли Ложь
Или ТипЗнч(Родитель) = Тип("ОтборКомпоновкиДанных")
Или ТипЗнч(Родитель) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
Или ТипЗнч(Родитель) = Тип("ДоступныеПоляКомпоновкиДанных")
Или ТипЗнч(Родитель) = Тип("ДоступноеПолеКомпоновкиДанных")
Или ТипЗнч(Родитель) = Тип("ДоступноеПолеОтбораКомпоновкиДанных")
Тогда
Результат = Родитель.Элементы.Индекс(СтрокаДерева);
ИначеЕсли Ложь
Или ТипЗнч(Родитель) = Тип("ДанныеФормыДерево")
Или ТипЗнч(Родитель) = Тип("ДанныеФормыЭлементДерева")
Тогда
Результат = Родитель.ПолучитьЭлементы().Индекс(СтрокаДерева);
Иначе
ВызватьИсключение "Неподдерживаемый тип элемента дерева - " + ТипЗнч(Родитель);
КонецЕсли;
Иначе
Результат = СтрокаДерева[ИмяКолонки];
КонецЕсли;
Попытка
Родитель = СтрокаДерева.Родитель;
Исключение
Родитель = СтрокаДерева.ПолучитьРодителя();
КонецПопытки;
Если Родитель = Неопределено Тогда
Если Истина
И ИгнорироватьПростойПервыйУровень
И СтрокаДерева.Владелец().Строки.Количество() = 1
Тогда
Результат = Неопределено;
КонецЕсли;
Иначе
РезультатСверху = Дерево_ПутьСтрокойЛкс(Родитель, ИмяКолонки, ИгнорироватьПростойПервыйУровень, Разделитель, Дерево);
Если РезультатСверху <> Неопределено Тогда
Результат = РезультатСверху + Разделитель + Результат;
КонецЕсли;
КонецЕсли;
Возврат XMLСтрока(Результат);
КонецФункции
// Параметры:
// ИмяКолонки - Строка - если задать пустое значение, то будет использован индекс строк дерева
// ИгнорироватьПростойПервыйУровень - Булево - если на первом уровне только одна строка, то игнорировать ее
Функция Дерево_НайтиПоПутиСтрокойЛкс(СтрокаДерева, ИмяКолонки = "Имя", Путь, ИгнорироватьПростойПервыйУровень = Ложь) Экспорт
Если Истина
И ИгнорироватьПростойПервыйУровень
И ТипЗнч(СтрокаДерева) = Тип("ДеревоЗначений")
И СтрокаДерева.Строки.Количество() = 1
Тогда
Возврат Дерево_НайтиПоПутиСтрокойЛкс(СтрокаДерева.Строки[0], ИмяКолонки, Сред(Путь, 2));
КонецЕсли;
ТекущийУровень = ПервыйФрагментЛкс(Путь);
Если Не ЗначениеЗаполнено(ТекущийУровень) Тогда
Возврат СтрокаДерева;
КонецЕсли;
ОстальнойПуть = Сред(Путь, СтрДлина(ТекущийУровень) + 2);
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ЗначениеИндекса = Число(ТекущийУровень);
Если Ложь
Или ТипЗнч(СтрокаДерева) = Тип("ДеревоЗначений")
Или ТипЗнч(СтрокаДерева) = Тип("СтрокаДереваЗначений")
Тогда
Если СтрокаДерева.Строки.Количество() > ЗначениеИндекса Тогда
ТекущаяСтрока = СтрокаДерева.Строки[ЗначениеИндекса];
КонецЕсли;
ИначеЕсли Ложь
Или ТипЗнч(СтрокаДерева) = Тип("ОтборКомпоновкиДанных")
Или ТипЗнч(СтрокаДерева) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
Или ТипЗнч(СтрокаДерева) = Тип("ДоступныеПоляКомпоновкиДанных")
Или ТипЗнч(СтрокаДерева) = Тип("ДоступноеПолеКомпоновкиДанных")
Или ТипЗнч(СтрокаДерева) = Тип("ДоступноеПолеОтбораКомпоновкиДанных")
Тогда
Если СтрокаДерева.Элементы.Количество() > ЗначениеИндекса Тогда
ТекущаяСтрока = СтрокаДерева.Элементы[ЗначениеИндекса];
КонецЕсли;
ИначеЕсли Ложь
Или ТипЗнч(СтрокаДерева) = Тип("ДанныеФормыДерево")
Или ТипЗнч(СтрокаДерева) = Тип("ДанныеФормыЭлементДерева")
Тогда
Если СтрокаДерева.ПолучитьЭлементы().Количество() > ЗначениеИндекса Тогда
ТекущаяСтрока = СтрокаДерева.ПолучитьЭлементы()[ЗначениеИндекса];
КонецЕсли;
Иначе
ВызватьИсключение "Неподдерживаемый тип элемента дерева - " + ТипЗнч(СтрокаДерева);
КонецЕсли;
Иначе
ТекущаяСтрока = СтрокаДерева.Строки.Найти(ТекущийУровень, ИмяКолонки);
КонецЕсли;
Если ТекущаяСтрока <> Неопределено Тогда
Возврат Дерево_НайтиПоПутиСтрокойЛкс(ТекущаяСтрока, ИмяКолонки, ОстальнойПуть);
Иначе
Возврат СтрокаДерева;
КонецЕсли;
КонецФункции // Дерево_НайтиПоПутиСтрокойЛкс()
// Процедура заполняет колонку дерева значением.
//
// Параметры
// ЭлементДЗ - ДеревоЗначений;
// ИмяКолонки - Строка;
// ЗначениеКолонки - Произвольный.
//
Процедура ЗаполнитьКолонкуДереваЛкс(ЭлементДЗ, ИмяКолонки, ЗначениеКолонки) Экспорт
Для Каждого ПодчиненнаяСтрока Из ЭлементДЗ.Строки Цикл
ПодчиненнаяСтрока[ИмяКолонки] = ЗначениеКолонки;
ЗаполнитьКолонкуДереваЛкс(ПодчиненнаяСтрока, ИмяКолонки, ЗначениеКолонки);
КонецЦикла;
КонецПроцедуры // ЗаполнитьКолонкуДереваЛкс
// Процедура удаляет все строки дерева со значением в колонке.
//
// Параметры
// ЭлементДЗ - ДеревоЗначений;
// ИмяКолонки - Строка;
// ЗначениеКолонки - Произвольный.
//
Процедура УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс(ЭлементДЗ, ИмяКолонки, ЗначениеКолонки) Экспорт
НачальноеКоличество = ЭлементДЗ.Строки.Количество();
Для Счетчик = 1 По НачальноеКоличество Цикл
ПодчиненнаяСтрока = ЭлементДЗ.Строки[НачальноеКоличество - Счетчик];
Если ПодчиненнаяСтрока[ИмяКолонки] = ЗначениеКолонки Тогда
ЭлементДЗ.Строки.Удалить(ПодчиненнаяСтрока);
Иначе
УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс(ПодчиненнаяСтрока, ИмяКолонки, ЗначениеКолонки);
КонецЕсли;
КонецЦикла;
КонецПроцедуры // УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс
// <Описание процедуры>
//
// Параметры:
// <Параметр1> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>.
//
Функция ДекодироватьТекстИзXMLЛкс(Знач Текст) Экспорт
//{ Заменяем символы, критичные для XML
Текст = СтрЗаменить(Текст,"&","&");
Текст = СтрЗаменить(Текст,"<","<");
Текст = СтрЗаменить(Текст,">",">");
Результат = Текст;
// Этот способ вернет пустую строку, если текст содержит XML элемент
//ЧтениеXML = Новый ЧтениеXML;
//ЧтениеXML.УстановитьСтроку("<ф>" + Текст + "ф>");
//ЧтениеXML.Прочитать();
//ЧтениеXML.Прочитать();
//Результат = ЧтениеXML.Значение;
Возврат Результат;
КонецФункции
Функция КодироватьТекстВXMLЛкс(Текст) Экспорт
Если Текст = "" Тогда
Возврат "";
КонецЕсли;
//{ Заменяем символы, критичные для XML
//выхХМЛТело = СтрЗаменить(выхХМЛТело,"&","&");
//выхХМЛТело = СтрЗаменить(выхХМЛТело,"<","<");
//выхХМЛТело = СтрЗаменить(выхХМЛТело,">",">");
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("");
ЗаписьXML.ЗаписатьНачалоЭлемента("ф");
ЗаписьXML.ЗаписатьТекст(Текст);
ЗаписьXML.ЗаписатьКонецЭлемента();
Результат = СтрокаМеждуМаркерамиЛкс(ЗаписьXML.Закрыть(), "<ф>", "ф>", Ложь);
Возврат Результат;
КонецФункции
Функция СтрокаВнутрВХМЛТелоЛкс(вхСтрока, выхХМЛТело = Неопределено) Экспорт
//{ Получение одной длинной строки
выхХМЛТело = СтрЗаменить(вхСтрока,СИМВОЛЫ.ПС,"");
выхХМЛТело = СтрЗаменить(выхХМЛТело,СИМВОЛЫ.ВК,"");
//}
выхХМЛТело = КодироватьТекстВXMLЛкс(выхХМЛТело);
//{ Замена одинарных символов
выхХМЛТело = СтрЗаменить(выхХМЛТело,",","");
выхХМЛТело = СтрЗаменить(выхХМЛТело,"{","");
выхХМЛТело = СтрЗаменить(выхХМЛТело,"}","");
//}
//{ Удаляем лишние блоки и
выхХМЛТело = СтрЗаменить(выхХМЛТело,"","");
выхХМЛТело = СтрЗаменить(выхХМЛТело,"","");
//}
//{ Добавляем перенос строки к и к для удобства поиска различий
выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""+СИМВОЛЫ.ПС);
выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""+СИМВОЛЫ.ПС);
//}
Возврат выхХМЛТело;
КонецФункции
Функция НоваяВКОбщаяЛкс() Экспорт
Попытка
ВК = Новый ("AddIn.ирОбщая.AddIn");
Исключение
Это64битныйПроцесс = ирКэш.Это64битныйПроцессЛкс();
ИмяМакета = "ВК";
Если Это64битныйПроцесс Тогда
ИмяМакета = ИмяМакета + "64";
Иначе
ИмяМакета = ИмяМакета + "32";
КонецЕсли;
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ДвоичныеДанные = ирПортативный.ПолучитьМакет(ИмяМакета);
Иначе
ДвоичныеДанные = Обработки.ирПортативный.ПолучитьМакет(ИмяМакета);
КонецЕсли;
АдресКомпоненты = ПолучитьИмяВременногоФайла("dll");
ДвоичныеДанные.Записать(АдресКомпоненты);
//АдресКомпоненты = "D:\VC\Native_Comp_RDT\binWin32\AddInNative.dll"; // Для отладки
Результат = ПодключитьВнешнююКомпоненту(АдресКомпоненты, "ирОбщая", ТипВнешнейКомпоненты.Native);
Если Не Результат Тогда
ВызватьИсключение "Не удалось подключить внешнюю компоненту Общая";
КонецЕсли;
ВК = Новый ("AddIn.ирОбщая.AddIn");
КонецПопытки;
Возврат ВК;
КонецФункции
// Получает структуру для индикации прогресса цикла.
//
// Параметры:
// КоличествоПроходов – Число - максимальное значение счетчика;
// ПредставлениеПроцесса – Строка, *"Выполнено" – отображаемое название процесса;
// КоличествоОбновлений - Число, *100 - всего количество обновлений индикатора;
// ЛиВыводитьВремя - Булево, *Истина - выводить приблизительное время до окончания процесса;
// РазрешитьПрерывание - Булево, *Истина - разрешает пользователю прерывать процесс.
// МинимальныйПериодОбновления - Число, *1 - с, обновлять не чаще чем этот период, 0 - по количеству обновлений,
// эта реализация не поддерживает дробные значения;
// ТаблицаИндикаторов - ТаблицаЗначений,* - передается при необходимости многоуровневой индикации
//
// Возвращаемое значение:
// Структура - которую потом нужно будет передавать в метод ОбработатьИндикаторЛкс.
//
Функция ПолучитьИндикаторПроцессаЛкс(Знач КоличествоПроходов = 0, ПредставлениеПроцесса = "Выполнение",
Знач КоличествоОбновлений = 0, ЛиВыводитьВремя = Истина, РазрешитьПрерывание = Истина, МинимальныйПериодОбновления = 1,
ТаблицаИндикаторов = Неопределено) Экспорт
ирПлатформа = ирКэш.Получить();
Если Не ЗначениеЗаполнено(КоличествоПроходов) Тогда
//#Если Клиент Тогда
// СостояниеЛкс(ПредставлениеПроцесса + "...");
//#КонецЕсли
КоличествоПроходов = 0;
КонецЕсли;
КоличествоПроходов = Цел(КоличествоПроходов);
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
Если ТаблицаИндикаторов.Количество() = 0 Тогда
#Если Клиент Тогда
ПодключитьГлобальныйОбработчикОжиданияЛкс("ОсвободитьВсеИндикаторыПроцессовОтложенноЛкс");
#КонецЕсли
ИначеЕсли ТаблицаИндикаторов.Количество() >= 10 Тогда
ВызватьИсключение "Превышена допустимая глубина вложенности индикаторов";
КонецЕсли;
Индикатор = ТаблицаИндикаторов.Добавить();
Индикатор.КоличествоПроходов = КоличествоПроходов;
Индикатор.ПредставлениеПроцесса = ПредставлениеПроцесса;
Индикатор.ЛиВыводитьВремя = ЛиВыводитьВремя;
Индикатор.РазрешитьПрерывание = РазрешитьПрерывание;
Индикатор.ДатаНачалаПроцесса = ТекущаяДата();
Индикатор.МинимальныйПериодОбновления = МинимальныйПериодОбновления;
Индикатор.ДатаСледующегоОбновления = Индикатор.ДатаНачалаПроцесса + Индикатор.МинимальныйПериодОбновления;
Если КоличествоОбновлений > 0 Тогда
Шаг = КоличествоПроходов / КоличествоОбновлений;
Иначе
Шаг = 0;
КонецЕсли;
Индикатор.Шаг = Шаг;
//Индикатор.СледующийСчетчик = 0;
//Индикатор.Счетчик = 0;
Возврат Индикатор;
КонецФункции // ПолучитьИндикаторПроцессаЛкс()
Функция ПолучитьТекстСостоянияИндикатораЛкс(Индикатор) Экспорт
Счетчик = Индикатор.Счетчик;
Если Истина
И Индикатор.ЛиВыводитьВремя
И Счетчик > 0
И Счетчик < Индикатор.КоличествоПроходов
Тогда
ТекущаяДата = ТекущаяДата();
ПрошлоВремени = ТекущаяДата - Индикатор.ДатаНачалаПроцесса;
Осталось = ПрошлоВремени * (Индикатор.КоличествоПроходов / Счетчик - 1);
ОсталосьДней = Цел(Осталось / (24*60*60));
ТекстОсталось = ", Осталось: ";
Если ОсталосьДней > 0 Тогда
ТекстОсталось = ТекстОсталось + ОсталосьДней + "д";
КонецЕсли;
ТекстОсталось = ТекстОсталось + Формат(Дата(1,1,1) + Осталось, "ДЛФ=T");
Иначе
ТекстОсталось = "";
КонецЕсли;
Если Индикатор.КоличествоПроходов > 0 Тогда
ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": "
+ Формат(Счетчик / Индикатор.КоличествоПроходов * 100, "ЧЦ=3; ЧДЦ=0; ЧН=") + "%" + ТекстОсталось;
Иначе
ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Счетчик + " ";
КонецЕсли;
Возврат ТекстСостояния;
КонецФункции
// Вызов метода при без параметра СтрокаИндикатора освобождает один полученный последним индикатор процесса. В качестве параметра этого метода можно передавать и конкретный индикатор процесса. При освобождении индикатора процесса выполняется либо его удаление из базы данных (без постоянного хранения состояния), либо сохранение его текущего состояния в базу данных (с постоянным хранением состояния)
// Параметры:
// СтрокаИндикатора - Неопределено, СтрокаТаблицыЗначений - Если Неопределено, то освобождается последний индикатор
// ВывестиИтогИндикации - Булево
// ТолькоВосстановитьСостояние - Булево - Устанавливается при обратном COM вызове
//
Процедура ОсвободитьИндикаторПроцессаЛкс(Знач Индикатор = Неопределено, Знач ВывестиИтогИндикации = Ложь) Экспорт
ирПлатформа = ирКэш.Получить();
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
Если Индикатор = Неопределено Тогда
Если ТаблицаИндикаторов.Количество() > 0 Тогда
Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1];
КонецЕсли;
КонецЕсли;
ИзменялосьСостояние = Индикатор <> Неопределено И ЗначениеЗаполнено(Индикатор.ТекстСостояния);
Если Индикатор <> Неопределено Тогда
Если ВывестиИтогИндикации Тогда
СообщитьИтогИндикацииЛкс(Индикатор);
КонецЕсли;
Если ТаблицаИндикаторов <> Неопределено Тогда
Если ТаблицаИндикаторов.Индекс(Индикатор) <> -1 Тогда
ТаблицаИндикаторов.Удалить(Индикатор);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ИзменялосьСостояние Тогда
Если Ложь
Или ТаблицаИндикаторов = Неопределено
Или ТаблицаИндикаторов.Количество() = 0
Тогда
НовоеСостояние = "";
Иначе
НовоеСостояние = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1].ТекстСостояния;
КонецЕсли;
#Если Клиент Тогда
СостояниеЛкс(НовоеСостояние,, Истина);
#КонецЕсли
КонецЕсли;
КонецПроцедуры
Процедура ОсвободитьВсеИндикаторыПроцессовЛкс() Экспорт
ирПлатформа = ирКэш.Получить();
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
//Для Каждого СтрокаИндикатора Из ТаблицаИндикаторов Цикл
// ОбработатьИндикаторЛкс(СтрокаИндикатора, , Истина);
//КонецЦикла;
ТаблицаИндикаторов.Очистить();
КонецПроцедуры
// Проверяет и обновляет индикатор. Нужно вызывать на каждом проходе индицируемого цикла.
//
// Параметры:
// Индикатор – Структура – индикатора, полученная методом ПолучитьИндикаторПроцессаЛкс;
// Счетчик – Число, *Неопределено – внешний счетчик цикла.
//
Функция ОбработатьИндикаторЛкс(Индикатор, Счетчик = Неопределено) Экспорт
#Если Клиент Тогда
Попытка
Если Индикатор.РазрешитьПрерывание Тогда
ОбработкаПрерыванияПользователя();
КонецЕсли;
Исключение
// На клиенте бывает, что строка таблицы индикаторов уже была удалена из-за модальности и обработчиков ожидания
Возврат Ложь;
КонецПопытки;
#КонецЕсли
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Если Счетчик = Неопределено Тогда
Счетчик = Индикатор.Счетчик + 1;
КонецЕсли;
Индикатор.Счетчик = Счетчик;
ОбновитьИндикатор = Истина;
ОчиститьСостояние = Ложь;
Если Ложь
Или Счетчик < Индикатор.КоличествоПроходов
Или Индикатор.КоличествоПроходов = 0
Тогда
Если Индикатор.МинимальныйПериодОбновления > 0 Тогда
ТекущаяДата = ТекущаяДата();
Если ТекущаяДата >= Индикатор.ДатаСледующегоОбновления Тогда
Индикатор.ДатаСледующегоОбновления = ТекущаяДата + Индикатор.МинимальныйПериодОбновления;
Иначе
ОбновитьИндикатор = Ложь;
КонецЕсли;
КонецЕсли;
Если ОбновитьИндикатор Тогда
Если Индикатор.Шаг > 0 Тогда
Если Счетчик < Индикатор.СледующийСчетчик Тогда
ОбновитьИндикатор = Ложь;
КонецЕсли;
//Иначе
// ОбновитьИндикатор = Ложь;
// ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Счетчик + " ";
// СостояниеЛкс(ТекстСостояния,, Истина);
КонецЕсли;
КонецЕсли;
Иначе
Если ТипЗнч(Индикатор) <> Тип("СтрокаТаблицыЗначений") Тогда
ОчиститьСостояние = Истина;
ОбновитьИндикатор = Ложь;
КонецЕсли;
КонецЕсли;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Если Счетчик = Неопределено Тогда Счетчик = Индикатор.Счетчик + 1; КонецЕсли; Индикатор.Счетчик = Счетчик; ОбновитьИндикатор = Истина; ОчиститьСостояние = Ложь; Если Ложь Или Счетчик < Индикатор.КоличествоПроходов Или Индикатор.КоличествоПроходов = 0 Тогда ТекущаяДата = ТекущаяДата(); Если Индикатор.МинимальныйПериодОбновления > 0 Тогда Если ТекущаяДата >= Индикатор.ДатаСледующегоОбновления Тогда Индикатор.ДатаСледующегоОбновления = ТекущаяДата + Индикатор.МинимальныйПериодОбновления; Иначе ОбновитьИндикатор = Ложь; КонецЕсли; КонецЕсли; Если ОбновитьИндикатор Тогда Если Индикатор.Шаг > 0 Тогда Если Счетчик < Индикатор.СледующийСчетчик Тогда ОбновитьИндикатор = Ложь; КонецЕсли; КонецЕсли; КонецЕсли; Иначе Если ТипЗнч(Индикатор) <> Тип("СтрокаТаблицыЗначений") Тогда ОчиститьСостояние = Истина; ОбновитьИндикатор = Ложь; КонецЕсли; КонецЕсли;
#Если Клиент Тогда
Если ОчиститьСостояние Тогда
СостояниеЛкс("",, Истина);
КонецЕсли;
#КонецЕсли
Если ОбновитьИндикатор Тогда
Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг);
Если ТипЗнч(Индикатор) = Тип("СтрокаТаблицыЗначений") Тогда
МассивИндикаторов = Индикатор.Владелец();
Иначе
МассивИндикаторов = Новый Массив;
МассивИндикаторов.Добавить(Индикатор);
КонецЕсли;
Если ирКэш.ЭтоФоновоеЗаданиеЛкс() Тогда
СтруктураИндикатора = СтруктураИзСтрокиТаблицыИлиДереваИлиВыборкиЛкс(Индикатор);
ТекстСостояния = "#Индикатор-" + ЗначениеВСтрокуВнутр(МассивИндикаторов);
СообщитьЛкс(ТекстСостояния);
Иначе
#Если Клиент Тогда
лИндикатор = ОбновитьТекстСостоянияВсехИндикаторовЛкс(МассивИндикаторов);
СостояниеЛкс(лИндикатор.ТекстСостояния, Индикатор.РазрешитьПрерывание, Истина);
#КонецЕсли
КонецЕсли;
КонецЕсли;
Возврат ОбновитьИндикатор;
КонецФункции
Функция ОбновитьТекстСостоянияВсехИндикаторовЛкс(Знач МассивИндикаторов)
ТекстСостояния = "";
Для Каждого лИндикатор Из МассивИндикаторов Цикл
Если ТекстСостояния <> "" Тогда
ТекстСостояния = ТекстСостояния + ".>> ";
КонецЕсли;
ТекстСостояния = ТекстСостояния + ПолучитьТекстСостоянияИндикатораЛкс(лИндикатор);
КонецЦикла;
лИндикатор.ТекстСостояния = ТекстСостояния;
Возврат лИндикатор;
КонецФункции
// Функция сравнивает две таблицы значений на идентичность структуры и данных
//
// Параметры
// ТаблицаЗначений1 - ТаблицаЗначений для сравнения
// ТаблицаЗначений2 - ТаблицаЗначений для сравнения
//
// Возвращаемое значение:
// Булево, идентичны или нет две таблицы
//
Функция ТаблицыЗначенийРавныЛкс(ТаблицаЗначений1, ТаблицаЗначений2) Экспорт
Если ТипЗнч(ТаблицаЗначений1) <> Тип("ТаблицаЗначений") ИЛИ ТипЗнч(ТаблицаЗначений2) <> Тип("ТаблицаЗначений") Тогда
Возврат Ложь;
КонецЕсли;
Если ТаблицаЗначений1.Количество() <> ТаблицаЗначений2.Количество() Тогда
Возврат Ложь;
КонецЕсли;
Если ТаблицаЗначений1.Колонки.Количество() <> ТаблицаЗначений2.Колонки.Количество() Тогда
Возврат Ложь;
КонецЕсли;
Для каждого Колонка Из ТаблицаЗначений1.Колонки Цикл
Если ТаблицаЗначений2.Колонки.Найти(Колонка.Имя) = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Для каждого СтрокаТаблицы1 Из ТаблицаЗначений1 Цикл
СтрокаТаблицы2 = ТаблицаЗначений2[ТаблицаЗначений1.Индекс(СтрокаТаблицы1)];
Если СтрокаТаблицы1[Колонка.Имя] <> СтрокаТаблицы2[Колонка.Имя] Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для каждого СтрокаТаблицы1 Из ТаблицаЗначений1 Цикл СтрокаТаблицы2 = ТаблицаЗначений2[ТаблицаЗначений1.Индекс(СтрокаТаблицы1)]; Если СтрокаТаблицы1[Колонка.Имя] <> СтрокаТаблицы2[Колонка.Имя] Тогда Возврат Ложь; КонецЕсли; КонецЦикла;
КонецЦикла;
Возврат Истина;
КонецФункции // СравнитьТаблицыЗначений()
Процедура ФункциональныеОпцииОбъектаМДЛкс(ОбъектМД, выхЗначенияФункОпций, выхСписокФункОпций = Неопределено, выхФункциональныеОпцииВключены = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Обработки
#КонецЕсли
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
выхЗначенияФункОпций = Новый Структура;
выхФункциональныеОпцииВключены = Неопределено;
ОпцииОбъектовМД = ирКэш.ФункциональныеОпцииОбъектовМДЛкс();
Для Каждого СтрокаОпции Из ОпцииОбъектовМД.НайтиСтроки(Новый Структура("ИмяОбъектаМД", ПолноеИмяМД)) Цикл
выхФункциональныеОпцииВключены = Ложь;
ОпцияВключена = ПолучитьФункциональнуюОпцию(СтрокаОпции.ИмяОпции);
выхЗначенияФункОпций.Вставить(СтрокаОпции.ИмяОпции, ОпцияВключена);
Если ОпцияВключена Тогда
выхФункциональныеОпцииВключены = Истина;
КонецЕсли;
КонецЦикла;
Если выхФункциональныеОпцииВключены = Неопределено Тогда
выхФункциональныеОпцииВключены = Истина;
КонецЕсли;
выхСписокФункОпций = Новый СписокЗначений;
Для Каждого КлючИЗначение Из выхЗначенияФункОпций Цикл
выхСписокФункОпций.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Ключ + " = " + ОпцияВключена);
КонецЦикла;
//Результат = Новый Структура;
//Результат.Вставить("ЗначенияФункОпций", выхЗначенияФункОпций);
//Результат.Вставить("СписокФункОпций", выхСписокФункОпций);
//Результат.Вставить("ФункциональныеОпцииВключены", выхФункциональныеОпцииВключены);
//Результат = ФункциональныеОпцииПоИмениОбъектаМДЛкс(ОбъектМД.ПолноеИмя());
//выхЗначенияФункОпций = Результат.ЗначенияФункОпций;
//выхФункциональныеОпцииВключены = Результат.ФункциональныеОпцииВключены;
//выхСписокФункОпций = Результат.СписокФункОпций;
КонецПроцедуры
#Если Клиент Тогда
Функция ИмяФормыИзСтрокиИнструментаЛкс(Знач СтрокаИнструмента) Экспорт
ИмяВыбраннойФормы = СтрокаИнструмента.ПолноеИмя;
Если Найти(ИмяВыбраннойФормы, "ОбщаяФорма.") <> 1 И Найти(ИмяВыбраннойФормы, ".Форма.") = 0 Тогда
Если Найти(ИмяВыбраннойФормы, "Справочник.") = 1 Тогда
ИмяВыбраннойФормы = ИмяВыбраннойФормы + ".ФормаСписка";
Иначе
ИмяВыбраннойФормы = ИмяВыбраннойФормы + ".Форма";
КонецЕсли;
КонецЕсли;
Возврат ИмяВыбраннойФормы;
КонецФункции
Процедура ПодключитьГлобальныйОбработчикОжиданияЛкс(ИмяМетода, Интервал = 0.1, Однократно = Истина) Экспорт
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ирПортативный.ПолучитьФорму().ПодключитьОбработчикОжидания(ИмяМетода, Интервал, Истина);
Иначе
ПодключитьОбработчикОжидания(ИмяМетода, Интервал, Истина);
КонецЕсли;
КонецПроцедуры
Процедура ОтключитьГлобальныйОбработчикОжиданияЛкс(ИмяМетода) Экспорт
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ирПортативный.ПолучитьФорму().ОтключитьОбработчикОжидания(ИмяМетода);
Иначе
ОтключитьОбработчикОжидания(ИмяМетода);
КонецЕсли;
КонецПроцедуры
Процедура ПодключитьГлобальныйОбработчикОжиданияСПараметрамиЛкс(ИмяМетода, Параметры, Интервал = 0.1, Однократно = Истина) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
Параметры = Новый Структура;
#КонецЕсли
Если мПлатформа.ПараметрыОбработчикаОжидания <> Неопределено Тогда
ВызватьИсключение "Обработчик ожидания занят";
КонецЕсли;
Параметры.Вставить("ИмяМетода", ИмяМетода);
мПлатформа.ПараметрыОбработчикаОжидания = Параметры;
ПодключитьГлобальныйОбработчикОжиданияЛкс("ГлобальныйОбработчикОжиданияСПараметрамиЛкс", Интервал, Однократно);
КонецПроцедуры
Процедура ОтлючитьГлобальныйОбработчикОжиданияСПараметрамиЛкс() Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
мПлатформа.ПараметрыОбработчикаОжидания = Неопределено;
ОтключитьГлобальныйОбработчикОжиданияЛкс("ГлобальныйОбработчикОжиданияСПараметрамиЛкс");
КонецПроцедуры
Процедура ОбработчикОжиданияСПараметрамиЛкс() Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ПараметрыОбработчикаОжидания = мПлатформа.ПараметрыОбработчикаОжидания;
Если ПараметрыОбработчикаОжидания = Неопределено Тогда
СообщитьЛкс("Не удалось выполнить страховочный обработчик ожидания, т.к. обработка ирПлатформа была удалена из кэша", СтатусСообщения.Внимание);
Возврат;
КонецЕсли;
мПлатформа.ПараметрыОбработчикаОжидания = Неопределено;
Выполнить(ПараметрыОбработчикаОжидания.ИмяМетода + "(ПараметрыОбработчикаОжидания)");
КонецПроцедуры
Процедура ОтключитьГлобальныеОбработчикиОжиданияЛкс() Экспорт
#Если ВебКлиент Или МобильныйКлиент Тогда
СообщитьЛкс("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#Иначе
Форма = ПолучитьФормуЛкс("Обработка.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Форма.ОбщиеМетоды",,, "Программно");
Форма.ПерезаполнитьТаблицуВсехМетодов();
Компоновщик = Форма.Компоновщик;
ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(Компоновщик.Настройки.Порядок, "Имя");
ирОбщий.НайтиДобавитьЭлементОтбораКомпоновкиЛкс(Компоновщик.Настройки.Отбор, "КоличествоПараметров", 0, ВидСравненияКомпоновкиДанных.Равно);
ирОбщий.НайтиДобавитьЭлементОтбораКомпоновкиЛкс(Компоновщик.Настройки.Отбор, "Глобальный", Истина);
Форма.ОбновитьДанные();
Для Каждого СтрокаМетода Из Форма.ОбщиеМетоды Цикл
ОтключитьОбработчикОжидания(СтрокаМетода.Имя);
КонецЦикла;
ирОбщий.СообщитьЛкс("Отключено " + Форма.ОбщиеМетоды.Количество() + " возможных глобальных обработчиков ожидания. Для их включения потребуется перезапуск сеанса.");
#КонецЕсли
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С ФОРМАМИ
// РежимОткрытия - Булево - Истина - Открытие, иначе Сохранение
Функция ВыбратьФайлЛкс(РежимОткрытия = Истина, Расширение = "", ОписаниеФормата = "", Знач ПолноеИмяФайла = "", Знач Каталог = "", Знач КраткоеИмя = "", Знач Заголовок = "") Экспорт
ВыборФайла = ДиалогВыбораФайлаЛкс(РежимОткрытия, Расширение, ОписаниеФормата, ПолноеИмяФайла, Каталог, КраткоеИмя, Заголовок);
Если Не ВыборФайла.Выбрать() Тогда
Возврат Неопределено;
КонецЕсли;
Возврат ВыборФайла.ПолноеИмяФайла;
КонецФункции
Функция ДиалогВыбораФайлаЛкс(РежимОткрытия = Истина, Знач Расширение = "", ОписаниеФормата = "", Знач ПолноеИмяФайла = "", Знач Каталог = "", Знач КраткоеИмя = "", Знач Заголовок = "") Экспорт
Если РежимОткрытия = Истина Тогда
РежимДиалога = РежимДиалогаВыбораФайла.Открытие;
Иначе
РежимДиалога = РежимДиалогаВыбораФайла.Сохранение;
КонецЕсли;
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалога);
ВыборФайла.Заголовок = Заголовок;
Если ЗначениеЗаполнено(ПолноеИмяФайла) Тогда
Файл = Новый Файл(ПолноеИмяФайла);
ВыборФайла.Каталог = Файл.Путь;
ВыборФайла.ПолноеИмяФайла = Файл.Имя;
Иначе
ВыборФайла.Каталог = Каталог;
ВыборФайла.ПолноеИмяФайла = КраткоеИмя;
КонецЕсли;
ВыборФайла.Расширение = Расширение;
Если Не ЗначениеЗаполнено(Расширение) Тогда
Расширение = "*";
КонецЕсли;
ВыборФайла.Фильтр = ПолучитьСтрокуФильтраДляВыбораФайлаЛкс(Расширение, ОписаниеФормата);
Возврат ВыборФайла;
КонецФункции
Функция ВыбратьКаталогВФормеЛкс(выхКаталог, ФормаДляУстановкиМодифицированности = Неопределено, Заголовок = "") Экспорт
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
ВыборФайла.Каталог = выхКаталог;
ВыборФайла.Заголовок = Заголовок;
Если Не ВыборФайла.Выбрать() Тогда
Возврат Неопределено;
КонецЕсли;
выхКаталог = ВыборФайла.Каталог;
Если ФормаДляУстановкиМодифицированности <> Неопределено Тогда
ФормаДляУстановкиМодифицированности.Модифицированность = Истина;
КонецЕсли;
Возврат выхКаталог;
КонецФункции
Процедура ПолучитьМассивЗначенийПеретаскиванияЛкс(Знач ПараметрыПеретаскивания, выхМассивЗначений, выхТипЗначенияПеретаскивания = Неопределено) Экспорт
ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение;
выхТипЗначенияПеретаскивания = ТипЗнч(ЗначениеПеретаскивания);
Если выхТипЗначенияПеретаскивания = Тип("Массив") Тогда
выхТипЗначенияПеретаскивания = ТипЗнч(ЗначениеПеретаскивания[0]);
выхМассивЗначений = ЗначениеПеретаскивания;
Иначе
выхМассивЗначений = Новый Массив;
выхМассивЗначений.Добавить(ЗначениеПеретаскивания);
КонецЕсли;
КонецПроцедуры
// Подразумевается, что имена колонок табличного поля и коллекции совпадают
// Параметры:
// ТабличноеПоле - ТабличноеПоле
// ИмяКолонкиПометки - Строка - если пустая, то берется текущая колонка типа "Булево" или колонка с именем "Пометка"
// КлючеваяКолонка - Строка - задается только для таблиц без колонки НомерСтроки при необходимости отобрать строки
// ПроверятьОформлениеСтроки - Булево - долго
Процедура ИзменитьПометкиВыделенныхИлиОтобранныхСтрокЛкс(Знач ТабличноеПоле, Знач ИмяКолонкиПометки = "", Знач НовоеЗначениеПометки = Истина, КлючеваяКолонка = "НомерСтроки",
СтруктураОтбора = Неопределено, Знач ПроверятьОформлениеСтроки = Истина, Знач ИнтерактивнаяУстановка = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
Если Не ЗначениеЗаполнено(ИмяКолонкиПометки) Тогда
КолонкаПометки = КолонкаПометкиТабличногоПоляЛкс(ТабличноеПоле);
Если КолонкаПометки <> Неопределено Тогда
ИмяКолонкиПометки = КолонкаПометки.Имя;
КонецЕсли;
КонецЕсли;
Если ТабличноеПоле.Колонки.Найти(ИмяКолонкиПометки) = Неопределено Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
Колонка = ТабличноеПоле.Колонки[ИмяКолонкиПометки];
Иначе
Колонка = ТабличноеПоле.ПодчиненныеЭлементы[ИмяКолонкиПометки];
КонецЕсли;
УстановитьЗначениеВКолонкеТабличногоПоляТЧИлиТЗЛкс(ТабличноеПоле, НовоеЗначениеПометки, "", Колонка, ТабличноеПоле.ВыделенныеСтроки.Количество() > 1, ИнтерактивнаяУстановка,, СтруктураОтбора);
Возврат;
/////////////////////////////////////////
// Оставил этот код на переходный период
СтараяТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
СтараяТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка;
СтарыеВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТабличноеПоле);
Если СтарыеВыделенныеСтроки.Количество() <= 1 Тогда
СтрокиДляОбработки = ТабличноеПоле.Значение;
Попытка
ОтборСтрок = ТабличноеПоле.ОтборСтрок;
Исключение
КонецПопытки;
Если ОтборСтрок <> Неопределено Или СтруктураОтбора <> Неопределено Тогда
Построитель = ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ТабличноеПоле, СтруктураОтбора);
#Если Сервер И Не Сервер Тогда
Построитель = Новый ПостроительЗапроса;
#КонецЕсли
Построитель.ВыбранныеПоля.Очистить();
Построитель.ВыбранныеПоля.Добавить(КлючеваяКолонка);
КлючиОтобранныхСтрок = Построитель.Результат.Выгрузить();
КлючиОтобранныхСтрок.Индексы.Добавить(КлючеваяКолонка);
КонецЕсли;
Иначе
СтрокиДляОбработки = СтарыеВыделенныеСтроки;
КонецЕсли;
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
ЭлементУправления = Колонка.ЭлементУправления;
ДействиеПриИзменении = "" + ЭлементУправления.ПолучитьДействие("ПриИзменении");
ИнтерактивнаяУстановка = ИнтерактивнаяУстановка И ЗначениеЗаполнено(ДействиеПриИзменении);
Иначе
ЭлементУправления = Колонка;
КонецЕсли;
ИспользоватьИндикатор = ПроверятьОформлениеСтроки Или ИнтерактивнаяУстановка;
Индикатор = ПолучитьИндикаторПроцессаЛкс(СтрокиДляОбработки.Количество(), "Изменение пометок");
ПоследняяОбработаннаяСтрока = Неопределено;
Для каждого СтрокаЦикл из СтрокиДляОбработки Цикл
ОбработкаПрерыванияПользователя();
Если ИспользоватьИндикатор Тогда
ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
Если Истина
И КлючиОтобранныхСтрок <> Неопределено
И КлючиОтобранныхСтрок.Найти(СтрокаЦикл[КлючеваяКолонка], КлючеваяКолонка) = Неопределено
Тогда
// Строка не отвечает отбору
Продолжить;
КонецЕсли;
Если ПроверятьОформлениеСтроки Тогда
ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(СтрокаЦикл);
Если ОформлениеСтроки.Ячейки[Колонка.Имя].ТолькоПросмотр Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если ИнтерактивнаяУстановка Тогда
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
ДействиеПриАктивизацииСтроки = ТабличноеПоле.ПолучитьДействие("ПриАктивизацииСтроки");
ТабличноеПоле.УстановитьДействие("ПриАктивизацииСтроки", Неопределено);
ТабличноеПоле.ТекущаяСтрока = СтрокаЦикл;
ТабличноеПоле.УстановитьДействие("ПриАктивизацииСтроки", ДействиеПриАктивизацииСтроки);
Иначе
ТабличноеПоле.ТекущаяСтрока = СтрокаЦикл;
КонецЕсли;
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначениеПометки,, Ложь,,, Истина);
Иначе
СтрокаЦикл[ИмяКолонкиПометки] = НовоеЗначениеПометки;
КонецЕсли;
ПоследняяОбработаннаяСтрока = СтрокаЦикл;
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Если Истина
И ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле")
И Не ИнтерактивнаяУстановка
И ПоследняяОбработаннаяСтрока <> Неопределено
Тогда
// Переустановим значение ради срабатывания события ПриИзменении без его фактического изменения, чтобы сработали механизмы подсчета количества помеченных
ТабличноеПоле.ТекущаяСтрока = ПоследняяОбработаннаяСтрока;
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, ПоследняяОбработаннаяСтрока[Колонка.Данные],,,,, Истина);
КонецЕсли;
ТабличноеПоле.ВыделенныеСтроки.Очистить();
Если СтараяТекущаяСтрока <> Неопределено Тогда
ТабличноеПоле.ТекущаяСтрока = СтараяТекущаяСтрока;
КонецЕсли;
Если СтараяТекущаяКолонка <> Неопределено Тогда
УстановитьТекущуюКолонкуТаблицыФормыЛкс(ТабличноеПоле, СтараяТекущаяКолонка);
КонецЕсли;
Для Каждого СтрокаЦикл Из СтарыеВыделенныеСтроки Цикл
ТабличноеПоле.ВыделенныеСтроки.Добавить(СтрокаЦикл);
КонецЦикла;
ТабличноеПоле.ОбновитьСтроки(); // Антибаг платформы. Без этого иногда некоторые строки были недорисованы
КонецПроцедуры
Функция ВыбратьСсылкуЛкс(ИмяТаблицыИлиМДИлиТип, НачальноеЗначениеВыбора = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено) Экспорт
Результат = ОткрытьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип,, ИспользоватьДинамическийСписокИР,, Истина,, НачальноеЗначениеВыбора, Истина);
Возврат Результат;
КонецФункции
Процедура ВыбратьИЗаполнитьТабличнуюЧастьОбъектаБДЛкс(ТаблицаИсточник, НачальноеПолноеИмяОбъекта = "") Экспорт
ФормаВыбораОбъектаБД = ирОбщий.ПолучитьФормуВыбораОбъектаМетаданныхЛкс(,, НачальноеПолноеИмяОбъекта,, Истина,, Истина, Истина,, Истина,,, Истина);
РезультатВыбора = ФормаВыбораОбъектаБД.ОткрытьМодально();
Если РезультатВыбора = Неопределено Тогда
Возврат;
КонецЕсли;
ОбъектМД = ирОбщий.ОбъектМДПоПолномуИмениТаблицыБДЛкс(РезультатВыбора.ПолноеИмяОбъекта);
ЭтоНаборЗаписей = ирОбщий.ЛиМетаданныеРегистраЛкс(ОбъектМД);
Если ЭтоНаборЗаписей Тогда
ПолноеИмяМДСписка = ОбъектМД.ПолноеИмя();
Иначе
ПолноеИмяМДСписка = ОбъектМД.Родитель().ПолноеИмя();
КонецЕсли;
МакетныйОбъект = Неопределено;
ТекущаяГруппаТипаМетаданных = Неопределено;
ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяМДСписка, МакетныйОбъект, ТекущаяГруппаТипаМетаданных);
Если ЭтоНаборЗаписей Тогда
СтруктураОбъекта = МакетныйОбъект;
ТаблицаПриемник = СтруктураОбъекта;
Иначе
ВыбраннаяСтрока = ОткрытьФормуСпискаЛкс(ПолноеИмяМДСписка,,,, Истина,,, Истина);
Если ВыбраннаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
СтруктураОбъекта = ирОбщий.ПолучитьОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(ВыбраннаяСтрока, МакетныйОбъект, ТекущаяГруппаТипаМетаданных, Истина);
ТаблицаПриемник = СтруктураОбъекта.Данные[ОбъектМД.Имя];
КонецЕсли;
Если ТаблицаПриемник.Количество() > 0 Тогда
Если ЭтоНаборЗаписей Тогда
ТекстВопроса = "Хотите очистить набор записей в памяти перед заполнением?";
Иначе
ТекстВопроса = "Выбранная табличная часть объекта не пустая. Хотите очистить ее в памяти перед заполнением?";
КонецЕсли;
Ответ = Вопрос(ТекстВопроса, РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Да);
Если Ответ = КодВозвратаДиалога.Да Тогда
ТаблицаПриемник.Очистить();
КонецЕсли;
КонецЕсли;
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИсточник, ТаблицаПриемник);
ОбработкаРедактора = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирРедакторОбъектаБД");
#Если Сервер И Не Сервер Тогда
ОбработкаРедактора = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
ФормаРедактора = ОбработкаРедактора.РедактироватьМодифицированныйОбъект(СтруктураОбъекта);
ФормаРедактора.ПоказатьЯчейкуДанныхОбъекта(РезультатВыбора.ПолноеИмяОбъекта);
КонецПроцедуры
// <Описание процедуры>
//
// Параметры:
// <Параметр1> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> – <Тип.Вид> – <описание параметра>
// <продолжение описания параметра>.
//
Функция СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс(Значение1, Значение2, Модально = Ложь,
Знач Название1 = Неопределено, Знач Название2 = Неопределено, СравнениеФайлов = Неопределено, ПолучатьXMLПредставлениеДляНеизвестныхТипов = Истина) Экспорт
Если Истина
И ТипЗнч(Значение1) = Тип("ТаблицаЗначений")
И ТипЗнч(Значение2) = Тип("ТаблицаЗначений")
Тогда
Обработка = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирСравнениеТаблиц");
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирСравнениеТаблиц.Создать();
#КонецЕсли
ФормаСравнителя = Обработка.ПолучитьФорму();
ФормаСравнителя.ПараметрТаблица1 = Значение1;
ФормаСравнителя.ПараметрТаблица2 = Значение2;
ФормаСравнителя.Открыть();
Возврат ФормаСравнителя.СравнитьТаблицыВФорме();
КонецЕсли;
Если Не ЗначениеЗаполнено(Название1) Тогда
Название1 = "первое";
КонецЕсли;
Если Не ЗначениеЗаполнено(Название2) Тогда
Название2 = "второе";
КонецЕсли;
Путь1 = ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение1, Название1, ПолучатьXMLПредставлениеДляНеизвестныхТипов);
Путь2 = ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение2, Название2, ПолучатьXMLПредставлениеДляНеизвестныхТипов);
// Думал, так будет использовать существующее окно, но этого не происходит. Пока оставил, может потом появится.
Если СравнениеФайлов = Неопределено Тогда
СравнениеФайлов = Новый СравнениеФайлов;
КонецЕсли;
СравнениеФайлов.ПервыйФайл = Путь1;
СравнениеФайлов.ВторойФайл = Путь2;
СравнениеФайлов.ИгнорироватьПустоеПространство = Ложь;
Если Истина
И ТипЗнч(Значение1) = Тип("ТабличныйДокумент")
И ТипЗнч(Значение2) = Тип("ТабличныйДокумент")
Тогда
СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТабличныйДокумент;
Иначе
СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТекстовыйДокумент;
КонецЕсли;
Если Модально Тогда
СравнениеФайлов.ПоказатьРазличияМодально();
Иначе
СравнениеФайлов.ПоказатьРазличия();
КонецЕсли;
Возврат СравнениеФайлов.Сравнить();
КонецФункции
// Сравнивает табличный документ, полученный из элемента управления с предыдущим.
//
// Параметры:
// СравнительТабличныхДокументов – Массив, *Неопределено – переменная для хранения предыдущего табличного документа.
// ЭлементУправления – ТабличноеПоле, ПолеТабличногоДокумента – откуда получаем содержимое.
//
Процедура СравнитьСодержимоеЭлементаУправленияЛкс(ЭтаФорма, ЭлементУправления) Экспорт
Если ТипЗнч(ЭлементУправления) = Тип("ПолеТекстовогоДокумента") Тогда
СравниваемыйДокумент = Новый ТекстовыйДокумент;
СравниваемыйДокумент.УстановитьТекст(ЭлементУправления.ПолучитьТекст());
ИначеЕсли ТипЗнч(ЭлементУправления) = Тип("ПолеВвода") Тогда
СравниваемыйДокумент = Новый ТекстовыйДокумент;
СравниваемыйДокумент.УстановитьТекст(ЭлементУправления.Значение);
ИначеЕсли Ложь
Или ТипЗнч(ЭлементУправления) = Тип("ТабличноеПоле")
Или ТипЗнч(ЭлементУправления) = Тип("ТаблицаФормы")
Тогда
СравниваемыйДокумент = ВывестиСтрокиТабличногоПоляСНастройкойЛкс(ЭлементУправления);
Если СравниваемыйДокумент = Неопределено Тогда
Возврат;
КонецЕсли;
ИначеЕсли Ложь
Или ТипЗнч(ЭлементУправления) = Тип("ПолеТабличногоДокумента")
Или (Истина
И ТипЗнч(ЭлементУправления) = Тип("ПолеФормы")
И ЭлементУправления.Вид = ВидПоляФормы.ПолеТабличногоДокумента)
Тогда
ТабличныйДокумент = ДанныеЭлементаФормыЛкс(ЭлементУправления);
СравниваемыйДокумент = ПолучитьОбластьТабличногоДокументаИнтерактивноЛкс(ТабличныйДокумент);
Иначе
СообщитьЛкс("Неподдерживаемый тип элемента управления для сравнения");
Возврат;
КонецЕсли;
ДобавитьДокументВБуферСравненияЛкс(СравниваемыйДокумент, ЭтаФорма);
КонецПроцедуры
Процедура ДобавитьДокументВБуферСравненияЛкс(СравниваемыйДокумент, Знач ЭтаФорма = Неопределено) Экспорт
МассивСравнения = ирКэш.БуферСравненияЛкс("" + ТипЗнч(СравниваемыйДокумент));
Если МассивСравнения.Количество() = 2 Тогда
МассивСравнения.Удалить(0);
КонецЕсли;
МассивСравнения.Добавить(СравниваемыйДокумент);
Если МассивСравнения.Количество() = 2 Тогда
Ответ = Вопрос("Сравнить с предыдущим?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Нет Тогда
Возврат;
КонецЕсли;
Если ЭтаФорма <> Неопределено Тогда
ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма);
КонецЕсли;
СравниваемыйДокумент1 = МассивСравнения[0];
СравниваемыйДокумент2 = МассивСравнения[1];
СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс(СравниваемыйДокумент1, СравниваемыйДокумент2);
Иначе
СообщитьЛкс("Первое значение для сравнения запомнено. Теперь передайте второе значение.");
КонецЕсли;
КонецПроцедуры
Функция ПолучитьОбластьТабличногоДокументаИнтерактивноЛкс(ТабличныйДокумент) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
Если Не ЛиОбластьЯчеекТабличногоДокументаОбъединенаЛкс(ТабличныйДокумент) Тогда
Ответ = Вопрос("Использовать только текущую область (Да) иначе будет использован весь документ (Нет)?", РежимДиалогаВопрос.ДаНет);
Иначе
Ответ = КодВозвратаДиалога.Нет;
КонецЕсли;
Если Ответ = КодВозвратаДиалога.Да Тогда
Результат = ТабличныйДокумент.ПолучитьОбласть(ТабличныйДокумент.ТекущаяОбласть.Имя);
ЗаполнитьЗначенияСвойств(Результат, ТабличныйДокумент,, "ВыделенныеОбласти, ТекущаяОбласть");
Иначе
Результат = ТабличныйДокумент.ПолучитьОбласть();
ЗаполнитьЗначенияСвойств(Результат, ТабличныйДокумент);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиОбластьЯчеекТабличногоДокументаОбъединенаЛкс(Знач ТабличныйДокумент, Знач ТекущаяОбласть = Неопределено)
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
Если ТекущаяОбласть = Неопределено Тогда
ТекущаяОбласть = ТабличныйДокумент.ТекущаяОбласть;
КонецЕсли;
Область = ТабличныйДокумент.Область(ТекущаяОбласть.Верх, ТекущаяОбласть.Лево);
Возврат ТекущаяОбласть.Низ = Область.Низ И ТекущаяОбласть.Право = Область.Право;
КонецФункции
Функция ВывестиСтрокиТабличногоПоляСНастройкойЛкс(Знач ТабличноеПоле, ВыводБезОформления = Истина, Знач НастройкиСписка = Неопределено, выхТекущаяСтрока = Неопределено) Экспорт
ФормаНастройки = ирКэш.Получить().ПолучитьФорму("ПараметрыВыводаСтрокТаблицы");
ФормаНастройки.ТабличноеПоле = ТабличноеПоле;
Если ВыводБезОформления <> Неопределено Тогда
ФормаНастройки.БезОформления = ВыводБезОформления;
КонецЕсли;
РезультатФормы = ФормаНастройки.ОткрытьМодально();
Если РезультатФормы = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
выхТекущаяСтрока = Неопределено;
Результат = ВывестиСтрокиТабличногоПоляЛкс(ТабличноеПоле, ФормаНастройки,, выхТекущаяСтрока, НастройкиСписка);
Возврат Результат;
КонецФункции
Функция ВывестиСтрокиТабличногоПоляЛкс(Знач ТабличноеПоле, Знач ПараметрыВывода, Отладка = Ложь, выхТекущаяСтрока = Неопределено, Знач НастройкиСписка = Неопределено) Экспорт
КлючТекущейСтроки = Неопределено;
ИндексТекущейСтроки = Неопределено;
ПолноеИмяТаблицыБД = "";
ДанныеТабличногоПоля = Неопределено;
ТипИсточника = ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле,,, ПолноеИмяТаблицыБД, ДанныеТабличногоПоля);
ВыбранныеКолонки = ПараметрыВывода.КолонкиТабличногоПоля.Выгрузить(Новый Структура("Пометка", Истина));
МассивСтрок = Неопределено;
ЗначениеТабличногоПоля = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
Если ЗначениеТабличногоПоля = Неопределено Тогда
КоллекцияСтрок = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле,,, Ложь);
ИначеЕсли ТипЗнч(ЗначениеТабличногоПоля) = Тип("ДанныеФормыДерево") Тогда
ЗначениеТабличногоПоля = ДанныеФормыВЗначение(ЗначениеТабличногоПоля, Тип("ДеревоЗначений"));
КонецЕсли;
Если ТипИсточника = "Список" И ЗначениеЗаполнено(ПолноеИмяТаблицыБД) Тогда
КлючТекущейСтроки = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Если ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(КлючТекущейСтроки, ТабличноеПоле.ТекущаяСтрока);
КонецЕсли;
Если ПараметрыВывода.ТолькоВыделенныеСтроки Тогда
КоллекцияСтрок = КлючиВыделенныхСтрокИмитатораДинамическогоСпискаЛкс(ТабличноеПоле);
ИначеЕсли ДанныеТабличногоПоля = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Иначе
Если ПараметрыВывода.ТолькоВыделенныеСтроки Тогда
МассивСтрок = ВыделенныеСтрокиТабличногоПоляЛкс(ТабличноеПоле);
КонецЕсли;
Если ТипЗнч(ЗначениеТабличногоПоля) = Тип("ДеревоЗначений") Тогда
Если МассивСтрок <> Неопределено Тогда
КоллекцияСтрок = МассивСтрок;
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
КоллекцияСтрок = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле, МассивСтрок,, Ложь);
КонецЕсли;
Иначе
КоллекцияСтрок = ЗначениеТабличногоПоля.Строки;
Если ТипЗнч(ТабличноеПоле.ТекущаяСтрока) = Тип("СтрокаДереваЗначений") Тогда
ИндексТекущейСтроки = КоллекцияСтрок.Индекс(ТабличноеПоле.ТекущаяСтрока);
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или ТипИсточника = "ТабличнаяЧасть"
Или ТипИсточника = "НаборЗаписей"
Или ТипИсточника = "ТаблицаЗначений"
Тогда
Если ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда
//ИндексТекущейСтроки = ЗначениеТабличногоПоля.Индекс(ТабличноеПоле.ТекущаяСтрока);
ИндексТекущейСтроки = ЗначениеТабличногоПоля.Индекс(ТабличноеПоле.ТекущиеДанные);
КонецЕсли;
Если ПараметрыВывода.БезОформления Тогда
КоллекцияСтрок = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле, МассивСтрок, Истина);
Иначе
Если МассивСтрок <> Неопределено Тогда
КоллекцияСтрок = МассивСтрок;
ИначеЕсли ТипИсточника = "ТаблицаЗначений" Или Не ОтборУстановленЛкс(ТабличноеПоле.ОтборСтрок) Тогда
КоллекцияСтрок = ТабличноеПоле.Значение;
Иначе
КоллекцияСтрок = Новый Массив;
КопияСтрок = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле, МассивСтрок, Истина);
Для Каждого КопияСтроки Из КопияСтрок Цикл
КоллекцияСтрок.Добавить(ТабличноеПоле.Значение[КопияСтроки.НомерСтроки - 1]);
КонецЦикла;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или ТипИсточника = "Список"
Тогда
КоллекцияСтрок = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле, МассивСтрок, Истина);
КонецЕсли;
КонецЕсли;
Если ПараметрыВывода.БезОформления Тогда
ВыбранныеКолонки = ВыбранныеКолонки.ВыгрузитьКолонку("Данные");
Если ТипИсточника = "Список" И ЗначениеЗаполнено(ПолноеИмяТаблицыБД) Тогда
КоллекцияСтрок = ДанныеСтрокДинамическогоСпискаЛкс(ТабличноеПоле, КоллекцияСтрок, ВыбранныеКолонки, НастройкиСписка, ПараметрыВывода.КоличествоПервых);
#Если Сервер И Не Сервер Тогда
КоллекцияСтрок = Новый ТаблицаЗначений;
#КонецЕсли
ВыбранныеКолонки = Неопределено;
ТекущаяСтрока = КоллекцияСтрок.НайтиСтроки(КлючТекущейСтроки);
Если ТекущаяСтрока.Количество() > 0 Тогда
ИндексТекущейСтроки = КоллекцияСтрок.Индекс(ТекущаяСтрока[0]);
КонецЕсли;
Если ЛиКорневойТипСсылкиЛкс(ТипТаблицыБДЛкс(ПолноеИмяТаблицыБД)) И ПараметрыВывода.КолонкиИдентификаторов Тогда
//ВыбранныеКолонки.Добавить("Ссылка");
КоллекцияСтрок.Колонки.Добавить("ИдентификаторСсылкиЛкс",, "Идентификатор ссылки");
//Если ВыбранныеКолонки.Найти("ИдентификаторСсылкиЛкс") = Неопределено Тогда
// ВыбранныеКолонки.Добавить("ИдентификаторСсылкиЛкс");
//КонецЕсли;
Для Каждого СтрокаКоллекции Из КоллекцияСтрок Цикл
СтрокаКоллекции.ИдентификаторСсылкиЛкс = ИдентификаторСсылкиЛкс(СтрокаКоллекции.Ссылка);
КонецЦикла;
КонецЕсли;
ИначеЕсли ТипЗнч(ЗначениеТабличногоПоля) = Тип("ДеревоЗначений") Тогда
ТаблицаСтрокДерева = Новый ТаблицаЗначений;
Для Каждого КолонкаДерева Из ЗначениеТабличногоПоля.Колонки Цикл
ТаблицаСтрокДерева.Колонки.Добавить(КолонкаДерева.Имя, КолонкаДерева.ТипЗначения, КолонкаДерева.Заголовок, КолонкаДерева.Ширина);
КонецЦикла;
Если ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияСтрокДереваЗначений") Тогда
КоллекцияСтрок = ВсеСтрокиДереваЗначенийЛкс(ЗначениеТабличногоПоля);
КонецЕсли;
Для Каждого СтрокаДерева Из КоллекцияСтрок Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтрокДерева.Добавить(), СтрокаДерева);
КонецЦикла;
КоллекцияСтрок = ТаблицаСтрокДерева;
КонецЕсли;
ИмяТекущейКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Результат = ВывестиТаблицуВТабличныйДокументИлиТаблицуЗначенийЛкс(КоллекцияСтрок,,, ПараметрыВывода.ИтогиЧисловыхКолонок,, ПараметрыВывода.ВстроитьЗначенияВРасшифровки,
ПараметрыВывода.ОтображатьПустые, ПараметрыВывода.КолонкиИдентификаторов, ПараметрыВывода.КолонкиТипов, ПараметрыВывода.КолонкиЗначений, ВыбранныеКолонки, ИмяТекущейКолонки,
ПараметрыВывода.ВыводВТаблицуЗначений, Отладка, ПараметрыВывода.КолонкиРазмеров, ПараметрыВывода.СузитьТипы);
Иначе
Если ТипИсточника = "Список" Тогда
КоллекцияСтрок = ДанныеСтрокДинамическогоСпискаЛкс(ТабличноеПоле, КоллекцияСтрок,, НастройкиСписка, ПараметрыВывода.КоличествоПервых);
#Если Сервер И Не Сервер Тогда
КоллекцияСтрок = Новый ТаблицаЗначений;
#КонецЕсли
ТекущаяСтрока = КоллекцияСтрок.НайтиСтроки(КлючТекущейСтроки);
Если ТекущаяСтрока.Количество() > 0 Тогда
ИндексТекущейСтроки = КоллекцияСтрок.Индекс(ТекущаяСтрока[0]);
КонецЕсли;
Если ЛиКорневойТипСсылкиЛкс(ТипТаблицыБДЛкс(ПолноеИмяТаблицыБД)) Тогда
КоллекцияСтрок = КоллекцияСтрок.ВыгрузитьКолонку("Ссылка");
КонецЕсли;
КонецЕсли;
ВыбранныеКолонки = ВыбранныеКолонки.ВыгрузитьКолонку("Имя");
Если ПараметрыВывода.ВыводВТаблицуЗначений Тогда
Результат = Новый ТаблицаЗначений;
Для Каждого ВыбраннаяКолонка Из ВыбранныеКолонки Цикл
Колонка = ТабличноеПоле.Колонки[ВыбраннаяКолонка];
Если Колонка.Имя = ирКэш.ИмяКолонкиНомерСтрокиЛкс() Тогда
Продолжить;
КонецЕсли;
Если Колонка.Видимость Тогда
КолонкаПриемник = Результат.Колонки.Добавить(Колонка.Имя, Новый ОписаниеТипов("Строка"), Колонка.ТекстШапки);
КонецЕсли;
КонецЦикла;
ВывестиСтрокиТабличногоПоляСОформлениемЛкс(КоллекцияСтрок,, Результат, ТабличноеПоле,, ПараметрыВывода.ВстроитьЗначенияВРасшифровки);
Иначе
Результат = Новый ТабличныйДокумент;
НомерКолонки = 1;
НомерСтроки = 1;
ОбластьТаблицы = Результат.Область();
ОбластьТаблицы.ЦветРамки = ЦветаСтиля.ЦветРамки;
ОбластьЗаголовков = Результат.Область(НомерСтроки, 0, НомерСтроки, 0);
ОбластьЗаголовков.ЦветФона = ТабличноеПоле.ЦветФонаШапки;
ОбластьЗаголовков.ЦветТекста = ТабличноеПоле.ЦветТекстаШапки;
Для Каждого ВыбраннаяКолонка Из ВыбранныеКолонки Цикл
Колонка = ТабличноеПоле.Колонки[ВыбраннаяКолонка];
Если Колонка.Имя = ирКэш.ИмяКолонкиНомерСтрокиЛкс() Тогда
Продолжить;
КонецЕсли;
Если Колонка.Видимость Тогда
ОбластьЗаголовка = Результат.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки);
ОбластьЗаголовка.Текст = Колонка.ТекстШапки;
ОбластьЗаголовка.ЦветФона = Колонка.ЦветФонаШапки;
ОбластьЗаголовка.ЦветТекста = Колонка.ЦветТекстаШапки;
//ШиринаКолонки = Колонка.Ширина;
//Если ШиринаКолонки <= 0 Тогда
// Если ЗначениеЗаполнено(Колонка.Данные) Тогда
// ШиринаКолонки = ЗначениеТабличногоПоля.Колонки[Колонка.Данные].Ширина;
// Если ШиринаКолонки = 0 Тогда
// ШиринаКолонки = 30;
// КонецЕсли;
// Иначе
// ШиринаКолонки = 30;
// КонецЕсли;
//КонецЕсли;
//ШиринаКолонки = Мин(ШиринаКолонки, 50);
//ШиринаКолонки = Макс(ШиринаКолонки, 10);
//ОбластьЗаголовка.ШиринаКолонки = ШиринаКолонки;
ОбластьЗаголовка.ЦветФона = ЦветаСтиля.ЦветФонаШапкиТаблицы;
ОбластьЗаголовка.ЦветТекста = ЦветаСтиля.ЦветТекстаШапкиТаблицы;
УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(ОбластьЗаголовка, ТабличноеПоле);
НомерКолонки = НомерКолонки + 1;
КонецЕсли;
КонецЦикла;
ВывестиСтрокиТабличногоПоляСОформлениемЛкс(КоллекцияСтрок, НомерСтроки, Результат, ТабличноеПоле,, ПараметрыВывода.ВстроитьЗначенияВРасшифровки);
УстановитьАвтоширинуКолонокТабличногоДокументаЛкс(Результат);
Если ТабличноеПоле.ТекущаяКолонка <> Неопределено Тогда
ИндексКолонки = ВыбранныеКолонки.Найти(ТабличноеПоле.ТекущаяКолонка.Имя);
Если ИндексКолонки <> Неопределено Тогда
Результат.ТекущаяОбласть = Результат.Область(2, ИндексКолонки + 1);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Результат <> Неопределено Тогда
Если ПараметрыВывода.ТолькоВыделенныеСтроки Или ИндексТекущейСтроки = Неопределено Тогда
ИндексТекущейСтроки = 0;
КонецЕсли;
Если ТипЗнч(Результат) = Тип("ТабличныйДокумент") Тогда
НомерСтроки = ИндексТекущейСтроки + 2;
Результат.ТекущаяОбласть = Результат.Область(НомерСтроки, Результат.ТекущаяОбласть.Лево);
ИначеЕсли Результат.Количество() > ИндексТекущейСтроки И ИндексТекущейСтроки >= 0 Тогда
выхТекущаяСтрока = Результат[ИндексТекущейСтроки];
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ДанныеСтрокДинамическогоСпискаЛкс(Знач ТабличноеПоле, Знач КлючиСтрок = Неопределено, Знач ВыбранныеКолонки = Неопределено, НастройкиСписка = Неопределено,
Знач КоличествоПервых = 100000) Экспорт
ПолноеИмяТаблицыБД = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле);
СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицыБД,,, Ложь);
ДинамическийСписок = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
ПсведонимТаблицы = "Таблица93423872";
СхемаКомпоновки = ирОбщий.ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицыБД,,,, ПсведонимТаблицы,, Истина, КоличествоПервых);
#Если Сервер И Не Сервер Тогда
СхемаКомпоновки = Новый СхемаКомпоновкиДанных;
#КонецЕсли
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
Если ДинамическийСписок = Неопределено Тогда
Если КлючиСтрок = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Иначе
Если НастройкиСписка = Неопределено Тогда
НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДинамическийСписок);
КонецЕсли;
ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, НастройкиСписка.Отбор);
Если Не ЛиКорневойТипПеречисленияЛкс(ПервыйФрагментЛкс(ПолноеИмяТаблицыБД)) Тогда
ирОбщий.СкопироватьПорядокЛюбойЛкс(НастройкаКомпоновки.Порядок, НастройкиСписка.Порядок);
КонецЕсли;
КонецЕсли;
Если КлючиСтрок <> Неопределено Тогда
ГруппаИли = НастройкаКомпоновки.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ГруппаИли.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;
ГруппаИли.Использование = Истина;
Для Каждого КлючСтроки Из КлючиСтрок Цикл
ГруппаИ = ГруппаИли.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ГруппаИ.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
ГруппаИ.Использование = Истина;
ЗначениеПоляКлюча = Неопределено;
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
Если ЛиТипСсылкиТочкиМаршрутаЛкс(ТипЗнч(КлючСтроки)) Тогда
ЗначениеПоляКлюча = КлючСтроки;
Иначе
ЗначениеПоляКлюча = КлючСтроки[КлючИЗначение.Ключ];
КонецЕсли;
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ГруппаИ, КлючИЗначение.Ключ, ЗначениеПоляКлюча);
КонецЦикла;
Если Истина
И СтруктураКлюча.Количество() = 1
И ТипЗнч(ЗначениеПоляКлюча) = Тип("УникальныйИдентификатор")
Тогда
// Антибаг платформы https://www.hostedredmine.com/issues/895239
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ГруппаИ);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, КлючИЗначение.Ключ);
СхемаКомпоновки.НаборыДанных[0].Поля.Найти(КлючИЗначение.Ключ).Роль.Обязательное = Истина;
КонецЦикла;
Если ВыбранныеКолонки <> Неопределено Тогда
Если ТипЗнч(ВыбранныеКолонки) = Тип("Строка") Тогда
ВыбранныеКолонки = СтрРазделитьЛкс(ВыбранныеКолонки, ",", Истина);
КонецЕсли;
Для Каждого ВыбраннаяКолонка Из ВыбранныеКолонки Цикл
Если Не ЗначениеЗаполнено(ВыбраннаяКолонка) Тогда
Продолжить;
КонецЕсли;
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ВыбраннаяКолонка);
КонецЦикла;
КонецЕсли;
ВыраженияВыбранныхПолей = Новый Массив;
Для Каждого ВыбранноеПоле Из НастройкаКомпоновки.Выбор.Элементы Цикл
Если ВыбранноеПоле.Использование Тогда
ВыраженияВыбранныхПолей.Добавить(ПсведонимТаблицы + "." + ВыбранноеПоле.Поле);
КонецЕсли;
КонецЦикла;
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки));
КомпоновщикНастроек.ЗагрузитьНастройки(НастройкаКомпоновки);
КомпоновщикНастроек.Восстановить();
НастройкаКомпоновки = КомпоновщикНастроек.Настройки;
КонецЕсли;
Если Истина
И ирОбщий.ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(ирОбщий.ПервыйФрагментЛкс(ПолноеИмяТаблицыБД))
И КлючиСтрок <> Неопределено
Тогда
// https://www.hostedredmine.com/issues/916752
Результат = КлючиСтрок;
Иначе
// https://www.hostedredmine.com/issues/897644
// Обеспечиваем наличие всех полей ключа. Некоторые могли быть отключены
Запрос = ПолучитьЗапросИзКомпоновкиЛкс(СхемаКомпоновки, НастройкаКомпоновки, Истина);
#Если Сервер И Не Сервер Тогда
Запрос = Новый Запрос;
#КонецЕсли
//МаркерИЗ = Символы.ПС + "ИЗ" + Символы.ПС;
//Разделитель = "," + Символы.ПС + Символы.Таб;
//Запрос.Текст = СтрЗаменитьЛкс(Запрос.Текст, МаркерИЗ, Разделитель + СтрСоединитьЛкс(ВыраженияВыбранныхПолей, Разделитель) + МаркерИЗ);
Результат = Запрос.Выполнить().Выгрузить();
КонецЕсли;
Возврат Результат;
КонецФункции
// Результат:
// Массив
Функция ВыделенныеСтрокиТабличногоПоляЛкс(Знач ТабличноеПоле, Знач НуженВидимыйПорядок = Истина) Экспорт
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
Если Не НуженВидимыйПорядок Тогда
Результат = Новый Массив;
Для Каждого ВыделеннаяСтрока Из ВыделенныеСтроки Цикл
Результат.Добавить(ВыделеннаяСтрока);
КонецЦикла;
Возврат Результат;
КонецЕсли;
// https://partners.v8.1c.ru/forum/t/1928636/m/1928636
// http://www.hostedredmine.com/issues/881648
МассивСтрок = Новый Массив;
ПолноеИмяТаблицыБД = "";
ДанныеТабличногоПоля = Неопределено;
ТипИсточника = ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле,,, ПолноеИмяТаблицыБД, ДанныеТабличногоПоля);
Если Истина
И ТипИсточника = "Список"
И ЗначениеЗаполнено(ПолноеИмяТаблицыБД)
И ДанныеТабличногоПоля <> Неопределено
Тогда
КоллекцияСтрок = ДанныеСтрокДинамическогоСпискаЛкс(ТабличноеПоле, ВыделенныеСтроки);
СтруктураКлюча = Неопределено;
ОбъектМД = Неопределено;
Для Каждого ДанныеСтроки Из КоллекцияСтрок Цикл
МассивСтрок.Добавить(ирОбщий.КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицыБД, ДанныеСтроки,,,, СтруктураКлюча, ОбъектМД));
КонецЦикла;
Иначе
Если Истина
И ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле")
И ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений")
Тогда
ВсеСтроки = ВсеСтрокиДереваЗначенийЛкс(ТабличноеПоле.Значение);
#Если Сервер И Не Сервер Тогда
ВсеСтроки = Новый Массив;
#КонецЕсли
Иначе
ВсеСтроки = ДанныеТабличногоПоля;
КонецЕсли;
Если ЭтоКоллекцияЛкс(ВсеСтроки) Тогда
Для Каждого ЭлементКоллекции Из ВсеСтроки Цикл
Если ТипЗнч(ЭлементКоллекции) = Тип("ДанныеФормыЭлементКоллекции") Тогда
ВыделеннаяСтрока = ЭлементКоллекции.ПолучитьИдентификатор();
СтрокаВыделена = ВыделенныеСтроки.Найти(ВыделеннаяСтрока) <> Неопределено;
Иначе
ВыделеннаяСтрока = ЭлементКоллекции;
СтрокаВыделена = ВыделенныеСтроки.Содержит(ВыделеннаяСтрока);
КонецЕсли;
Если СтрокаВыделена Тогда
МассивСтрок.Добавить(ВыделеннаяСтрока);
КонецЕсли;
КонецЦикла;
Иначе
// Грязно
ПредПозиция = Неопределено;
ПорядокНарушен = Ложь;
ТаблицаСтрок = Новый ТаблицаЗначений;
ТаблицаСтрок.Колонки.Добавить("Строка");
ТаблицаСтрок.Колонки.Добавить("Позиция");
Для Каждого ВыделеннаяСтрока Из ВыделенныеСтроки Цикл
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
ПозицияСтроки = ВыделеннаяСтрока;
Если Истина
И ТипЗнч(ПозицияСтроки) = Тип("Число") // Бывают и другие типы. Для них не будет корректировки порядка
И ПредПозиция <> Неопределено
И ПозицияСтроки < ПредПозиция И ТаблицаСтрок.Количество() > 2
Тогда
ПорядокНарушен = Истина;
КонецЕсли;
ПредПозиция = ПозицияСтроки;
ИначеЕсли Истина
И ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле")
И ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений")
Тогда
ПозицияСтроки = ВсеСтроки.Найти(ВыделеннаяСтрока);
Иначе
ПозицияСтроки = Неопределено;
КонецЕсли;
СтрокаТаблицы = ТаблицаСтрок.Добавить();
СтрокаТаблицы.Строка = ВыделеннаяСтрока;
СтрокаТаблицы.Позиция = ПозицияСтроки;
КонецЦикла;
Если Не ПорядокНарушен Или ТипЗнч(ТабличноеПоле) <> Тип("ТаблицаФормы") Тогда
ТаблицаСтрок.Сортировать("Позиция");
КонецЕсли;
МассивСтрок = ТаблицаСтрок.ВыгрузитьКолонку("Строка");
КонецЕсли;
КонецЕсли;
Возврат МассивСтрок;
КонецФункции
Функция ВыделенныеИлиВсеСтрокиТабличногоПоляЛкс(Знач ТабличноеПоле) Экспорт
Если ТабличноеПоле.ВыделенныеСтроки.Количество() > 1 Тогда
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
Иначе
ВыделенныеСтроки = ТабличноеПоле.Значение;
КонецЕсли;
Возврат ВыделенныеСтроки;
КонецФункции
Процедура ВывестиСтрокиТабличногоПоляСОформлениемЛкс(Знач КоллекцияСтрок, НомерСтроки = Неопределено, Знач Результат, Знач ТабличноеПоле, Смещение = "", ВстроитьЗначенияВРасшифровки = Истина)
Индикатор = ПолучитьИндикаторПроцессаЛкс(КоллекцияСтрок.Количество());
Для Каждого СтрокаИсточника Из КоллекцияСтрок Цикл
ОбработатьИндикаторЛкс(Индикатор);
ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(СтрокаИсточника);
Если ОформлениеСтроки = Неопределено Тогда
Прервать;
КонецЕсли;
Если ТипЗнч(Результат) = Тип("ТабличныйДокумент") Тогда
#Если Сервер И Не Сервер Тогда
Результат = Новый ТабличныйДокумент;
#КонецЕсли
НомерСтроки = НомерСтроки + 1;
ОбластьСтроки = Результат.Область(НомерСтроки, 0, НомерСтроки, 0);
//ЗаполнитьЗначенияСвойств(ОбластьСтроки, ОформлениеСтроки, "Шрифт, ЦветТекста, ЦветФона");
ИначеЕсли ТипЗнч(Результат) = Тип("ТаблицаЗначений") Тогда
#Если Сервер И Не Сервер Тогда
Результат = Новый ТаблицаЗначений;
#КонецЕсли
ОбластьСтроки = Результат.Добавить();
КонецЕсли;
НомерКолонки = 1;
Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл
Если Не Колонка.Видимость Или Колонка.Имя = ирКэш.ИмяКолонкиНомерСтрокиЛкс() Тогда
Продолжить;
КонецЕсли;
ОформлениеЯчейки = ОформлениеСтроки.Ячейки[Колонка.Имя];
Если ТипЗнч(Результат) = Тип("ТабличныйДокумент") Тогда
ОбластьЯчейки = Результат.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки);
ЗаполнитьЗначенияСвойств(ОбластьЯчейки, ОформлениеЯчейки, "Шрифт, ЦветТекста, ЦветФона");
Если ОформлениеЯчейки.ОтображатьТекст Тогда
ОбластьЯчейки.Текст = Смещение + ОформлениеЯчейки.Текст;
ИначеЕсли ОформлениеЯчейки.ОтображатьФлажок Тогда
ОбластьЯчейки.Текст = Смещение + ОформлениеЯчейки.ЗначениеФлажка;
КонецЕсли;
Если Истина
И ВстроитьЗначенияВРасшифровки
//И ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ОформлениеЯчейки.Значение, Ложь)
Тогда
ОбластьЯчейки.Расшифровка = ОформлениеЯчейки.Значение;
КонецЕсли;
УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(ОбластьЯчейки, ТабличноеПоле);
НомерКолонки = НомерКолонки + 1;
ИначеЕсли ТипЗнч(Результат) = Тип("ТаблицаЗначений") Тогда
ОбластьСтроки[Колонка.Имя] = ОформлениеЯчейки.Текст;
КонецЕсли;
КонецЦикла;
Если Истина
И ТипЗнч(Результат) = Тип("ТабличныйДокумент")
И ТипЗнч(СтрокаИсточника) = Тип("СтрокаДереваЗначений")
И ТабличноеПоле.Развернут(СтрокаИсточника)
Тогда
Результат.НачатьГруппуСтрок();
ВывестиСтрокиТабличногоПоляСОформлениемЛкс(СтрокаИсточника.Строки, НомерСтроки, Результат, ТабличноеПоле, Смещение + " ");
Результат.ЗакончитьГруппуСтрок();
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
КонецПроцедуры
Процедура ВывестиСтрокиТабличногоПоляИПоказатьЛкс(Знач ТабличноеПоле, Знач ВыводБезОформления = Неопределено, Знач НастройкиСписка = Неопределено) Экспорт
ТекущаяСтрока = Неопределено;
Результат = ВывестиСтрокиТабличногоПоляСНастройкойЛкс(ТабличноеПоле, ВыводБезОформления, НастройкиСписка, ТекущаяСтрока);
Если Результат <> Неопределено Тогда
ОткрытьЗначениеЛкс(Результат,,,, Ложь,, ТабличноеПоле);
КонецЕсли;
КонецПроцедуры
Процедура УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(Знач ОбластьЯчейки, Знач ЭлементУправления) Экспорт
ЛинияСплошная = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная);
Если ЭлементУправления.ГоризонтальныеЛинии Тогда
ОбластьЯчейки.ГраницаСверху = ЛинияСплошная;
ОбластьЯчейки.ГраницаСнизу = ЛинияСплошная;
КонецЕсли;
Если ЭлементУправления.ВертикальныеЛинии Тогда
ОбластьЯчейки.ГраницаСлева = ЛинияСплошная;
ОбластьЯчейки.ГраницаСправа = ЛинияСплошная;
КонецЕсли;
КонецПроцедуры // ЛксСравнитьСодержимоеПоля()
Процедура РасширитьКолонкиТабличногоПоляЛкс(ТабличноеПоле, УважатьЗапретИзмененияРазмера = Истина) Экспорт
//ВведенноеЗначениеШирины = 10;
//Если ВвестиЧисло(ВведенноеЗначениеШирины, "Введите новую ширину колонки для всех колонок", 5, 0) Тогда
// УстановитьСвойствоВКоллекцииЛкс(ТабличноеПоле.Колонки, , "-Ширина", ВведенноеЗначениеШирины);
//КонецЕсли;
Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл
Ширина = Колонка.Ширина;
Если Ширина = 0 Тогда
// Антибаг платформы.
Ширина = 10;
КонецЕсли;
Если Ложь
Или Не УважатьЗапретИзмененияРазмера
Или Колонка.ИзменениеРазмера = ИзменениеРазмераКолонки.Изменять
Тогда
НоваяШирина = Ширина + 3;
Колонка.Ширина = НоваяШирина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // РасширитьКолонкиТабличногоПоляЛкс()
// Пропорционально сжимает ширины колонок табличного поля.
//
// Параметры:
// ТабличноеПоле – ТабличноеПоле;
// Сжатие – Число, *2 – коэффициент сжатия;
// УважатьЗапретИзмененияРазмера – Булево, *Истина – не сжимать колонки с запретом изменения размера;
//
Процедура СжатьКолонкиТабличногоПоляЛкс(ТабличноеПоле, Сжатие = 2, УважатьЗапретИзмененияРазмера = Истина) Экспорт
Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл
Ширина = Колонка.Ширина;
Если Ширина = 0 Тогда
// Антибаг платформы.
Ширина = 10;
КонецЕсли;
Если Ложь
Или Не УважатьЗапретИзмененияРазмера
Или Колонка.ИзменениеРазмера = ИзменениеРазмераКолонки.Изменять
Тогда
НоваяШирина = Ширина / Сжатие;
НоваяШирина = Макс(НоваяШирина, 1);
Колонка.Ширина = НоваяШирина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // СжатьКолонкиТабличногоПоляЛкс()
// Интерактивно записывает значение в элемент управления. Интерактивность заключается в срабатывании
// события ПриИзменении у элемента управления.
//
// Параметры:
// ЭлементУправления – ЭлементУправления – которому присваиваем значение;
// Значение – Произвольный – присваиваемое значение;
// *ФормаИнициатор - Форма, УправляемаяФорма, *Неопределено - которая будет использована в качестве инициатора события;
// если не указана, то будет создана временная форма-пустышка.
//
// Результат - Булево - успешно ли значение установлено
Функция ИнтерактивноЗаписатьВЭлементУправленияЛкс(ЭлементУправления, Знач Значение = Неопределено, Знач ФормаИнициатор = Неопределено) Экспорт
Если ФормаИнициатор = Неопределено Тогда
ФормаИнициатор = ирКэш.ФормаПустышкаЛкс();
Иначе
СтарыйВладелец = ФормаИнициатор.ВладелецФормы;
СтарыйЗакрыватьПриВыборе = ФормаИнициатор.ЗакрыватьПриВыборе;
ФормаИнициатор.ЗакрыватьПриВыборе = Ложь;
КонецЕсли;
ФормаИнициатор.ВладелецФормы = ЭлементУправления;
НовоеЗначение = ЭлементУправления.ОграничениеТипа.ПривестиЗначение(Значение);
Если Ложь
Или НовоеЗначение <> Значение
Или ЭлементУправления.ТолькоПросмотр
Тогда
Возврат Ложь;
КонецЕсли;
ФормаИнициатор.ОповеститьОВыборе(Значение);
Если СтарыйЗакрыватьПриВыборе <> Неопределено Тогда
ФормаИнициатор.ВладелецФормы = СтарыйВладелец;
ФормаИнициатор.ЗакрыватьПриВыборе = СтарыйЗакрыватьПриВыборе;
КонецЕсли;
ЗначениеПоля = ДанныеЭлементаФормыЛкс(ЭлементУправления);
//Попытка
Результат = ЗначениеПоля = Значение;
//Исключение
// // Это поле управляемой формы
// Результат = Истина;
//КонецПопытки;
Возврат Результат;
КонецФункции
// Интерактивно записывает значение в элемент управления (только поле ввода/формы) колонки табличного поля или таблицы формы.
// Интерактивность заключается в срабатывании события ПриИзменении у элемента управления.
// Строка табличного поля или таблицы формы должна находиться в режиме редактирования,
// иначе никаких изменений данных не произойдет.
//
// Параметры:
// ТабличноеПоле - ТабличноеПоле, ТаблицаФормы - внутри него строка редактируется;
// Колонка – КолонкаТабличногоПоля, ПолеФормы – в ее ячейку будем помещать значение;
// Значение – Произвольный – присваиваемое значение;
// *ФормаИнициатор - Форма, УправляемаяФормы, *Неопределено - которая будет использована в качестве инициатора события;
// если не указана, то будет создана временная форма-пустышка;
// *ВосстанавитьТекущуюКолонку – Булево, *Истина;
// *ВключитьРежимРедактирования – Булево, *Истина.
//
Процедура ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Знач Колонка, Знач Значение, Знач ФормаИнициатор = Неопределено,
Знач ВосстанавитьТекущуюКолонку = Истина, Знач ВключитьРежимРедактирования = Истина, Знач КонтролироватьТекущиеДанные = Истина, Знач ВыключитьРежимРедактирования = Ложь) Экспорт
Если ТипЗнч(Колонка) = Тип("КолонкаТабличногоПоля") Тогда
Если Ложь
Или Не Колонка.Доступность
Или Колонка.ТолькоПросмотр
Тогда
Возврат;
КонецЕсли;
ЭлементУправления = Колонка.ЭлементУправления;
Если ТипЗнч(ЭлементУправления) <> Тип("ПолеВвода") Тогда
ЭлементУправления = Неопределено;
КонецЕсли;
Иначе
ЭлементУправления = Колонка;
Если ТипЗнч(ЭлементУправления) <> Тип("ПолеФормы") Тогда
ЭлементУправления = Неопределено;
КонецЕсли;
КонецЕсли;
Если ЭлементУправления <> Неопределено Тогда
Если ТипЗнч(ЭлементУправления) = Тип("ПолеВвода") Тогда
ДанныеПоля = ДанныеЭлементаФормыЛкс(ЭлементУправления);
ХмлТип = XMLТипЗнч(ДанныеПоля);
Если Истина
И ХмлТип <> Неопределено
И Найти(ХмлТип.ИмяТипа, "CatalogRef.") > 0
Тогда
Если Ложь
Или (Истина
И ЗначениеЗаполнено(ЭлементУправления.ВыборПоВладельцу)
И Значение.Владелец <> ЭлементУправления.ВыборПоВладельцу)
Или (Истина
И ЭлементУправления.ВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Элементы
И Значение.ЭтоГруппа)
Или (Истина
И ЭлементУправления.ВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Группы
И Не Значение.ЭтоГруппа)
Тогда
Возврат;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ВосстанавитьТекущуюКолонку Тогда
СтараяТекущаяКолонка = ТекущаяКолонкаТаблицыФормыЛкс(ТабличноеПоле);
КонецЕсли;
ТабличноеПоле_УстановитьТекущуюКолонкуЛкс(ТабличноеПоле, Колонка);
Если ВключитьРежимРедактирования Тогда
ТабличноеПоле.ИзменитьСтроку();
КонецЕсли;
ИнтерактивноЗаписатьВЭлементУправленияЛкс(ЭлементУправления, Значение, ФормаИнициатор);
Если ВосстанавитьТекущуюКолонку Тогда
ТабличноеПоле_УстановитьТекущуюКолонкуЛкс(ТабличноеПоле, СтараяТекущаяКолонка);
КонецЕсли;
Если ВыключитьРежимРедактирования Тогда
ТабличноеПоле.ЗакончитьРедактированиеСтроки(Ложь);
КонецЕсли;
КонецЕсли;
Если КонтролироватьТекущиеДанные Тогда // На 8.3.8 значение в свойство строки почему то не попадает
ПутьКДаннымКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле, Колонка);
Если ПутьКДаннымКолонки <> "" Тогда
ДанныеСтроки = ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле);
Попытка
ЗначениеЯчейки = ДанныеСтроки[ПутьКДаннымКолонки];
ИмяДанныхПравильное = Истина;
Исключение
// В табличных полях компоновки
ИмяДанныхПравильное = Ложь;
КонецПопытки;
Если ИмяДанныхПравильное Тогда
Если Значение <> ЗначениеЯчейки Тогда
// Такое случается в некоторых состояниях формы (пока Открыта() = Ложь)
// Также это срабатывает для неподдерживаемых типов в поле ввода
ДанныеСтроки[ПутьКДаннымКолонки] = Значение;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ТабличноеПоле_УстановитьТекущуюКолонкуЛкс(Знач ТабличноеПоле, НоваяТекущаяКолонка)
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
ПрисвоитьЕслиНеРавноЛкс(ТабличноеПоле.ТекущаяКолонка, НоваяТекущаяКолонка);
Иначе
ПрисвоитьЕслиНеРавноЛкс(ТабличноеПоле.ТекущийЭлемент, НоваяТекущаяКолонка);
КонецЕсли;
КонецПроцедуры
Функция КомпонуемаяТаблицаЗначенийТабличногоПоляЛкс(Знач Форма, Знач ТабличноеПоле) Экспорт
КомпонуемаяТаблицаЗначений = Неопределено;
МаркерОтобранное = "Отобранное";
Если ирОбщий.СтрКончаетсяНаЛкс(ТабличноеПоле.Данные, МаркерОтобранное) Тогда
ИмяРеквизитаКоллекция = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ТабличноеПоле.Данные, МаркерОтобранное);
ИмяРеквизитаКомпоновщик = ИмяРеквизитаКоллекция + "Компоновщик";
ИмяРеквизитаИспользоватьОтбор = ИмяРеквизитаКоллекция + "ИспользоватьОтбор";
ПолнаяКоллекция = Форма[ИмяРеквизитаКоллекция];
ИспользоватьОтбор = Форма[ИмяРеквизитаИспользоватьОтбор];
Компоновщик = Форма[ИмяРеквизитаКомпоновщик];
КомпонуемаяТаблицаЗначений = Новый Структура();
КомпонуемаяТаблицаЗначений.Вставить("ПолнаяКоллекция", ПолнаяКоллекция);
КомпонуемаяТаблицаЗначений.Вставить("ИспользоватьОтбор", ИспользоватьОтбор);
КомпонуемаяТаблицаЗначений.Вставить("Компоновщик", Компоновщик);
КонецЕсли;
Возврат КомпонуемаяТаблицаЗначений;
КонецФункции
Функция ТабличноеПолеСдвинутьВыделенныеСтрокиЛкс(Знач ТабличноеПоле, Знач Направление) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
Если ТабличноеПоле.ТолькоПросмотр Тогда
Возврат Ложь;
КонецЕсли;
ПорядокИзменен = Ложь;
ВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТабличноеПоле);
#Если Сервер И Не Сервер Тогда
ВыделенныеСтроки = Новый Массив;
#КонецЕсли
Для Индекс = 0 По ВыделенныеСтроки.ВГраница() Цикл
Если Направление = -1 Тогда
ВыделеннаяСтрока = ВыделенныеСтроки[Индекс];
Иначе
ВыделеннаяСтрока = ВыделенныеСтроки[ВыделенныеСтроки.ВГраница() - Индекс];
КонецЕсли;
Позиция = ТабличноеПоле.Значение.Индекс(ВыделеннаяСтрока);
Если Ложь
Или (Истина
И Направление = -1
И Позиция > 0 + Индекс)
Или (Истина
И Направление = 1
И Позиция > -1
И Позиция < ТабличноеПоле.Значение.Количество() - 1 - Индекс)
Тогда
ТабличноеПоле.Значение.Сдвинуть(ВыделеннаяСтрока, Направление);
ПорядокИзменен = Истина;
КонецЕсли;
КонецЦикла;
Возврат ПорядокИзменен;
КонецФункции
Процедура ТабличноеПолеОбновитьТекстыПодваловЛкс(Знач ТабличноеПолеРезультата) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПолеРезультата = Новый ТабличноеПоле;
#КонецЕсли
Если Не ТабличноеПолеРезультата.Подвал Тогда
Возврат;
КонецЕсли;
Если ЗначениеЗаполнено(ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПолеРезультата)) Тогда
Возврат;
КонецЕсли;
КоличествоВыделенных = ТабличноеПолеРезультата.ВыделенныеСтроки.Количество();
Если КоличествоВыделенных > 1 Тогда
ВыделенныеСтроки = ирОбщий.ВыделенныеСтрокиТабличногоПоляЛкс(ТабличноеПолеРезультата, Ложь);
Иначе
ВыделенныеСтроки = Неопределено;
КонецЕсли;
КопияТаблицы = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПолеРезультата, ВыделенныеСтроки);
#Если Сервер И Не Сервер Тогда
КопияТаблицы = Новый ТаблицаЗначений;
#КонецЕсли
КоличествоУжеВыведено = Ложь;
КоллекцияСтрок = ТабличноеПолеРезультата.Значение;
Если ТипЗнч(КоллекцияСтрок) = Тип("ДеревоЗначений") Тогда
КоллекцияСтрок = КоллекцияСтрок.Строки;
КонецЕсли;
Для Каждого Колонка Из ТабличноеПолеРезультата.Колонки Цикл
Если Не Колонка.Видимость Тогда
Продолжить;
КонецЕсли;
ДанныеКолонки = Колонка.Данные;
СуммаКолонки = Неопределено;
Если Истина
И ЗначениеЗаполнено(ДанныеКолонки)
И КоллекцияСтрок.Количество() > 0
И КопияТаблицы.Колонки.Найти(ДанныеКолонки).ТипЗначения.СодержитТип(Тип("Число"))
Тогда
СуммаКолонки = КопияТаблицы.Итог(ДанныеКолонки);
КонецЕсли;
Если СуммаКолонки = Неопределено Тогда
ТекстПодвала = "";
Если Истина
И Не КоличествоУжеВыведено
И (Ложь
Или Колонка.Ширина > 5
Или Колонка.ИзменениеРазмера = ИзменениеРазмераКолонки.Изменять)
Тогда
ТекстПодвала = "N" + КопияТаблицы.Количество();
КоличествоУжеВыведено = Истина;
КонецЕсли;
Колонка.ТекстПодвала = ТекстПодвала;
Продолжить;
КонецЕсли;
Если КоличествоВыделенных > 1 Тогда
ТекстПодвала = "!Σ";
Иначе
ТекстПодвала = "Σ";
КонецЕсли;
ТекстПодвала = ТекстПодвала + СуммаКолонки;
Колонка.ТекстПодвала = ТекстПодвала;
Колонка.ГоризонтальноеПоложениеВПодвале = ГоризонтальноеПоложение.Право;
КонецЦикла;
КонецПроцедуры
Процедура ТабличноеПолеКнопкаОтображенияИтоговНажатиеЛкс(Знач ТабличноеПолеРезультата, Знач Кнопка) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПолеРезультата = Новый ТабличноеПоле;
#КонецЕсли
Кнопка.Пометка = Не Кнопка.Пометка;
ТабличноеПолеРезультата.Подвал = Кнопка.Пометка;
ТабличноеПолеОбновитьТекстыПодваловЛкс(ТабличноеПолеРезультата);
КонецПроцедуры
// Проверяет колонку табличного поля на интерактивную доступность для редактирования.
//
// Параметры:
// пКолонка – КолонкаТабличногоПоля.
//
// Возвращаемое значение:
// Истина - колонка интерактивно доступна;
// Ложь - иначе.
//
Функция ЛиИнтерактивноДоступнаяКолонкаЛкс(КолонкаТабличногоПоля) Экспорт
Если Истина
И КолонкаТабличногоПоля <> Неопределено
И КолонкаТабличногоПоля.Доступность
И КолонкаТабличногоПоля.Видимость
И Не КолонкаТабличногоПоля.ТолькоПросмотр
И (Ложь
Или ТипЗнч(КолонкаТабличногоПоля) = Тип("ПолеФормы")
Или КолонкаТабличногоПоля.ДанныеФлажка <> ""
Или (Истина
И КолонкаТабличногоПоля.ЭлементУправления <> Неопределено
И КолонкаТабличногоПоля.ЭлементУправления.Доступность))
Тогда
Попытка
Если КолонкаТабличногоПоля.ЭлементУправления.ТолькоПросмотр Тогда
Возврат Ложь;
КонецЕсли;
Исключение
КонецПопытки;
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиИнтерактивноДоступнаяКолонкаЛкс()
// Копирует привязки между элементами форм.
//
// Параметры:
// пФорма – Форма – в которую копируем;
// ЭлементПриемник – ЭлементУправления;
// ЭлементИсточник – ЭлементУправления.
//
Процедура СкопироватьПривязкиЛкс(пФорма, ЭлементПриемник, ЭлементИсточник) Экспорт
Перем ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент, ГраницаВторогоЭлемента;
Границы = Новый Массив;
Границы.Добавить(ГраницаЭлементаУправления.Верх);
Границы.Добавить(ГраницаЭлементаУправления.Низ);
Границы.Добавить(ГраницаЭлементаУправления.Лево);
Границы.Добавить(ГраницаЭлементаУправления.Право);
Для Каждого Граница Из Границы Цикл
ЭлементИсточник.ПолучитьПривязку( Граница, ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент,
ГраницаВторогоЭлемента);
Если ПервыйЭлемент <> Неопределено Тогда
ПервыйЭлемент = пФорма.ЭлементыФормы.Найти(ПервыйЭлемент.Имя);
Если ПервыйЭлемент = Неопределено Тогда
ПервыйЭлемент = пФорма.Панель;
КонецЕсли;
КонецЕсли;
Если ВторойЭлемент <> Неопределено Тогда
ВторойЭлемент = пФорма.ЭлементыФормы.Найти(ВторойЭлемент.Имя);
Если ВторойЭлемент = Неопределено Тогда
ВторойЭлемент = пФорма.Панель;
КонецЕсли;
КонецЕсли;
ЭлементПриемник.УстановитьПривязку(Граница, ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент,
ГраницаВторогоЭлемента);
КонецЦикла;
КонецПроцедуры // СкопироватьПривязкиЛкс()
// Заполняет форму по ее макету. Используется для динамического добавления элементов
// в типовые формы, чтобы облегчить их обновление. Макет формы, если явно не указан,
// ищется среди форм объекта метаданных формы по имени "Лкс"+<ИмяФормы>+"Макет".
// Для измененных элементов в макете к имени следует добавлять через "_" суффиксы
// в соответствии с изменениями: "Привязка", "Размер", "Позиция", "Внутри" (для коллекций).
// Следует вызывать в обработчике ПередОткрытием формы.
// Ограничения.
// 1. Без явного указания макета работает только для основной формы объекта.
// 2. Нельзя добавлять элементы в панели и поля табличного документа, т.к. у элемента нельзя
// определить родителя.
// 3. Нельзя, чтобы форма и макет имели разные размеры. Обрабатывается.
// 4. Нельзя добавлять и изменять элементы, привязанные косвенно к низу формы.
// 5. Иногда элементы, привязанные косвенно к правой границе формы неверно располагаются.
// 6. Нельзя, чтобы оригинальные имена измененных элементов включали "_". Обрабатывается.
//
// Параметры:
// пФорма – Форма – которую настраиваем;
// *пМакет – Форма - макет, по которому настраиваем.
//
Процедура НастроитьФормуПоМакетуЛкс(пФорма, пМакетФормы) Экспорт
МакетФормы = пМакетФормы;
СоответствиеПривязки = Новый Соответствие;
Если Ложь
Или пФорма.Высота <> МакетФормы.Высота
Или пФорма.Ширина <> МакетФормы.Ширина
Тогда
СообщитьЛкс("Не соответствие размеров формы при заполнении по макету",
СтатусСообщения.Важное);
КонецЕсли;
//ЗаполнитьЗначенияСвойств(пФорма, МакетФормы, , "ДокументОбъект, Данные, ЭтотОбъект, Панель, ЭлементыФормы");
//ЗаполнитьЗначенияСвойств(пФорма.Панель, МакетФормы.Панель, , "Данные");
ЭлементыФормы = пФорма.ЭлементыФормы;
Для Каждого ЭлементМакета Из МакетФормы.ЭлементыФормы Цикл
ИмяЭлемента = ЭлементМакета.Имя;
ЭлементФормы = ЭлементыФормы.Добавить(ТипЗнч(ЭлементМакета), ИмяЭлемента, Ложь, пФорма.Панель);
Если ТипЗнч(ЭлементМакета) = Тип("КоманднаяПанель") Тогда
ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные, Кнопки, ИсточникДействий");
Если ЭлементМакета.ИсточникДействий = пМакетФормы Тогда
ЭлементФормы.ИсточникДействий = пФорма;
КонецЕсли;
ИначеЕсли ТипЗнч(ЭлементМакета) = Тип("ТабличноеПоле") Тогда
ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные, ТекущаяСтрока");
Иначе
ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные");
КонецЕсли;
СоответствиеПривязки.Вставить(ЭлементФормы, ЭлементМакета);
КонецЦикла;
// Установи новые привязки
Для Каждого Привязка Из СоответствиеПривязки Цикл
ЭлементФормы = Привязка.Ключ;
ЭлементМакета = Привязка.Значение;
СкопироватьПривязкиЛкс(пФорма, ЭлементФормы, ЭлементМакета);
КонецЦикла;
КонецПроцедуры // НастроитьФормуПоМакетуЛкс()
Процедура ДеревоКонсолиПроверкаПеретаскиванияЛкс(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка, ИмяТипаСроки) Экспорт
Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Структура") Тогда
ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение;
Если ЗначениеПеретаскивания.Свойство("Тип") Тогда
Если НРег(ЗначениеПеретаскивания.Тип) = Нрег(ИмяТипаСроки) Тогда
ТекущийРодитель = Строка;
Пока ТекущийРодитель <> Неопределено Цикл
Если ТекущийРодитель = ЗначениеПеретаскивания.Значение Тогда
ПараметрыПеретаскивания.ДопустимыеДействия = ДопустимыеДействияПеретаскивания.НеОбрабатывать;
Возврат;
КонецЕсли;
ТекущийРодитель = ТекущийРодитель.Родитель;
КонецЦикла;
СтандартнаяОбработка = Ложь;
ПараметрыПеретаскивания.ДопустимыеДействия = ДопустимыеДействияПеретаскивания.Копирование;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ДеревоКонсолиПеретаскиваниеЛкс(ЭтаФорма, Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, СтрокаПриемник, Колонка, ИмяТипаСроки, ИмяПоляНаименования = "Наименование") Экспорт
Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Структура") Тогда
ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение;
Если ЗначениеПеретаскивания.Свойство("Тип") Тогда
Если НРег(ЗначениеПеретаскивания.Тип) = Нрег(ИмяТипаСроки) Тогда
СтандартнаяОбработка = Ложь;
Если СтрокаПриемник <> Неопределено Тогда
РодительскаяСтрока = СтрокаПриемник;
Иначе
РодительскаяСтрока = Элемент.Значение;
КонецЕсли;
НоваяСтрокаДерева = РодительскаяСтрока.Строки.Добавить();
СкопироватьСтрокиДереваЛкс(ЗначениеПеретаскивания.Значение, НоваяСтрокаДерева);
Если Истина
И ЗначениеПеретаскивания.Значение.Родитель = НоваяСтрокаДерева.Родитель
И ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Перемещение
Тогда
//
Иначе
ДеревоКонсолиПриОкончанииРедактированияЛкс(НоваяСтрокаДерева, ИмяПоляНаименования);
КонецЕсли;
Элемент.ТекущаяСтрока = НоваяСтрокаДерева;
Если ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Перемещение Тогда
РодительСтроки = ЗначениеПеретаскивания.Значение.Родитель;
Если РодительСтроки = Неопределено Тогда
РодительСтроки = Элемент.Значение;
Если ЗначениеПеретаскивания.Значение.Владелец() <> РодительСтроки Тогда
// Строка другой формы. Не будем ее удалять
РодительСтроки = Неопределено;
КонецЕсли;
КонецЕсли;
Если РодительСтроки <> Неопределено Тогда
РодительСтроки.Строки.Удалить(ЗначениеПеретаскивания.Значение);
КонецЕсли;
КонецЕсли;
Если Элемент.ИзменяетДанные Тогда
ЭтаФорма.Модифицированность = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ДеревоКонсолиПриОкончанииРедактированияЛкс(Знач СтрокаДерева, Знач ИмяПоляНаименования = "Наименование") Экспорт
РодительСтроки = ПолучитьРодителяСтрокиДереваЛкс(СтрокаДерева);
СтрокаДерева[ИмяПоляНаименования] = АвтоУникальноеИмяВКоллекцииЛкс(РодительСтроки.Строки, СтрокаДерева, ИмяПоляНаименования, Ложь);
КонецПроцедуры
Процедура ДеревоКонсолиНачалоПеретаскиванияЛкс(Элемент, ПараметрыПеретаскивания, Выполнение, ИмяТипаСроки) Экспорт
Элемент.ТекущаяСтрока = Элемент.ТекущаяСтрока; // Для сохранения изменений в строке
ЗначениеПеретаскивания = Новый Структура("Тип, Значение", ИмяТипаСроки, Элемент.ТекущаяСтрока);
ПараметрыПеретаскивания.Значение = ЗначениеПеретаскивания;
КонецПроцедуры
Процедура ТабличноеПолеСпискаНастроекКомпоновкиПроверкаПеретаскиванияЛкс(Знач ЭтаФорма, Знач Элемент, Знач ПараметрыПеретаскивания, СтандартнаяОбработка, Знач Строка) Экспорт
Если Не СтандартнаяОбработка Тогда
Возврат;
КонецЕсли;
ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение;
Если Строка <> Неопределено И ТипЗнч(ЗначениеПеретаскивания) = Тип("Массив") Тогда
ЗначениеПеретаскивания = ЗначениеПеретаскивания[0];
//Если Ложь
// Или ТипЗнч(ЗначениеПеретаскивания) = Тип("ЭлементОтбораКомпоновкиДанных")
// Или ТипЗнч(ЗначениеПеретаскивания) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
// Или ТипЗнч(ЗначениеПеретаскивания) = Тип("ОтборКомпоновкиДанных")
// Или ТипЗнч(ЗначениеПеретаскивания) = Тип("ВыбранноеПолеКомпоновкиДанных")
// Или ТипЗнч(ЗначениеПеретаскивания) = Тип("ГруппаВыбранныхПолейКомпоновкиДанных")
// Или ТипЗнч(ЗначениеПеретаскивания) = Тип("ЭлементПорядкаКомпоновкиДанных")
// Или ТипЗнч(ЗначениеПеретаскивания) = Тип("ЗначениеПараметраНастроекКомпоновкиДанных")
// Или ТипЗнч(ЗначениеПеретаскивания) = Тип("ЭлементУсловногоОформления")
// Или ТипЗнч(ЗначениеПеретаскивания) = Тип("ПользовательскоеПолеВыборКомпоновкиДанных")
// Или ТипЗнч(ЗначениеПеретаскивания) = Тип("ПользовательскоеПолеВыражениеКомпоновкиДанных")
// Или ТипЗнч(ЗначениеПеретаскивания) = Тип("ГруппировкаТаблицыКомпоновкиДанных")
// Или ТипЗнч(ЗначениеПеретаскивания) = Тип("ГруппировкаКомпоновкиДанных")
// Или ТипЗнч(ЗначениеПеретаскивания) = Тип("ГруппировкаДиаграммыКомпоновкиДанных")
// Или ТипЗнч(ЗначениеПеретаскивания) = Тип("ТаблицаКомпоновкиДанных")
//Тогда
Элемент.ТекущаяСтрока = Строка;
СтандартнаяОбработка = Ложь;
ПараметрыПеретаскивания.ДопустимыеДействия = ДопустимыеДействияПеретаскивания.НеОбрабатывать;
//КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Для корректной активации при проверке перетаскивания
Процедура ОбновитьТабличноеПолеДереваПослеУстановкиДанныхЛкс(ЭтаФорма, Знач ТабличноеПолеДерева) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПолеДерева = Новый ТабличноеПоле;
#КонецЕсли
Если ТипЗнч(ТабличноеПолеДерева.Значение) = Тип("ДеревоЗначений") Тогда
Если Истина
И ТабличноеПолеДерева.ТекущаяСтрока = Неопределено
И ТабличноеПолеДерева.Значение.Строки.Количество() > 0
Тогда
ТабличноеПолеДерева.ТекущаяСтрока = ТабличноеПолеДерева.Значение.Строки[0];
КонецЕсли;
Если ТабличноеПолеДерева.НачальноеОтображениеДерева = НачальноеОтображениеДерева.РаскрыватьВсеУровни Тогда
ТабличноеПолеДеревоЗначений_РазвернутьВсеСтрокиЛкс(ТабличноеПолеДерева);
КонецЕсли;
Иначе
Если ТабличноеПолеДерева.ТекущаяСтрока = Неопределено Тогда
Попытка
ТабличноеПолеДерева.ТекущаяСтрока = ТабличноеПолеДерева.Значение;
Исключение
КонецПопытки;
КонецЕсли;
Если ТабличноеПолеДерева.НачальноеОтображениеДерева = НачальноеОтображениеДерева.РаскрыватьВсеУровни Тогда
Попытка
ТабличноеПолеДерева.Развернуть(ТабличноеПолеДерева.Значение, Истина);
Исключение
// Например это ЗначенияПараметровДанныхКомпоновкиДанных
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура СкопироватьСтрокиДереваЛкс(СтрокаИсточник, СтрокаПриемник, СтопСтрока = Неопределено, Рекурсивно = Истина) Экспорт
Если СтопСтрока = Неопределено Тогда
Если СтрокаПриемник.Родитель <> Неопределено Тогда
СтопСтрока = СтрокаПриемник.Родитель;
КонецЕсли;
КонецЕсли;
Дерево = СтрокаПриемник.Владелец();
Для Каждого Колонка Из Дерево.Колонки Цикл
СтрокаПриемник[Колонка.Имя] = КопияОбъектаЛкс(СтрокаИсточник[Колонка.Имя]);
КонецЦикла;
Если Рекурсивно Тогда
Для Каждого Строка Из СтрокаИсточник.Строки Цикл
Если Строка = СтопСтрока Тогда
Продолжить;
КонецЕсли;
НоваяСтрока = СтрокаПриемник.Строки.Добавить();
СкопироватьСтрокиДереваЛкс(Строка, НоваяСтрока, СтопСтрока, Рекурсивно);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ИзменитьСвернутостьЛкс(ЭтаФорма, Видимость, ГлавныйЭлемент, Разделитель, Панель, Направление, ПодчиненныйЭлемент = Неопределено,
ПропорциональныйРазмер = Истина) Экспорт
Если Не ЭтаФорма.Открыта() Тогда
// Антибаг платформы. Иначе после закрытия и затем открытия привязки могут сломаться
//ирОбщий.СообщитьЛкс("Изменение свернутости панели вызвано для закрытой формы """ + ЭтаФорма.Заголовок + """");
Возврат;
КонецЕсли;
Если Разделитель = Неопределено Тогда
Разделитель = ГлавныйЭлемент;
КонецЕсли;
Если ТипЗнч(Разделитель) = Тип("Разделитель") Тогда
Если Разделитель.Ориентация = Ориентация.Авто Тогда
// возможно это касается только свертки вправо
СообщитьЛкс("Корректная работа свертки с разделителем """ + Разделитель.Имя + """ с ориентацией Авто невозможна из-за ошибки платформы",
СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
//ПервыйЭлемент = 0;
//ГраницаПервогоЭлемента = 0;
//ВторойЭлемент = 0;
//ГраницаВторогоЭлемента = 0;
Если СтрокиРавныЛкс(Направление, "лево") Тогда
Если Видимость Тогда
// откроем
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право);
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет;
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет;
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право);
Если ПропорциональныйРазмер Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Лево, Панель,
ГраницаЭлементаУправления.Право);
Иначе
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Право);
КонецЕсли;
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, Разделитель, ГраницаЭлементаУправления.Лево);
КонецЕсли;
//Разделитель.Ширина = ШиринаРазделителя;
Иначе
// скроем
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ГлавныйЭлемент, ГраницаЭлементаУправления.Право);
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Лево;
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Лево;
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ГлавныйЭлемент, ГраницаЭлементаУправления.Право);
КонецЕсли;
КонецЕсли;
ИначеЕсли СтрокиРавныЛкс(Направление, "право") Тогда
Если Видимость Тогда
// откроем
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, Разделитель, ГраницаЭлементаУправления.Лево);
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет;
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет;
Если ПропорциональныйРазмер Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Лево, Панель,
ГраницаЭлементаУправления.Право);
Иначе
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Право);
КонецЕсли;
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право);
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право);
//Разделитель.Ширина = ШиринаРазделителя;
КонецЕсли;
Иначе
// Скроем
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, ГлавныйЭлемент, ГраницаЭлементаУправления.Лево);
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Право;
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Право;
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, ГлавныйЭлемент, ГраницаЭлементаУправления.Лево);
КонецЕсли;
КонецЕсли;
ИначеЕсли СтрокиРавныЛкс(Направление, "низ") Тогда
Если Видимость Тогда
// Откроем
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ);
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет;
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет;
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ);
Если ПропорциональныйРазмер Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Верх, Панель,
ГраницаЭлементаУправления.Низ);
Иначе
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Низ);
КонецЕсли;
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ);
КонецЕсли;
//Разделитель.Высота = ШиринаРазделителя;
Иначе // Скроем
Если Разделитель <> ГлавныйЭлемент Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх);
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ГлавныйЭлемент, ГраницаЭлементаУправления.Верх);
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Низ;
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Низ;
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ГлавныйЭлемент, ГраницаЭлементаУправления.Верх);
КонецЕсли;
КонецЕсли;
ИначеЕсли СтрокиРавныЛкс(Направление, "верх") Тогда
Если Видимость Тогда
// Откроем
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Разделитель, ГраницаЭлементаУправления.Верх);
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет;
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет;
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ);
Если ПропорциональныйРазмер Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Верх, Панель,
ГраницаЭлементаУправления.Низ);
Иначе
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Низ);
КонецЕсли;
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Разделитель, ГраницаЭлементаУправления.Верх);
//Разделитель.Высота = ШиринаРазделителя;
КонецЕсли;
Иначе // Скроем
Если Разделитель <> ГлавныйЭлемент Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ);
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ГлавныйЭлемент, ГраницаЭлементаУправления.Низ);
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Верх;
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Верх;
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ГлавныйЭлемент, ГраницаЭлементаУправления.Низ);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура УстановитьТекстСОткатомЛкс(ПолеТекста, Текст) Экспорт
СтарыйТекст = ПолеТекста.ПолучитьТекст();
ПолеТекста.УстановитьГраницыВыделения(1, СтрДлина(СтарыйТекст) + 1);
ПолеТекста.ВыделенныйТекст = Текст;
КонецПроцедуры // УстановитьТекстСОткатомЛкс()
// <Описание процедуры>
//
// Параметры:
// Ссылка – Ссылка, КлючЗаписи, КонстантаМенеджер;
// ПолноеИмя - Строка - полное имя метаданных для константы.
//
Процедура ОткрытьСсылкуИзРезультатаПоискаСсылокЛкс(Ссылка, ПолноеИмя = "") Экспорт
Если ЛиКлючЗаписиРегистраЛкс(Ссылка) Тогда
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(Ссылка));
ПолноеИмя = ОбъектМетаданных.ПолноеИмя();
ФормаСписка = ПолучитьФормуСпискаЛкс(ОбъектМетаданных.ПолноеИмя(),,,,,, Ссылка);
ФормаСписка.Открыть();
ИначеЕсли ЛиКорневойТипКонстантыЛкс(ПервыйФрагментЛкс(ПолноеИмя)) Тогда
ОткрытьКонстантуВСпискеЛкс(ПоследнийФрагментЛкс(ПолноеИмя));
Иначе
ОткрытьЗначение(Ссылка);
КонецЕсли;
КонецПроцедуры // ОткрытьСсылкуИзРезультатаПоискаСсылокЛкс()
Процедура ОткрытьКонстантуВСпискеЛкс(ИмяКонстанты) Экспорт
ФормаСписка = ПолучитьФормуЛкс("Обработка.ирРедакторКонстант.Форма",,, ИмяКонстанты);
ФормаСписка.НачальноеЗначениеВыбора = ИмяКонстанты;
ФормаСписка.Открыть();
КонецПроцедуры
Функция ПромежуточноеОбновлениеСтроковогоЗначенияПоляВводаЛкс(Знач Элемент, Знач Текст = Неопределено, Знач ВыделитьТекстДоКонца = Ложь) Экспорт
НачалоКолонки = 0; НачалоСтроки = 0; КонецКолонки = 0; КонецСтроки = 0;
Элемент.ПолучитьГраницыВыделения(НачалоСтроки, НачалоКолонки, КонецСтроки, КонецКолонки);
Если Текст = Неопределено Тогда
Текст = Элемент.Значение;
КонецЕсли;
Элемент.Значение = Текст;
//ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, Текст); // Так делать нельзя, т.к. будет засоряться история последних введенных строк
Если Текст = "" Тогда
Возврат Неопределено;
КонецЕсли;
Элемент.УстановитьГраницыВыделения(1, СтрДлина(Текст) + 1);
Элемент.ВыделенныйТекст = Элемент.ВыделенныйТекст;
Если ВыделитьТекстДоКонца Тогда
//Элемент.УстановитьГраницыВыделения(СтрДлина(Текст) + 1, СтрДлина(Текст) + 1); // так будет ошибка, ставить справа от последнего символа можно только 4-мя параметрами
Элемент.УстановитьГраницыВыделения(НачалоСтроки, СтрДлина(Текст) + 1, КонецСтроки, СтрДлина(Текст) + 1);
Иначе
Элемент.УстановитьГраницыВыделения(НачалоСтроки, НачалоКолонки, КонецСтроки, КонецКолонки);
КонецЕсли;
КонецФункции
Функция ПрочитатьЗначениеИзФайлаСКонтролемПотерьЛкс(ПолноеИмяФайла) Экспорт
ФайлЗначения = Новый Файл(ПолноеИмяФайла);
ПолученноеЗначение = Неопределено;
Если ФайлЗначения.Существует() Тогда
Попытка
ПолученноеЗначение = ЗначениеИзФайла(ПолноеИмяФайла);
Исключение
СообщитьЛкс("Ошибка чтения из файла: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Если ПолученноеЗначение = Неопределено Тогда
Возврат ПолученноеЗначение;
КонецЕсли;
СравнениеФайлов = Новый СравнениеФайлов;
ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
Если Не ПроверитьСериализациюXMLПередВызовомЗначениеВФайлЛкс(ПолученноеЗначение) Тогда
//СообщитьЛкс("Не удалось сериализовать считанные из файла данные: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат ПолученноеЗначение;
КонецЕсли;
Попытка
ЗначениеВФайл(ИмяВременногоФайла, ПолученноеЗначение);
Исключение
Возврат ПолученноеЗначение;
КонецПопытки;
СравнениеФайлов.ПервыйФайл = ПолноеИмяФайла;
СравнениеФайлов.ВторойФайл = ИмяВременногоФайла;
СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.Двоичное;
Если Не СравнениеФайлов.Сравнить() Тогда
СообщитьЛкс("При чтении из файла вероятно была потеряна часть информации", СтатусСообщения.Внимание);
КонецЕсли;
УдалитьФайлы(ИмяВременногоФайла);
Возврат ПолученноеЗначение;
КонецФункции
Функция ПроверитьСериализациюXMLПередВызовомЗначениеВФайлЛкс(Знач ПолученноеЗначение) Экспорт
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803012 Тогда
СериализацияXMLУспешна = Истина;
Иначе
СериализацияXMLУспешна = Ложь;
Попытка
// Антибаг платформы https://bugboard.v8.1c.ru/error/000035977.html
// ЗначениеВФайл на некоторых ошибках вызывает безусловное завершение работы http://devtool1c.ucoz.ru/forum/2-746-1
// http://devtool1c.ucoz.ru/forum/2-752-1
// Выполняется сильно дольше чем ЗначениеВФайл!
ирОбщий.СохранитьОбъектВВидеСтрокиXMLЛкс(ПолученноеЗначение);
СериализацияXMLУспешна = Истина;
Исключение
// Может быть ошибка - Отсутствует отображение для типа 'ОбходРезультатаЗапроса'. http://devtool1c.ucoz.ru/forum/2-756-1
КонецПопытки;
КонецЕсли;
Возврат СериализацияXMLУспешна;
КонецФункции
Процедура УстановитьАвтоматическоеРаскрытиеУзловДереваЛкс(Знач ТабличноеПолеДерева, Порог = 30) Экспорт
Дерево = ТабличноеПолеДерева.Значение;
#Если Сервер И Не Сервер Тогда
Дерево = Новый ДеревоЗначений;
#КонецЕсли
ДеревоЗначенийСвернутьРазвернутьЛкс(ТабличноеПолеДерева, ирОбщий.ВсеСтрокиДереваЗначенийЛкс(Дерево).Количество() > Порог);
Если Дерево.Строки.Количество() = 1 Тогда
ТабличноеПолеДерева.Развернуть(Дерево.Строки[0]);
КонецЕсли;
КонецПроцедуры
#КонецЕсли
Функция НомерВерсииБСПЛкс() Экспорт
Если Метаданные.РегистрыСведений.Найти("ВерсииПодсистем") <> Неопределено Тогда
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
| ВерсииПодсистем.Версия КАК Версия
|ИЗ
| РегистрСведений.ВерсииПодсистем КАК ВерсииПодсистем
|ГДЕ
| ВерсииПодсистем.ИмяПодсистемы = &ИмяПодсистемы
|";
Запрос.УстановитьПараметр("ИмяПодсистемы", "СтандартныеПодсистемы");
Таблица = Запрос.Выполнить().Выгрузить();
Если Таблица.Количество() > 0 Тогда
ВерсияБСП = Таблица[0].Версия;
КонецЕсли;
КонецЕсли;
Возврат ВерсияБСП;
КонецФункции
Функция НеблокирующиеМетаданныеБСПЛкс() Экспорт
#Если ТолстыйКлиентУправляемоеПриложение И Не Сервер Тогда
ИменаМД = ирСервер.НеблокирующиеМетаданныеБСПЛкс();
#Иначе
Массив = Новый Массив;
ОбщегоНазначенияПереопределяемыйМой = Вычислить("ОбщегоНазначенияПереопределяемый");
#Если Сервер И Не Сервер Тогда
ОбщегоНазначенияПереопределяемыйМой = ОбщегоНазначенияПереопределяемый;
#КонецЕсли
ОбщегоНазначенияПереопределяемыйМой.ПриДобавленииИсключенийПоискаСсылок(Массив);
ИменаМД = Новый Массив;
Для Каждого ОбъектМД Из Массив Цикл
Если ТипЗнч(ОбъектМД) = Тип("ОбъектМетаданных") Тогда
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
Иначе
ПолноеИмяМД = ОбъектМД;
КонецЕсли;
ИменаМД.Добавить(ПолноеИмяМД);
КонецЦикла;
#КонецЕсли
Возврат ИменаМД;
КонецФункции
Функция ДопРеквизитыБСПОбъектаЛкс(СсылкаОбъекта) Экспорт
#Если Сервер И Не Сервер Тогда
СсылкаОбъекта = Справочники.ирАлгоритмы.ПустаяСсылка();
#КонецЕсли
СписокСвойств = Неопределено;
Если Истина
И ирКэш.НомерВерсииБСПЛкс() > 200
И Не ирКэш.ЛиПортативныйРежимЛкс()
И Метаданные.ОбщиеМодули.Найти("УправлениеСвойствами") <> Неопределено
И ТабличныеЧастиОбъектаЛкс(СсылкаОбъекта).Свойство("ДополнительныеРеквизиты")
И Метаданные.ОпределяемыеТипы.ВладелецДополнительныхСведений.Тип.СодержитТип(ТипЗнч(СсылкаОбъекта))
Тогда
СписокСвойств = ирСервер.СписокДопСвойствОбъектаБСПЛкс(СсылкаОбъекта);
КонецЕсли;
Возврат СписокСвойств;
КонецФункции
// Доп. сведение сразу записывается, а доп. реквизит только устанавливается в ТЧ.ДополнительныеРеквизиты без записи
//
// Параметры:
// Объект - - ? -
// ДопРеквизит - - ?, ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения -
// НовоеЗначение - - ? -
// ИмяПоляСсылка - - ? -
// ОбработатьРеквизит - -
// ОбработатьСведение - -
//
Процедура УстановитьЗначениеДопРеквизитаБСПЛкс(Объект, ДопРеквизит, НовоеЗначение, ИмяПоляСсылка = Неопределено, ОбработатьРеквизит = Истина, ОбработатьСведение = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ДопРеквизит = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ПустаяСсылка();
#КонецЕсли
Если Не ЗначениеЗаполнено(ИмяПоляСсылка) Тогда
ИмяПоляСсылка = ирОбщий.ПеревестиСтроку("Ссылка");
КонецЕсли;
Если Не ДопРеквизит.ЭтоДополнительноеСведение Тогда // изменение дополнительного реквизита
Если Не ОбработатьРеквизит Тогда
Возврат;
КонецЕсли;
//Если Не СвойствоНужноИзменять(Объект.Ссылка, ДопРеквизит, Параметры) Тогда
// Продолжить;
//КонецЕсли;
НайденнаяСтрока = Объект.ДополнительныеРеквизиты.Найти(ДопРеквизит, "Свойство");
Если ЗначениеЗаполнено(НовоеЗначение) Тогда
Если НайденнаяСтрока = Неопределено Тогда
НайденнаяСтрока = Объект.ДополнительныеРеквизиты.Добавить();
НайденнаяСтрока.Свойство = ДопРеквизит;
КонецЕсли;
НайденнаяСтрока.Значение = НовоеЗначение;
МодульУправлениеСвойствами = Вычислить("УправлениеСвойствамиСлужебный");
#Если Сервер И Не Сервер Тогда
МодульУправлениеСвойствами = УправлениеСвойствамиСлужебный;
#КонецЕсли
Если МодульУправлениеСвойствами.ИспользоватьНеограниченнуюСтроку(ДопРеквизит.ТипЗначения, ДопРеквизит.МногострочноеПолеВвода) Тогда
НайденнаяСтрока.ТекстоваяСтрока = НовоеЗначение;
КонецЕсли;
Иначе
Если НайденнаяСтрока <> Неопределено Тогда
Объект.ДополнительныеРеквизиты.Удалить(НайденнаяСтрока);
КонецЕсли;
КонецЕсли;
Иначе // изменение дополнительного сведения
Если Не ОбработатьСведение Тогда
Возврат;
КонецЕсли;
//Если Не СвойствоНужноИзменять(Объект.Ссылка, ДопРеквизит, Параметры) Тогда
// Продолжить;
//КонецЕсли;
МенеджерЗаписи = РегистрыСведений["ДополнительныеСведения"].СоздатьМенеджерЗаписи();
МенеджерЗаписи.Объект = Объект[ИмяПоляСсылка];
МенеджерЗаписи.Свойство = ДопРеквизит;
МенеджерЗаписи.Значение = НовоеЗначение;
МенеджерЗаписи.Записать();
КонецЕсли;
КонецПроцедуры
Функция ЗначениеДопРеквизитаБСПЛкс(Знач Объект, ДопРеквизит, Знач ИмяПоляСсылка = "") Экспорт
Если Не ЗначениеЗаполнено(ИмяПоляСсылка) Тогда
ИмяПоляСсылка = ирОбщий.ПеревестиСтроку("Ссылка");
КонецЕсли;
Если Не ДопРеквизит.ЭтоДополнительноеСведение Тогда // изменение дополнительного реквизита
НайденнаяСтрока = Объект.ДополнительныеРеквизиты.Найти(ДопРеквизит, "Свойство");
Если НайденнаяСтрока <> Неопределено Тогда
ТекущееЗначение = НайденнаяСтрока.Значение;
КонецЕсли;
Иначе
МенеджерЗаписи = РегистрыСведений["ДополнительныеСведения"].СоздатьМенеджерЗаписи();
МенеджерЗаписи.Объект = Объект[ИмяПоляСсылка];
МенеджерЗаписи.Свойство = ДопРеквизит;
МенеджерЗаписи.Прочитать();
ТекущееЗначение = МенеджерЗаписи.Значение;
КонецЕсли;
Возврат ТекущееЗначение;
КонецФункции
Процедура ОформитьСтрокуДопРеквизитаБСПЛкс(ОформлениеСтроки) Экспорт
ОформлениеСтроки.ЦветТекста = Новый Цвет(0, 0, 128);
КонецПроцедуры
Функция ПраваСОграничениямиДоступаКДаннымЛкс() Экспорт
ДоступныеПрава = Новый СписокЗначений;
ДоступныеПрава.Добавить("Чтение", "Read");
ДоступныеПрава.Добавить("Добавление", "Insert");
ДоступныеПрава.Добавить("Изменение", "Update");
ДоступныеПрава.Добавить("Удаление", "Delete");
Возврат ДоступныеПрава;
КонецФункции
Процедура ЗаменитьИВыделитьВыделенныйТекстПоляЛкс(ЭтаФорма, ПолеТекстаВыражения, Знач НовыйВыделенныйТекст = "") Экспорт
Перем Граница1, Граница2, Граница3, Граница4;
Граница1 = 0; Граница2 = 0; Граница3 = 0; Граница4 = 0;
ПолеТекстаВыражения.ПолучитьГраницыВыделения(Граница1, Граница2, Граница3, Граница4);
Если Не ЗначениеЗаполнено(НовыйВыделенныйТекст) Тогда
Если ТипЗнч(ПолеТекстаВыражения) = Тип("ПолеВвода") Тогда
НовыйВыделенныйТекст = ПолеТекстаВыражения.Значение;
Иначе
НовыйВыделенныйТекст = ПолеТекстаВыражения.ПолучитьТекст();
КонецЕсли;
Граница2 = 1;
Иначе
ПолеТекстаВыражения.ВыделенныйТекст = НовыйВыделенныйТекст;
КонецЕсли;
ПолеТекстаВыражения.УстановитьГраницыВыделения(Граница1, Граница2, Граница1, Граница2 + СтрДлина(НовыйВыделенныйТекст));
ЭтаФорма.ТекущийЭлемент = ПолеТекстаВыражения;
КонецПроцедуры
Процедура ОбновитьЗаголовокФормыСОткрытымФайломЛкс(Знач ЭтаФорма, Знач ИмяОткрытогоФайла = Неопределено, Знач АвтосохранениеТекущегоФайла = Ложь) Экспорт
Если ИмяОткрытогоФайла <> "" Тогда
НоваяСтрока = "";
Если АвтосохранениеТекущегоФайла Тогда
НоваяСтрока = " <Автосохранение> ";
КонецЕсли;
НоваяСтрока = НоваяСтрока + ИмяОткрытогоФайла;
Иначе
НоваяСтрока = "<Новый файл>";
КонецЕсли;
ОбновитьТекстПослеМаркераВСтрокеЛкс(ЭтаФорма.Заголовок, , НоваяСтрока, ": ");
КонецПроцедуры // мУстановитьЗаголовокФормы()
Функция ОбновитьЗаголовкиСтраницПанелиЛкс(ЭтаФорма, ЭлементыФормы, Панель) Экспорт
ТабличноеПолеСтраниц = ЭлементыФормы.Найти("Страницы" + Панель.Имя);
Если ТабличноеПолеСтраниц <> Неопределено Тогда
ТаблицаСтраниц = ДанныеЭлементаФормыЛкс(ТабличноеПолеСтраниц);
КонецЕсли;
ОбщееКоличество = 0;
НеготовыеСтраницы = СлужебныеДанныеФормыЛкс(ЭтаФорма).НеготовыеСтраницы;
#Если Сервер И Не Сервер Тогда
НеготовыеСтраницы = Новый СписокЗначений;
#КонецЕсли
Если ТипЗнч(Панель) = Тип("ГруппаФормы") Тогда
Страницы = Панель.ПодчиненныеЭлементы;
Иначе
Страницы = Панель.Страницы;
КонецЕсли;
Для Каждого Страница Из Страницы Цикл
ИмяСтраницы = Страница.Имя;
Если ИмяСтраницы = "" Тогда // Служебная страница. Появляется после очистки страниц.
Продолжить;
КонецЕсли;
Если Найти("." + ИмяСтраницы, ".Страница") = 1 Тогда
ИмяСтраницы = СтрЗаменить("." + ИмяСтраницы, ".Страница", "");
КонецЕсли;
ЭУ = ЭлементыФормы.Найти(ИмяСтраницы);
Если ЭУ = Неопределено Тогда
Продолжить;
КонецЕсли;
ЗначениеСтраницы = Неопределено;
#Если Клиент Тогда
Если ТипЗнч(Страница) = Тип("СтраницаПанели") Тогда
ЗначениеСтраницы = Страница.Значение;
КонецЕсли;
#КонецЕсли
Если Ложь
Или НеготовыеСтраницы.НайтиПоЗначению(Страница.Имя) <> Неопределено
Или (Истина
И ТипЗнч(ЗначениеСтраницы) = Тип("Структура")
И ЗначениеСтраницы.Свойство("Рассчитано")
И Не ЗначениеСтраницы.Рассчитано)
Тогда
Количество = "-";
Иначе
Суффикс = "";
Количество = Неопределено;
Если Ложь
#Если Клиент Тогда
Или ТипЗнч(ЭУ) = Тип("ТабличноеПоле")
#КонецЕсли
Или ТипЗнч(ЭУ) = Тип("ТаблицаФормы")
Тогда
ЗначениеЭУ = ДанныеЭлементаФормыЛкс(ЭУ);
Если ТипЗнч(ЗначениеЭУ) = Тип("ДеревоЗначений") Тогда
Количество = ЗначениеЭУ.Строки.Количество();
Суффикс = "*";
ИначеЕсли ТипЗнч(ЗначениеЭУ) = Тип("ДанныеФормыДерево") Тогда
Количество = ЗначениеЭУ.ПолучитьЭлементы().Количество();
Суффикс = "*";
Иначе
Попытка
Количество = ЗначениеЭУ.Количество();
Исключение КонецПопытки;
Если Количество = Неопределено Тогда
// Компоновка
Попытка
Количество = ЗначениеЭУ.Элементы.Количество();
//Суффикс = "*";
Исключение КонецПопытки;
КонецЕсли;
КонецЕсли;
//Если Количество = 0 Тогда
// Попытка
// КоличествоКолонок = ЗначениеЭУ.Колонки.Количество();
// Исключение
// КоличествоКолонок = 1;
// КонецПопытки;
// Если КоличествоКолонок = 0 Тогда
// Количество = "-";
// КонецЕсли;
//КонецЕсли;
#Если Клиент Тогда
ИначеЕсли Ложь
Или ТипЗнч(ЭУ) = Тип("ПолеТабличногоДокумента")
Или ТипЗнч(ЭУ) = Тип("ПолеТабличногоДокументаФормы")
Тогда
//Количество = ?(ЭУ.ВысотаТаблицы > 0, 1, 0);
Количество = ЭУ.ВысотаТаблицы;
ИначеЕсли Ложь
Или ТипЗнч(ЭУ) = Тип("ПолеТекстовогоДокумента")
Или ТипЗнч(ЭУ) = Тип("ПолеТекстовогоДокументаФормы")
Тогда
//Количество = ?(ЭУ.КоличествоСтрок() > 0, 1, 0);
Количество = ЭУ.КоличествоСтрок();
ИначеЕсли Ложь
Или ТипЗнч(ЭУ) = Тип("ПолеГрафическойСхемы")
Или ТипЗнч(ЭУ) = Тип("ПолеГрафическойСхемыФормы")
Тогда
Количество = ЭУ.ЭлементыГрафическойСхемы.Количество();
#КонецЕсли
ИначеЕсли Ложь
#Если Клиент Тогда
Или ТипЗнч(ЭУ) = Тип("Панель")
#КонецЕсли
Или (Истина
И ТипЗнч(ЭУ) = Тип("ГруппаФормы")
И ЭУ.Вид = ВидГруппыФормы.Страницы)
Тогда
//Количество = ЭУ.Страницы.Количество();
//Если Количество = 1 Тогда
// Если ЭУ.Страницы[0].Имя = "" Тогда
// Количество = 0;
// КонецЕсли;
//КонецЕсли;
Количество = ОбновитьЗаголовкиСтраницПанелиЛкс(ЭтаФорма, ЭлементыФормы, ЭУ);
КонецЕсли;
Если ТипЗнч(Количество) = Тип("Число") Тогда
ОбщееКоличество = ОбщееКоличество + Количество;
КонецЕсли;
КонецЕсли;
Если ТаблицаСтраниц <> Неопределено Тогда
СтрокаСтраницы = ТаблицаСтраниц.НайтиСтроки(Новый Структура("ИмяСтраницы", ИмяСтраницы));
Если СтрокаСтраницы.Количество() > 0 Тогда
СтрокаСтраницы = СтрокаСтраницы[0];
СтрокаСтраницы.Количество = Количество;
СтрокаСтраницы.Непустая = СтрокаСтраницы.Количество > 0;
КонецЕсли;
КонецЕсли;
ОбновитьТекстПослеМаркераВСтрокеЛкс(Страница.Заголовок, , "" + Количество + Суффикс + ")", "(");
КонецЦикла;
Возврат ОбщееКоличество;
КонецФункции
//Для Объект = Неопределено возвращает Ложь, работает только для русского и английского языков платформы
// Параметры:
// КоличествоПараметров - нужно задать заведомо большее значение, чем может быть у метода
Функция МетодРеализованЛкс(Объект, ИмяМетода) Экспорт
Если Объект = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Выражение = "Объект." + ИмяМетода + "(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)";
Попытка
Выполнить(Выражение);
Исключение
Инфо = ИнформацияОбОшибке();
Описание = Инфо.Описание;
КонецПопытки;
Результат = Найти(НРег(Описание), "(" + НРег(ИмяМетода) + ")") = 0;
Возврат Результат;
КонецФункции
// Параметры:
// КоличествоПроходов - Число(Н8,0)
// КлючЗамера - Строка
// ВыдатьСообщение - Булево
//
Функция НачатьЗамерЛкс(Знач КоличествоПроходов = 1, Знач КлючЗамера = "", Знач ВыдатьСообщение = Ложь) Экспорт
ирПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
ирПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ТаблицаЗамеров = ирПлатформа.мТаблицаЗамеров;
Если Не ЗначениеЗаполнено(КлючЗамера) Тогда
КлючЗамера = "Замер" + ТаблицаЗамеров.Колонки[0].Имя;
КонецЕсли;
ТаблицаЗамеров.Колонки[0].Имя = "_" + XMLСтрока(Число(Сред(ТаблицаЗамеров.Колонки[0].Имя, 2)) + 1);
СтрокаЗамера = ТаблицаЗамеров.Добавить();
СтрокаЗамера.Ключ = КлючЗамера;
#Если Клиент Тогда
СтрокаЗамера.Отладчик = ирПлатформа.ИдентификаторПроцессаОтладчика() <> Неопределено;
#КонецЕсли
СтрокаЗамера.КоличествоПроходов = КоличествоПроходов;
Если Ложь
Или ВыдатьСообщение
//Или СтрокаЗамера.Отладчик
Тогда
Сообщение = "Начало замера """ + СтрокаЗамера.Ключ + """, количество проходов = " + КоличествоПроходов;
Если СтрокаЗамера.Отладчик Тогда
Сообщение = Сообщение + ". Отладчик подключен и неравномерно замедляет выполнение кода!";
КонецЕсли;
СообщитьЛкс(Сообщение);
КонецЕсли;
СтрокаЗамера.ДатаНачала = ТекущееВремяВМиллисекундахЛкс();
Результат = КоличествоПроходов;
Возврат Результат;
КонецФункции
// Параметры:
// КлючЗамера - Строка - По умолчанию последний замер
//
Функция КончитьЗамерЛкс(Знач КлючЗамера = "") Экспорт
ТекущееВремя = ТекущееВремяВМиллисекундахЛкс();
ирПлатформа = ирКэш.Получить();
ТаблицаЗамеров = ирПлатформа.мТаблицаЗамеров;
Если Не ЗначениеЗаполнено(КлючЗамера) Тогда
Если ТаблицаЗамеров.Количество() > 0 Тогда
СтрокаЗамера = ТаблицаЗамеров[ТаблицаЗамеров.Количество() - 1];
КонецЕсли;
Иначе
СтрокаЗамера = ТаблицаЗамеров.Найти(КлючЗамера, "Ключ");
КонецЕсли;
Если СтрокаЗамера = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Длительность = ТекущееВремя - СтрокаЗамера.ДатаНачала;
Длительность = Длительность / 1000;
Сообщение = "Окончание замера """ + СтрокаЗамера.Ключ + """ - Длительность = " + XMLСтрока(Длительность) + "с";
Если СтрокаЗамера.КоличествоПроходов > 1 Тогда
Среднее = Длительность / СтрокаЗамера.КоличествоПроходов;
Сообщение = Сообщение + ", Среднее = " + XMLСтрока(Среднее) + "с";
КонецЕсли;
Если Ложь
Или СтрокаЗамера.Отладчик
Или ирПлатформа.ИдентификаторПроцессаОтладчика() <> Неопределено
Тогда
Сообщение = Сообщение + ". Отладчик подключен и неравномерно замедляет выполнение кода!";
КонецЕсли;
СообщитьЛкс(Сообщение);
ТаблицаЗамеров.Удалить(СтрокаЗамера);
Результат = Длительность;
Возврат Результат;
КонецФункции
Функция ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ТабличноеПоле, СтруктураОтбора = Неопределено) Экспорт
ВременныйПостроительЗапроса = Новый ПостроительЗапроса;
ВременныйПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличноеПоле.Значение);
Попытка
ОтборСтрок = ТабличноеПоле.ОтборСтрок;
Исключение
КонецПопытки;
Если ОтборСтрок <> Неопределено Тогда
СкопироватьОтборПостроителяЛкс(ВременныйПостроительЗапроса.Отбор, ОтборСтрок);
КонецЕсли;
Если СтруктураОтбора <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
ВременныйПостроительЗапроса.Отбор.Добавить(КлючИЗначение.Ключ).Установить(КлючИЗначение.Значение);
КонецЦикла;
КонецЕсли;
Возврат ВременныйПостроительЗапроса;
КонецФункции
Функция ПолучитьСтруктуруВыделенияТекстаЛкс() Экспорт
Структура = Новый Структура();
Структура.Вставить("НачальнаяСтрока", 1);
Структура.Вставить("НачальнаяКолонка", 1);
Структура.Вставить("КонечнаяСтрока", 1);
Структура.Вставить("КонечнаяКолонка", 1);
Возврат Структура;
КонецФункции
Функция ПолеТекста_ПолучитьДиапазонВыделенияЛкс(ПолеТекста) Экспорт
СтруктураВыделения = ПолучитьСтруктуруВыделенияТекстаЛкс();
ПолеТекста.ПолучитьГраницыВыделения(СтруктураВыделения.НачальнаяСтрока, СтруктураВыделения.НачальнаяКолонка, СтруктураВыделения.КонечнаяСтрока, СтруктураВыделения.КонечнаяКолонка);
Возврат СтруктураВыделения;
КонецФункции
Функция ПолеТекста_УстановитьДиапазонВыделенияЛкс(Знач ПолеТекста, Знач СтруктураВыделения) Экспорт
Если СтруктураВыделения.НачальнаяКолонка <= 0 Тогда
СтруктураВыделения.НачальнаяКолонка = 1;
КонецЕсли;
Если СтруктураВыделения.НачальнаяСтрока <= 0 Тогда
СтруктураВыделения.НачальнаяСтрока = 1;
КонецЕсли;
Если СтруктураВыделения.НачальнаяКолонка > СтруктураВыделения.КонечнаяКолонка Тогда
СтруктураВыделения.КонечнаяКолонка = СтруктураВыделения.НачальнаяКолонка;
КонецЕсли;
Если СтруктураВыделения.НачальнаяСтрока > СтруктураВыделения.КонечнаяСтрока Тогда
СтруктураВыделения.КонечнаяСтрока = СтруктураВыделения.НачальнаяСтрока;
КонецЕсли;
ПолеТекста.УстановитьГраницыВыделения(СтруктураВыделения.НачальнаяСтрока, СтруктураВыделения.НачальнаяКолонка, СтруктураВыделения.КонечнаяСтрока, СтруктураВыделения.КонечнаяКолонка);
Возврат Неопределено;
КонецФункции
Процедура ПолеТекстовогоДокументаУстановитьВставитьТекстИПереносСтрокиЛкс(Знач ПолеТекстовогоДокумента, Знач НовыйТекст) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекстовогоДокумента = Новый ТекстовыйДокумент;
#КонецЕсли
НачальнаяПозиция = 0;
КонечнаяПозиция = 0;
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяПозиция, КонечнаяПозиция, НачальнаяПозиция, КонечнаяПозиция);
ПолеТекстовогоДокумента.ВыделенныйТекст = НовыйТекст;
// Антибаг 8.3.12 https://partners.v8.1c.ru/forum/t/1719342/m/1719342, http://www.hostedredmine.com/issues/882423
ПолеТекстовогоДокумента.ВыделенныйТекст = Символы.ПС;
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяПозиция, КонечнаяПозиция, НачальнаяПозиция, КонечнаяПозиция);
КонецПроцедуры
// Копирует таблицу значений из исходной таблицы значений с удалением типа Null из описаний типов колонок.
// Параметры:
// ЗагружатьДанныеВНовуюТаблицу - Булево - после создания новой таблицы загрузить в нее данные из исходной
// ОбработатьТолькоКолонки - Строка - имена колонок разделенные запятыми
// НеОбрабатыватьКолонки - Строка - имена колонок разделенные запятыми
//
// Возвращаемое значение:
// ТаблицаЗначений
//
Функция ТаблицаСКолонкамиБезТипаNullЛкс(Знач Таблица, ЗагружатьДанныеВНовуюТаблицу = Истина, ОбрабатыватьТолькоКолонки = "", НеОбрабатыватьКолонки = "") Экспорт
Результат = Новый ТаблицаЗначений;
НовыеКолонки = Результат.Колонки;
ИсходныеКолонки = Таблица.Колонки;
ИменаОбрабатываемыхКолонок = Новый Массив();
Если ОбрабатыватьТолькоКолонки <> "" Тогда
ИменаОбрабатываемыхКолонок = СтрРазделитьЛкс(ОбрабатыватьТолькоКолонки, ",", Истина);
КонецЕсли;
ИменаНеобрабатываемыхКолонок = Новый Массив();
Если НеОбрабатыватьКолонки <> "" Тогда
ИменаНеобрабатываемыхКолонок = СтрРазделитьЛкс(НеОбрабатыватьКолонки, ",", Истина);
КонецЕсли;
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Для Каждого Колонка Из ИсходныеКолонки Цикл
Если Ложь
Или (Истина
И ОбрабатыватьТолькоКолонки <> ""
И ИменаОбрабатываемыхКолонок.Найти(Колонка.Имя) = Неопределено)
Или (Истина
И НеОбрабатыватьКолонки <> ""
И ИменаНеобрабатываемыхКолонок.Найти(Колонка.Имя) <> Неопределено)
Тогда
ОписаниеТипов = Колонка.ТипЗначения;
Иначе
ОписаниеТипов = Новый ОписаниеТипов(Колонка.ТипЗначения, , "NULL");
КонецЕсли;
НовыеКолонки.Добавить(Колонка.Имя, ОписаниеТипов, Колонка.Заголовок, Колонка.Ширина);
КонецЦикла;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Каждого Колонка Из ИсходныеКолонки Цикл Если Ложь Или (Истина И ОбрабатыватьТолькоКолонки <> "" И ИменаОбрабатываемыхКолонок.Найти(Колонка.Имя) = Неопределено) Или (Истина И НеОбрабатыватьКолонки <> "" И ИменаНеобрабатываемыхКолонок.Найти(Колонка.Имя) <> Неопределено) Тогда ОписаниеТипов = Колонка.ТипЗначения; Иначе ОписаниеТипов = Новый ОписаниеТипов(Колонка.ТипЗначения, , "NULL"); КонецЕсли; НовыеКолонки.Добавить(Колонка.Имя, ОписаниеТипов, Колонка.Заголовок, Колонка.Ширина); КонецЦикла;
Если ЗагружатьДанныеВНовуюТаблицу Тогда
ЗагрузитьВТаблицуЗначенийЛкс(Таблица, Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьОпределениеТаблицыБДДляИЗЛкс(ИмяТаблицы) Экспорт
Результат = ИмяТаблицы;
ТипТаблицы = ТипТаблицыБДЛкс(ИмяТаблицы);
Если ТипТаблицы = "ДвиженияССубконто" Тогда
Результат = Результат + "(,, {Регистратор.*, НомерСтроки, Активность})";
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяТаблицы, выхМакетныйОбъект, выхТекущаяГруппаТипаМетаданных = Неопределено, выхКлючевыеПоля = Неопределено, ОбъектыНаСервере = Неопределено) Экспорт
выхКлючевыеПоля = Новый Массив;
ТипТаблицы = ТипТаблицыБДЛкс(ПолноеИмяТаблицы);
ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы);
Если ЛиМетаданныеСсылочногоОбъектаЛкс(ОбъектМД) Тогда
выхМакетныйОбъект = ОбъектБДПоКлючуЛкс(ПолноеИмяТаблицы,,,, ОбъектыНаСервере);
выхТекущаяГруппаТипаМетаданных = "Ссылочный";
выхКлючевыеПоля.Добавить("Ссылка");
ИначеЕсли ЛиМетаданныеРегистраЛкс(ОбъектМД) Тогда
выхМакетныйОбъект = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицы, ОбъектыНаСервере);
выхТекущаяГруппаТипаМетаданных = "Регистр";
Для Каждого ЭлементОтбора Из выхМакетныйОбъект.Методы.Отбор Цикл
выхКлючевыеПоля.Добавить(ЭлементОтбора.ПутьКДанным);
КонецЦикла;
ИначеЕсли ЛиКорневойТипКонстантыЛкс(ТипТаблицы) Тогда
выхМакетныйОбъект = ОбъектБДПоКлючуЛкс(ПолноеИмяТаблицы,,,, ОбъектыНаСервере);
выхТекущаяГруппаТипаМетаданных = "Константа";
Иначе
Если ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
выхТекущаяГруппаТипаМетаданных = "ВложеннаяТаблица";
КонецЕсли;
//ВызватьИсключение "Макетный объект данных для таблицы типа " + ТипТаблицы + " не допустим";
КонецЕсли;
КонецПроцедуры
Функция ОписаниеТиповОбъектаИлиСтрокиБДПоИменамТаблицЛкс(Знач МассивИлиИмяТаблицыБД, Знач НуженТипОбъекта, РежимОбходаДанных = "Строки", Знач ТипТаблицы = Неопределено, выхПолноеИмяТаблицы = Неопределено) Экспорт
МассивИменТаблицБД = Новый Массив();
Если ТипЗнч(МассивИлиИмяТаблицыБД) = Тип("Строка") Тогда
ТипТаблицы = ирОбщий.ТипТаблицыБДЛкс(МассивИлиИмяТаблицыБД);
МассивИменТаблицБД.Добавить(МассивИлиИмяТаблицыБД);
Иначе
МассивИменТаблицБД = МассивИлиИмяТаблицыБД;
КонецЕсли;
МассивТипов = Новый Массив();
ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(МассивИменТаблицБД[0]);
Если ирОбщий.ЛиМетаданныеСсылочногоОбъектаЛкс(ОбъектМД) Тогда
Если РежимОбходаДанных = "КлючиОбъектов" Тогда
РасширениеТипа = "Ссылка";
Иначе
РасширениеТипа = "Объект";
КонецЕсли;
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ИмяТипа = ирОбщий.ИмяТипаИзПолногоИмениТаблицыБДЛкс(ИмяТаблицыБД, РасширениеТипа);
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли Ложь
Или ирОбщий.ЛиКорневойТипЖурналаДокументовЛкс(ТипТаблицы)
Тогда
Если РежимОбходаДанных = "КлючиОбъектов" Тогда
РасширениеТипа = "Ссылка";
Иначе
РасширениеТипа = "Объект";
КонецЕсли;
Поля = ирОбщий.ПоляТаблицыБДЛкс(МассивИменТаблицБД[0]);
Поле = Поля.Найти("Ссылка", "Имя");
Для Каждого ТипЗначения Из Поле.ТипЗначения.Типы() Цикл
ИмяТипа = ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(Метаданные.НайтиПоТипу(ТипЗначения), РасширениеТипа);
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли ТипТаблицы = "Точки" Тогда
РасширениеТипа = "ТочкаМаршрутаБизнесПроцессаСсылка";
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ИмяТипа = СтрЗаменить(ИмяТаблицыБД, "БизнесПроцесс.", РасширениеТипа + ".");
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли ирОбщий.ЛиКорневойТипПеречисленияЛкс(ТипТаблицы) Тогда
РасширениеТипа = "Ссылка";
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ИмяТипа = СтрЗаменить(ИмяТаблицыБД, ".", РасширениеТипа + ".");
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли ирОбщий.ЛиКорневойТипКонстантыЛкс(ТипТаблицы) Тогда
РасширениеТипа = "МенеджерЗначения";
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ИмяТипа = СтрЗаменить(ИмяТаблицыБД, ".", РасширениеТипа + ".");
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ИмяТаблицыБД);
выхПолноеИмяТаблицы = МассивФрагментов[0] + "." + МассивФрагментов[1];
Если Не НуженТипОбъекта И РежимОбходаДанных = "Строки" Тогда
Если Ложь
Или ТипТаблицы = "ТабличнаяЧасть"
Или ТипТаблицы = "ВидыСубконто"
Тогда
ИмяТипа = МассивФрагментов[0] + ТипТаблицы + "Строка." + МассивФрагментов[1];
Иначе // Виды расчета
ИмяТипа = ТипТаблицы + "Строка." + МассивФрагментов[1];
КонецЕсли;
Если ТипТаблицы = "ТабличнаяЧасть" Тогда
ИмяТипа = ИмяТипа + "." + МассивФрагментов[2];
выхПолноеИмяТаблицы = выхПолноеИмяТаблицы + "." + МассивФрагментов[2];
Иначе
выхПолноеИмяТаблицы = выхПолноеИмяТаблицы + "." + ТипТаблицы;
КонецЕсли;
МассивТипов.Добавить(Тип(ИмяТипа));
ИначеЕсли РежимОбходаДанных = "КлючиОбъектов" Тогда
МассивТипов.Добавить(Тип(МассивФрагментов[0] + "Ссылка." + МассивФрагментов[1]));
Иначе
МассивТипов.Добавить(Тип(МассивФрагментов[0] + "Объект." + МассивФрагментов[1]));
КонецЕсли;
КонецЦикла;
ИначеЕсли ирОбщий.ЛиМетаданныеРегистраЛкс(ОбъектМД) Тогда
Если Не НуженТипОбъекта И РежимОбходаДанных = "Строки" Тогда
РасширениеТипа = "Запись";
Иначе
РасширениеТипа = "НаборЗаписей";
КонецЕсли;
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ТипЭлементаДанных = Тип(ирОбщий.ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ИмяТаблицыБД, РасширениеТипа));
МассивТипов.Добавить(ТипЭлементаДанных);
КонецЦикла;
Иначе
ВызватьИсключение "Неподдерживаемый тип таблицы """ + ТипТаблицы + """";
КонецЕсли;
Результат = Новый ОписаниеТипов(МассивТипов);
Возврат Результат;
КонецФункции
Функция ЛиПолноеИмяРегистраБухгалтерииЛкс(ПолноеИмяМД) Экспорт
Фрагменты = СтрРазделитьЛкс(ПолноеИмяМД);
Результат = Истина
И Фрагменты.Количество() = 2
И (Ложь
Или Фрагменты[0] = "AccountingRegister"
Или Фрагменты[0] = "РегистрБухгалтерии");
Возврат Результат;
КонецФункции
// Создает тип из метаданных.
//
// Параметры:
// Метаданные – ОбъектМетаданных;
// *Расширение - Строка, "Ссылка" - расширение типа.
//
// Возвращаемое значение:
// Тип.
//
Функция ПолучитьТипИзМетаданныхЛкс(ОбъектМД, Расширение = "Ссылка") Экспорт
Возврат Тип(ИмяТипаИзПолногоИмениМДЛкс(ОбъектМД, Расширение));
КонецФункции // ПолучитьТипИзМетаданных()
Функция ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Экспорт
ЭлементСостава = ОбщийРеквизит.Состав.Найти(ОбъектМетаданных);
Результат = Истина
И ЭлементСостава <> Неопределено
И (Ложь
Или ЭлементСостава.Использование = Метаданные.СвойстваОбъектов.ИспользованиеОбщегоРеквизита.Использовать
Или (Истина
И ЭлементСостава.Использование = Метаданные.СвойстваОбъектов.ИспользованиеОбщегоРеквизита.Авто
И ОбщийРеквизит.АвтоИспользование = Метаданные.СвойстваОбъектов.АвтоИспользованиеОбщегоРеквизита.Использовать));
Возврат Результат;
КонецФункции
Функция ПолучитьАлгоритмОбъектПоИдентификаторуЛкс(Знач Алгоритм) Экспорт
Если ТипЗнч(Алгоритм) <> Тип("СправочникСсылка.ирАлгоритмы") Тогда
Алгоритм = "" + Алгоритм;
Если Найти(Алгоритм, "-") > 0 Тогда
// Передан GUID
Алгоритм = Справочники.ирАлгоритмы.ПолучитьСсылку(Новый УникальныйИдентификатор(Алгоритм));
Иначе
// Передано имя алгоритма
Попытка
Алгоритм = ПредопределенноеЗначение("Справочник.ирАлгоритмы." + Алгоритм);
Исключение
КонецПопытки;
Если ТипЗнч(Алгоритм) <> Тип("СправочникСсылка.ирАлгоритмы") Тогда
Алгоритм = Справочники.ирАлгоритмы.НайтиПоНаименованию(Алгоритм, Истина);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(Алгоритм) Тогда
ВызватьИсключение "Алгоритм по идентификатору """ + Алгоритм + """ не найден";
КонецЕсли;
Возврат Алгоритм.ПолучитьОбъект();
КонецФункции
//Если объекту не назначена ссылка, назначает эту ссылку
Функция ПолучитьТочнуюСсылкуОбъектаЛкс(ОбъектБД) Экспорт
Ссылка = ОбъектБД.Ссылка;
Если Ссылка.Пустая() Тогда
Ссылка = ОбъектБД.ПолучитьСсылкуНового();
Если Ссылка.Пустая() Тогда
Ссылка = XMLЗначение(ТипЗнч(Ссылка), "" + Новый УникальныйИдентификатор);
ОбъектБД.УстановитьСсылкуНового(Ссылка);
//ОбъектБД.ДополнительныеСвойства.Вставить("СсылкаНового", Ссылка); // Для обхода кривого кода в конфигурациях фиры 1С https://www.forum.mista.ru/topic.php?id=826103#58
КонецЕсли;
КонецЕсли;
Возврат Ссылка;
КонецФункции
Функция ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(Знач Текст) Экспорт
//Если СНовойСтроки Тогда
// Текст = Символы.ПС + Текст;
//КонецЕсли;
Текст = СтрЗаменить(Текст, Символы.ПС, Символы.ПС + "|");
Текст = """" + СтрЗаменить(Текст, """", """""") + """";
Возврат Текст;
КонецФункции // ПолучитьСтроковыйЛитералИзМногострочногоТекста()
Функция ВсеСтрокиДереваЗначенийЛкс(СтрокаИлиДеревоЗначений, ВВидеТаблицыЗначений = Ложь) Экспорт
Если ТипЗнч(СтрокаИлиДеревоЗначений) = Тип("СтрокаДереваЗначений") Тогда
ДеревоЗначений = СтрокаИлиДеревоЗначений.Владелец();
Иначе
ДеревоЗначений = СтрокаИлиДеревоЗначений;
КонецЕсли;
Идентификатор = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", "");
ДеревоЗначений.Колонки.Добавить(Идентификатор);
ВсеСтроки = СтрокаИлиДеревоЗначений.Строки.НайтиСтроки(Новый Структура(Идентификатор,), Истина);
ДеревоЗначений.Колонки.Удалить(Идентификатор);
Если ТипЗнч(СтрокаИлиДеревоЗначений) = Тип("СтрокаДереваЗначений") Тогда
ВсеСтроки.Добавить(СтрокаИлиДеревоЗначений);
КонецЕсли;
Если ВВидеТаблицыЗначений Тогда
ТаблицаСтрокДерева = Новый ТаблицаЗначений;
Для Каждого КолонкаДерева Из ДеревоЗначений.Колонки Цикл
ТаблицаСтрокДерева.Колонки.Добавить(КолонкаДерева.Имя, КолонкаДерева.ТипЗначения, КолонкаДерева.Заголовок, КолонкаДерева.Ширина);
КонецЦикла;
Для Каждого СтрокаДерева Из ВсеСтроки Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтрокДерева.Добавить(), СтрокаДерева);
КонецЦикла;
ВсеСтроки = ТаблицаСтрокДерева;
КонецЕсли;
Возврат ВсеСтроки;
КонецФункции // ПолучитьВсеСтрокиДереваЗначений()
Функция СериализацииРавныЛкс(Таблица1, Таблица2) Экспорт
Хмл1 = СохранитьОбъектВВидеСтрокиXMLЛкс(Таблица1);
Хмл2 = СохранитьОбъектВВидеСтрокиXMLЛкс(Таблица2);
Возврат (Хмл1 = Хмл2);
КонецФункции
// ВариантОбрезания - 1
// ВариантОбрезания - 2
Функция ПолучитьИнформациюОбОшибкеБезВерхнегоМодуляЛкс(ИнформацияОбОшибке = Неопределено, ВариантОбрезания = 2) Экспорт
Если ИнформацияОбОшибке = Неопределено Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецЕсли;
Если ВариантОбрезания = 1 Тогда
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
КонецЕсли;
ИначеЕсли Истина
И ВариантОбрезания = 2
И ИнформацияОбОшибке.Причина <> Неопределено
Тогда
ОписаниеОшибки = ИнформацияОбОшибке.Описание + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
Иначе
ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
КонецЕсли;
Возврат ОписаниеОшибки;
КонецФункции
// МаксимальнаяГлубинаПричины - на сколько уровней вниз надо опуститься, пока есть вложенная причина
Функция ПредставлениеИнформацииОбОшибкеЛкс(Знач ИнформацияОбОшибке, Знач МаксимальнаяГлубинаПричины = 0, УбратьСтрокуКодаСПервогоУровня = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
ОписаниеОшибки = "";
Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда
Для Счетчик = 1 По МаксимальнаяГлубинаПричины Цикл
Если ТипЗнч(ИнформацияОбОшибке.Причина) = Тип("ИнформацияОбОшибке") Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
Если УбратьСтрокуКодаСПервогоУровня Тогда
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если ТипЗнч(ИнформацияОбОшибке.Причина) = Тип("ИнформацияОбОшибке") Тогда
ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(ОписаниеОшибки) Тогда
Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда
ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
Иначе
// Такое может случаться в свойстве ИнформацияОбОшибке объекта ФоновоеЗадание из-за ошибки платформы
ОписаниеОшибки = "Описание ошибки отсутствует";
КонецЕсли;
КонецЕсли;
Возврат ОписаниеОшибки;
КонецФункции
// Первая строка табличного документа содержит заголовки
Функция ТаблицаЗначенийИзТабличногоДокументаЛкс(Знач ТабличныйДокумент, ЛиПерваяСтрокаСодержитИменаКолонок = Истина, _ДлинаСтрокиТипаКолонки = 0, ВычислятьНетипизированныеЗначения = Ложь,
ЛиВтораяСтрокаСодержитТипыЗначений = Ложь, ТолькоВыделеннаяОбласть = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент
#КонецЕсли
Если ТолькоВыделеннаяОбласть Тогда
ТабличныйДокумент = ТабличныйДокумент.ПолучитьОбласть(ТабличныйДокумент.ТекущаяОбласть.Имя);
КонецЕсли;
ТаблицаПриемник = Новый ТаблицаЗначений;
НачальнаяСтрока = 1;
Если ЛиПерваяСтрокаСодержитИменаКолонок Тогда
НачальнаяСтрока = НачальнаяСтрока + 1;
КонецЕсли;
Если ЛиВтораяСтрокаСодержитТипыЗначений Тогда
НачальнаяСтрока = НачальнаяСтрока + 1;
КонецЕсли;
ТипизированныеКолонки = Новый Соответствие;
Для Счетчик = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Если ЛиПерваяСтрокаСодержитИменаКолонок Тогда
ИмяКолонки = ТабличныйДокумент.Область(1, Счетчик).Текст;
Если Найти(ИмяКолонки, ".") > 0 Тогда
Если Найти(ИмяКолонки, "_") > 0 Тогда
ВызватьИсключение "В именах колонок макета не допускается использование одновременно ""_"" и "".""";
КонецЕсли;
ИмяКолонки = СтрЗаменить(ИмяКолонки, ".", "_");
КонецЕсли;
ИмяКолонки = АвтоУникальноеИмяВКоллекцииЛкс(ТаблицаПриемник.Колонки, ИмяКолонки,,, "Колонка1");
Иначе
ИмяКолонки = "Колонка" + Счетчик;
КонецЕсли;
Если ЛиВтораяСтрокаСодержитТипыЗначений Тогда
ИменаТипов = ТабличныйДокумент.Область(2, Счетчик).Текст;
Иначе
ИменаТипов = "";
КонецЕсли;
Если ЗначениеЗаполнено(ИменаТипов) Тогда
ТипизированныеКолонки[Счетчик] = 1;
КонецЕсли;
ТаблицаПриемник.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов(ИменаТипов));
КонецЦикла;
// Цикл перебора строк табличного документа
ВысотаТаблицы = ТабличныйДокумент.ВысотаТаблицы;
//Индикатор = ПолучитьИндикаторПроцессаЛкс(ТабличныйДокумент.ВысотаТаблицы);
Для НомерСтроки = НачальнаяСтрока По ВысотаТаблицы Цикл
// Добавление строки результирующей таблицы
НоваяСтрокаТЗ = ТаблицаПриемник.Добавить();
Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Область = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
ТекстЯчейки = Область.Текст;
ЗначениеЯчейки = Неопределено;
ОписаниеТиповКолонки = Неопределено;
Если ТипизированныеКолонки[НомерКолонки] <> Неопределено Тогда
ОписаниеТиповКолонки = ТаблицаПриемник.Колонки[НомерКолонки - 1].ТипЗначения;
Если ОписаниеТиповКолонки.СодержитТип(Тип("ОписаниеТипов")) Тогда
Попытка
ЗначениеЯчейки = Новый ОписаниеТипов(ТекстЯчейки);
Исключение
КонецПопытки;
ИначеЕсли ОписаниеТиповКолонки.СодержитТип(Тип("Тип")) Тогда
Попытка
ЗначениеЯчейки = Тип(ТекстЯчейки);
Исключение
КонецПопытки;
ИначеЕсли ОписаниеТиповКолонки.СодержитТип(Тип("Картинка")) Тогда
Поддокумент = ТабличныйДокумент.ПолучитьОбласть(НомерСтроки, НомерКолонки); // Тяжелая операция
Если Поддокумент.Рисунки.Количество() > 0 Тогда
ЗначениеЯчейки = Поддокумент.Рисунки[0].Картинка;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Ложь
Или ВычислятьНетипизированныеЗначения
Или (Истина
И ОписаниеТиповКолонки <> Неопределено
И ЗначениеЯчейки = Неопределено)
Тогда
Если ВычислятьНетипизированныеЗначения Или ОписаниеТиповКолонки.СодержитТип(Тип("Булево")) Тогда
Если ирОбщий.СтрокиРавныЛкс(ТекстЯчейки, "Да",, Истина) Тогда
ЗначениеЯчейки = Истина;
ИначеЕсли ирОбщий.СтрокиРавныЛкс(ТекстЯчейки, "Нет",, Истина) Тогда
ЗначениеЯчейки = Ложь;
КонецЕсли;
КонецЕсли;
Если ЗначениеЯчейки = Неопределено Тогда
Попытка
ЗначениеЯчейки = Вычислить(ТекстЯчейки);
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если ЗначениеЯчейки = Неопределено Тогда
ЗначениеЯчейки = ТекстЯчейки;
КонецЕсли;
НоваяСтрокаТЗ[НомерКолонки - 1] = ЗначениеЯчейки;
КонецЦикла;
КонецЦикла;
Возврат ТаблицаПриемник;
КонецФункции
Процедура УпроститьРасшифровкиТабличногоДокументаКомпоновкиЛкс(ТабличныйДокумент, ДанныеРасшифровки) Экспорт
#Если Сервер И Не Сервер Тогда
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
ВысотаТаблицы = ТабличныйДокумент.ВысотаТаблицы;
Для НомерСтроки = 1 По ВысотаТаблицы Цикл
Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Область = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
Если ТипЗнч(Область.Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
Для каждого ЗначениеПоля Из ДанныеРасшифровки.Элементы[Область.Расшифровка].ПолучитьПоля() Цикл
Если Не ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение, Ложь) Тогда
Продолжить;
КонецЕсли;
Область.Расшифровка = ЗначениеПоля.Значение;
Прервать;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьИдентификаторТипаЛкс(Тип) Экспорт
Результат = СтрокаМеждуМаркерамиЛкс("" + ЗначениеВСтрокуВнутр(Тип), ",", "}", Ложь);
Возврат Результат;
КонецФункции
Функция ПолучитьПеременныеТекстаВстроенногоЯзыкаЛкс(Знач ТекстПрограммы = "") Экспорт
Если ПустаяСтрока(ТекстПрограммы) Тогда
#Если Клиент Тогда
ТекстПрограммы = ПолучитьТекстИзБуфераОбменаОСЛкс();
#Иначе
ВызватьИсключение "Получение текста из буфера обмена возможно только на клиенте";
#КонецЕсли
КонецЕсли;
Параметры = Новый Структура();
ПолеВстроенногоЯзыка = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой");
#Если Сервер И Не Сервер Тогда
ПолеВстроенногоЯзыка = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать();
#КонецЕсли
ПолеВстроенногоЯзыка.ИнициализироватьНеинтерактивно();
ПолеВстроенногоЯзыка.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(,,,, Истина, ТекстПрограммы);
СтрокиЛокальныхПеременных = ПолеВстроенногоЯзыка.ТаблицаСлов.НайтиСтроки(Новый Структура("ТипСлова, Определение", "Свойство", "Статистический"));
//СтрокиЛокальныхПеременных = ПолеВстроенногоЯзыка.ТаблицаСлов.НайтиСтроки(Новый Структура("ТипСлова", "Свойство"));
Для Каждого СтрокаПеременной Из СтрокиЛокальныхПеременных Цикл
Параметры.Вставить(СтрокаПеременной.Слово);
КонецЦикла;
Возврат Параметры;
КонецФункции
// КолонкиНабора - КоллекцияКолонокДереваЗначений, КоллекцияКолонокТаблицыЗначений, КоллекцияКолонокРезультатаЗапроса
Функция СоздатьИлиОбновитьНаборДанныхОбъектПоМетаданнымЛкс(Знач СхемаИлиМакетКомпоновкиДанных, Знач КолонкиНабора, Знач ИмяНабора = "Основной", Знач СоздаватьПапкиПолей = Ложь,
СоздаватьРесурсыЧисловыхПолей = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
СхемаИлиМакетКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
Результат = СхемаИлиМакетКомпоновкиДанных.НаборыДанных.Найти(ИмяНабора);
Если Результат = Неопределено Тогда
Результат = СхемаИлиМакетКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
КонецЕсли;
Результат.Имя = ИмяНабора;
Результат.ИсточникДанных = СхемаИлиМакетКомпоновкиДанных.ИсточникиДанных[0].Имя;
Результат.ИмяОбъекта = ИмяНабора;
Для Каждого ЭлементМетаданных Из КолонкиНабора Цикл
Если Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаДереваЗначений")
Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаТаблицыЗначений")
Тогда
ИмяПоля = ЭлементМетаданных.Имя;
ЗаголовокПоля = ЭлементМетаданных.Заголовок;
ИначеЕсли Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаРезультатаЗапроса")
Тогда
ИмяПоля = ЭлементМетаданных.Имя;
ЗаголовокПоля = ИмяПоля;
ИначеЕсли Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("ПолеНастройки")
Тогда
ИмяПоля = ЭлементМетаданных.Имя;
ЗаголовокПоля = ЭлементМетаданных.Представление;
ИначеЕсли Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("ДоступноеПолеОтбораКомпоновкиДанных")
Тогда
ИмяПоля = "" + ЭлементМетаданных.Поле;
ЗаголовокПоля = ЭлементМетаданных.Заголовок;
Иначе
Продолжить;
КонецЕсли;
Поле = Результат.Поля.Найти(ИмяПоля);
Если Поле = Неопределено Тогда
Если ТипЗнч(Результат) = Тип("НаборДанныхОбъектМакетаКомпоновкиДанных") Тогда
Поле = Результат.Поля.Добавить();
Поле.Имя = ИмяПоля;
Иначе
Поле = Результат.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
Поле.Поле = ИмяПоля;
КонецЕсли;
КонецЕсли;
ПутьКДанным = ИмяПоля;
Если СоздаватьПапкиПолей Тогда
ПутьКДанным = Результат.Имя + "." + ПутьКДанным;
КонецЕсли;
Поле.ПутьКДанным = ПутьКДанным;
Если ТипЗнч(Результат) = Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Тогда
Поле.Заголовок = ЗаголовокПоля;
Поле.ТипЗначения = ЭлементМетаданных.ТипЗначения;
Если Не ирКэш.ЛиПортативныйРежимЛкс() И ЭлементМетаданных.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
Поле.ВыражениеПредставления = "ирОбщий.РасширенноеПредставлениеЗначенияЛкс(" + ИмяПоля + ")";
КонецЕсли;
Если Истина
И СоздаватьРесурсыЧисловыхПолей
И Поле.ТипЗначения.СодержитТип(Тип("Число"))
Тогда
Ресурс = СхемаИлиМакетКомпоновкиДанных.ПоляИтога.Добавить();
Ресурс.Выражение = "Сумма(" + ИмяПоля + ")";
Ресурс.ПутьКДанным = ИмяПоля;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура ЗаполнитьПараметрыСхемыПоЗапросуЛкс(Знач СхемаКомпоновкиДанных, Знач Запрос) Экспорт
#Если Сервер И Не Сервер Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
ОписанияПараметров = Запрос.НайтиПараметры(); // Здесь могут быть ложные ошибки синтаксического контроля
Для Каждого ОписаниеПараметра Из ОписанияПараметров Цикл
Если Не Запрос.Параметры.Свойство(ОписаниеПараметра.Имя) Тогда
Запрос.Параметры.Вставить(ОписаниеПараметра.Имя);
КонецЕсли;
КонецЦикла;
Для Каждого КлючИЗначение Из Запрос.Параметры Цикл
ЗначениеПараметра = КлючИЗначение.Значение;
Если ТипЗнч(ЗначениеПараметра) = Тип("Массив") Тогда
Список = Новый СписокЗначений;
Список.ЗагрузитьЗначения(ЗначениеПараметра);
ЗначениеПараметра = Список;
КонецЕсли;
ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти(КлючИЗначение.Ключ);
Если ПараметрСхемы = Неопределено Тогда
ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Добавить();
КонецЕсли;
ПараметрСхемы.Имя = КлючИЗначение.Ключ;
ПараметрСхемы.ДоступенСписокЗначений = ТипЗнч(ЗначениеПараметра) = Тип("СписокЗначений");
//Тип надо задавать, чтобы значение корректно записалось. Иначе ссылки будут преобразованы к строке.
МассивТипов = Новый Массив;
МассивТипов.Добавить(ТипЗнч(КлючИЗначение.Значение));
Если Не ПараметрСхемы.ДоступенСписокЗначений Тогда
ПараметрСхемы.ТипЗначения = Новый ОписаниеТипов(МассивТипов);
КонецЕсли;
ПараметрСхемы.Значение = ЗначениеПараметра;
КонецЦикла;
КонецПроцедуры
Функция СоздатьИлиОбновитьНаборДанныхЗапросПоЗапросуЛкс(Знач СхемаКомпоновкиДанных, Знач Запрос, Знач ИмяНабора = "Основной", Представления = Неопределено,
АвтоЗаполнениеДоступныхПолей = Истина) Экспорт
НаборДанных = ДобавитьНаборДанныхЗапросЛкс(СхемаКомпоновкиДанных.НаборыДанных, СхемаКомпоновкиДанных.ИсточникиДанных[0]);
НаборДанных.АвтоЗаполнениеДоступныхПолей = АвтоЗаполнениеДоступныхПолей;
НаборДанных.Запрос = Запрос.Текст;
Если Представления <> Неопределено Тогда
Для Каждого КлючИЗначение Из Представления Цикл
ПолеНабора = НаборДанных.Поля.Найти(КлючИЗначение.Ключ);
Если ПолеНабора = Неопределено Тогда
ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
КонецЕсли;
ПолеНабора.Поле = КлючИЗначение.Ключ;
ПолеНабора.ПутьКДанным = КлючИЗначение.Ключ;
ПолеНабора.Заголовок = КлючИЗначение.Значение;
КонецЦикла;
КонецЕсли;
ЗаполнитьПараметрыСхемыПоЗапросуЛкс(СхемаКомпоновкиДанных, Запрос);
Возврат НаборДанных;
КонецФункции
// Представления - Структура
Функция СоздатьСхемуКомпоновкиПоЗапросу(Знач ЗапросИлиТекст, ИмяНабораДанных = "Основной", Представления = Неопределено, АвтоЗаполнениеДоступныхПолей = Истина) Экспорт
СхемаКомпоновки = СоздатьСхемуКомпоновкиЛкс();
#Если Сервер И Не Сервер Тогда
СхемаКомпоновки = Новый СхемаКомпоновкиДанных;
#КонецЕсли
Если ТипЗнч(ЗапросИлиТекст) = Тип("Строка") Тогда
Запрос = Новый Запрос;
Запрос.Текст = ЗапросИлиТекст;
Иначе
Запрос = ЗапросИлиТекст;
КонецЕсли;
СоздатьИлиОбновитьНаборДанныхЗапросПоЗапросуЛкс(СхемаКомпоновки, Запрос, ИмяНабораДанных, Представления, АвтоЗаполнениеДоступныхПолей);
Возврат СхемаКомпоновки;
КонецФункции
Функция КомпоновщикПоСхемеКомпоновкиЛкс(Знач Схема) Экспорт
#Если Сервер И Не Сервер Тогда
Схема = Новый СхемаКомпоновкиДанных;
#КонецЕсли
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема);
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроек.Инициализировать(ИсточникДоступныхНастроек);
Возврат КомпоновщикНастроек;
КонецФункции
Функция ВыбратьВсеДоступныеПоляКомпоновки(Знач СхемаКомпоновки, Знач НастройкаКомпоновки = Неопределено) Экспорт
Если НастройкаКомпоновки = Неопределено Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
КонецЕсли;
КомпоновщикНастройки = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастройки.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки));
КомпоновщикНастройки.ЗагрузитьНастройки(НастройкаКомпоновки);
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
ЭлементСтруктуры = НастройкаКомпоновки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Иначе
ЭлементСтруктуры = НастройкаКомпоновки.Структура[0];
КонецЕсли;
ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
Для Каждого ДоступноеПоле Из КомпоновщикНастройки.Настройки.ДоступныеПоляВыбора.Элементы Цикл
// Чтобы пропустить системные папки
Если Не ДоступноеПоле.Папка Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ДоступноеПоле.Поле);
КонецЕсли;
КонецЦикла;
Возврат НастройкаКомпоновки;
КонецФункции
Функция ПолучитьСхемуКомпоновкиПоОбъектуМетаданныхЛкс(Знач ПолноеИмяИлиОбъектМД, ИмяНабораДанных = "Основной", ДобавитьАвтополеКоличествоСтрок = Истина,
ПсевдонимТаблицы = "Т", ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "", ИменаВместоПредставлений = Ложь) Экспорт
Если ТипЗнч(ПолноеИмяИлиОбъектМД) = Тип("Строка") Тогда
ПолноеИмяМД = ПолноеИмяИлиОбъектМД;
Иначе
ПолноеИмяМД = ПолноеИмяИлиОбъектМД.ПолноеИмя();
КонецЕсли;
ПолноеИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
Схема = ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВыражениеПараметраПериодичность, ДобавитьАвтополеКоличествоСтрок, ИндексПараметраПериодичность, ПсевдонимТаблицы,
ИменаВместоПредставлений);
Возврат Схема;
КонецФункции
Функция ПоляТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, _ВызыватьИсключениеПриОтсутствииПрав = Истина, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "") Экспорт
ТаблицаРезультата = ПустаяТаблицаЗначенийИзТаблицыБДЛкс(ПолноеИмяТаблицыБД, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность);
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Имя");
Результат.Колонки.Добавить("ТипЗначения");
Результат.Колонки.Добавить("Метаданные");
Результат.Колонки.Добавить("Заголовок");
ПоляТаблицы = ТаблицаРезультата.Колонки;
Если Не ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(ПервыйФрагментЛкс(ПолноеИмяТаблицыБД)) Тогда
ПоляТаблицы = ТаблицаСКолонкамиБезТипаNullЛкс(ТаблицаРезультата).Колонки;
КонецЕсли;
Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл
СтрокаПоля = Результат.Добавить();
СтрокаПоля.Имя = ПолеТаблицы.Имя;
СтрокаПоля.Заголовок = ПолеТаблицы.Имя;
СтрокаПоля.ТипЗначения = ПолеТаблицы.ТипЗначения;
КонецЦикла;
ТипТаблицы = ТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Если Истина
И ТипТаблицы <> "ДвиженияССубконто"
//И ТипТаблицы <> "ВиртуальнаяТаблица"
Тогда
ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, Истина);
Если ОбъектМД <> Неопределено Тогда
Если ТипТаблицы = "Внешняя" Тогда
Для Каждого ПолеТаблицы Из ОбъектМД.Поля Цикл
СтрокаПоля = Результат.Найти(ПолеТаблицы.Имя, "Имя");
Если СтрокаПоля <> Неопределено Тогда
СтрокаПоля.Метаданные = ПолеТаблицы;
Заголовок = ПолеТаблицы.Представление();
Если ЗначениеЗаполнено(Заголовок) Тогда
СтрокаПоля.Заголовок = Заголовок;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе
ПрефиксРеквизита = ОбъектМД.ПолноеИмя() + ".Реквизит.";
РодительМД = ОбъектМД.Родитель();
Если Истина
И ТипТаблицы <> "Перерасчет"
И ТипТаблицы <> "Внешняя"
И ТипЗнч(РодительМД) <> Тип("ОбъектМетаданныхКонфигурация")
Тогда
ОбъектМДФильтра = РодительМД;
Иначе
ОбъектМДФильтра = ОбъектМД;
КонецЕсли;
ФильтрМетаданных = Новый Массив;
ФильтрМетаданных.Добавить(ОбъектМДФильтра);
//Если ТипТаблицы = "ДвиженияССубконто" Тогда
// ПолноеИмяТаблицыБД = Лев(ПолноеИмяТаблицыБД, СтрДлина(ПолноеИмяТаблицыБД) - СТрДлина(".ДвиженияССубконто"));
//КонецЕсли;
НуженПеревод = Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский;
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803016 Тогда
СтруктураХраненияБД = ирКэш.СтруктураХраненияБДЛкс(, Ложь);
ирОбщий.ДобавитьИндексВТаблицуЛкс(СтруктураХраненияБД, "ИмяТаблицы");
Иначе
// https://partners.v8.1c.ru/forum/topic/1751092
// https://bugboard.v8.1c.ru/error/000046221.html
// В этих версиях платформы будут компилироваться модули менеджеров. Поэтому получаем структуру хранения узко
СтруктураХраненияБД = ПолучитьСтруктуруХраненияБазыДанных(ФильтрМетаданных);
ПеревестиКолонкиСтруктурыХраненияБДТаблицыЛкс(СтруктураХраненияБД, НуженПеревод);
КонецЕсли;
СтрокиСтруктурыТаблицы = СтруктураХраненияБД.НайтиСтроки(Новый Структура("ИмяТаблицы", ПолноеИмяТаблицыБД));
Если Истина
И СтрокиСтруктурыТаблицы.Количество() = 0
И ТипТаблицы = "ВиртуальнаяТаблица"
Тогда
СтрокиСтруктурыТаблицы = СтруктураХраненияБД.НайтиСтроки(Новый Структура("Назначение", "Основная"));
КонецЕсли;
Если СтрокиСтруктурыТаблицы.Количество() = 0 Тогда
Если Истина
И ТипТаблицы <> "Изменения"
И ТипТаблицы <> "Константа"
//И ТипТаблицы <> "Границы"
//И ТипТаблицы <> "ЗадачиПоИсполнителю"
Тогда
СообщитьЛкс("Не удалось найти в структуре хранения БД описание таблицы " + ПолноеИмяТаблицыБД);
Иначе
// Для отладки
// Сюда попадаем для констант, у которых у таблицы изменений имя ошибочно указано то же, что и у основной таблицы.
// Сюда попадаем для границ последовательностей, у которых ошибочно пустое имя таблицы.
Пустышка = 1;
КонецЕсли;
Иначе
Если СтрокиСтруктурыТаблицы.Количество() > 1 Тогда
Пустышка = 1; // Для отладки. Сюда попадаем для констант, у которых у таблицы изменений имя ошибочно указано то же, что и у основной таблицы
КонецЕсли;
ТаблицаПолей = СтрокиСтруктурыТаблицы[0].Поля;
Если НуженПеревод Тогда
ПеревестиКолонкиСтруктурыХраненияБДПоляЛкс(ТаблицаПолей, НуженПеревод);
КонецЕсли;
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Для Каждого ПолеТаблицы Из ТаблицаПолей Цикл
Если Истина
И ЗначениеЗаполнено(ПолеТаблицы.Метаданные)
И (Ложь
Или ПолеТаблицы.ИмяПоля <> "НомерСтроки"
Или Найти(ПолеТаблицы.Метаданные, ".ТабличнаяЧасть.") = 0)
Тогда
СтрокаПоля = Результат.Найти(ПолеТаблицы.ИмяПоля, "Имя");
Если СтрокаПоля <> Неопределено Тогда
Если Найти(ПолеТаблицы.Метаданные, ПрефиксРеквизита) = 1 Тогда
// Для ускорения
СтрокаПоля.Метаданные = ОбъектМД.Реквизиты[ПоследнийФрагментЛкс(ПолеТаблицы.Метаданные)];
Иначе
СтрокаПоля.Метаданные = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолеТаблицы.Метаданные);
КонецЕсли;
Заголовок = СтрокаПоля.Метаданные.Представление();
Если ЗначениеЗаполнено(Заголовок) Тогда
СтрокаПоля.Заголовок = Заголовок;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Каждого ПолеТаблицы Из ТаблицаПолей Цикл Если Истина И ЗначениеЗаполнено(ПолеТаблицы.Метаданные) И (Ложь Или ПолеТаблицы.ИмяПоля <> "НомерСтроки" Или Найти(ПолеТаблицы.Метаданные, ".ТабличнаяЧасть.") = 0) Тогда СтрокаПоля = Результат.Найти(ПолеТаблицы.ИмяПоля, "Имя"); Если СтрокаПоля <> Неопределено Тогда Если Найти(ПолеТаблицы.Метаданные, ПрефиксРеквизита) = 1 Тогда СтрокаПоля.Метаданные = ОбъектМД.Реквизиты[ПоследнийФрагментЛкс(ПолеТаблицы.Метаданные)]; Иначе СтрокаПоля.Метаданные = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолеТаблицы.Метаданные); КонецЕсли; Заголовок = СтрокаПоля.Метаданные.Представление(); Если ЗначениеЗаполнено(Заголовок) Тогда СтрокаПоля.Заголовок = Заголовок; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПустаяТаблицаЗначенийИзТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, Знач ИндексПараметраПериодичность = Неопределено, Знач ВыражениеПараметраПериодичность = "") Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ТекстЗапроса = ПолучитьТекстЗапросаПолейТаблицыБДЛкс(ПолноеИмяТаблицыБД, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность);
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803005 Тогда
// Этот способ в 4 раза быстрее
Схема = Вычислить("Новый СхемаЗапроса");
#Если Сервер И Не Сервер Тогда
Схема = Новый СхемаЗапроса;
#КонецЕсли
Попытка
Схема.УстановитьТекстЗапроса(ТекстЗапроса);
Исключение
СообщитьЛкс(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке().Причина));
//Возврат Неопределено;
КонецПопытки;
ТаблицаРезультата = Новый ТаблицаЗначений;
Для Каждого КолонкаСхемы Из Схема.ПакетЗапросов[0].Колонки Цикл
Если ТипЗнч(КолонкаСхемы) = Тип("КолонкаВложеннаяТаблицаСхемыЗапроса") Тогда
ТипЗначения = Новый ОписаниеТипов("ТаблицаЗначений");
Иначе
ТипЗначения = КолонкаСхемы.ТипЗначения;
КонецЕсли;
ТаблицаРезультата.Колонки.Добавить(КолонкаСхемы.Псевдоним, ТипЗначения);
КонецЦикла;
Иначе
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса + " ГДЕ ЛОЖЬ";
Попытка
ТаблицаРезультата = Запрос.Выполнить().Выгрузить();
Исключение
// Долгий способ пробуем только если быстрый не удался
ПостроительЗапроса = Новый ПостроительЗапроса;
Попытка
ПостроительЗапроса.Текст = Запрос.Текст;
ПостроительЗапроса.ЗаполнитьНастройки();
Исключение
//Если ВызыватьИсключениеПриОтсутствииПрав Тогда
// ВызватьИсключение;
//КонецЕсли;
СообщитьЛкс(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке().Причина));
//Возврат Неопределено;
КонецПопытки;
ТаблицаРезультата = Новый ТаблицаЗначений;
Для Каждого ДоступноеПоле Из ПостроительЗапроса.ДоступныеПоля Цикл
ТаблицаРезультата.Колонки.Добавить(ДоступноеПоле.ПутьКДанным, ДоступноеПоле.ТипЗначения);
КонецЦикла;
КонецПопытки;
КонецЕсли;
Возврат ТаблицаРезультата;
КонецФункции
Функция ПроверитьПропуститьНедоступнуюТаблицуБДЛкс(Знач ОписаниеТаблицы) Экспорт
Пропустить = Ложь;
Если Не ОписаниеТаблицы.ЕстьДоступ Тогда
ирОбщий.СообщитьЛкс("Пропускаем недоступную таблицу БД """ + ОписаниеТаблицы.ПолноеИмя + """", СтатусСообщения.Внимание);
Пропустить = Истина;
КонецЕсли;
Возврат Пропустить;
КонецФункции
Функция ТаблицаВсехТаблицБДБезОжиданияЛкс() Экспорт
СостояниеРасчета = ирКэш.СостояниеПодготовкиТаблицыВсехТаблицБДЛкс();
Если СостояниеРасчета <> Неопределено Тогда
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(СостояниеРасчета.ИдентификаторЗадания);
КонецЕсли;
Если ФоновоеЗадание <> Неопределено Тогда
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Активно Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Результат = ирКэш.ТаблицаВсехТаблицБДЛкс();
Возврат Результат;
КонецФункции
Процедура ТаблицаВсехТаблицБДВФонеЛкс(АдресВременногоХранилища) Экспорт
ПоместитьВоВременноеХранилище(ирКэш.ТаблицаВсехТаблицБДЛкс(), АдресВременногоХранилища);
КонецПроцедуры
// Параметры:
// НужныПредставления - Булево - для стандартных полей будут заполняться представления (дольше)
Функция ПоляТаблицыМДЛкс(ПолноеИмяИлиОбъектМД, _ВызыватьИсключениеПриОтсутствииПрав = Истина, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "",
НужныПредставления = Истина) Экспорт
Если ТипЗнч(ПолноеИмяИлиОбъектМД) = Тип("ОбъектМетаданных") Тогда
ПолноеИмяМД = ПолноеИмяИлиОбъектМД.ПолноеИмя();
Иначе
ПолноеИмяМД = ПолноеИмяИлиОбъектМД;
КонецЕсли;
ПолноеИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
ПоляТаблицы = ирКэш.ПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД, _ВызыватьИсключениеПриОтсутствииПрав, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность);
Если НужныПредставления Тогда
КомпоновщикТаблицы = ирКэш.КомпоновщикТаблицыМетаданныхЛкс(ПолноеИмяМД);
#Если Сервер И Не Сервер Тогда
КомпоновщикТаблицы = Новый КомпоновщикНастроекКомпоновкиДанных;
#КонецЕсли
Для Каждого ДоступноеПоле Из КомпоновщикТаблицы.Настройки.ДоступныеПоляВыбора.Элементы Цикл
Если Истина
И Найти("" + ДоступноеПоле.Заголовок, " ") < 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
//Тогда
// Если ТипТаблицы = "РегистрБухгалтерии" Тогда
// Если ИмяВиртуальнойТаблицы = "" Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Регистратор", "Регистратор");
// ИначеЕсли ИмяВиртуальнойТаблицы = "ДвиженияССубконто" Тогда
// ЭлементСтруктуры.ПоляГруппировки.Элементы.Удалить(ПолеГруппировки);
// // Группировки по забалансовым
// Для каждого Измерение Из ОбъектМД.Измерения Цикл
// Если Измерение.Балансовый Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, Измерение.Имя, Измерение.Синоним);
// КонецЕсли
// КонецЦикла;
// // ИзмеренияДт
// Для каждого Измерение Из ОбъектМД.Измерения Цикл
// Если НЕ Измерение.Балансовый Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, Измерение.Имя + "Дт", Измерение.Синоним + " Дт");
// КонецЕсли
// КонецЦикла;
// Для К = 1 По 3 Цикл
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СубконтоДт" + К, "СубконтоДт" + К);
// КонецЦикла;
// // ИзмеренияКт
// Для каждого Измерение Из ОбъектМД.Измерения Цикл
// Если НЕ Измерение.Балансовый Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, Измерение.Имя + "Кт", Измерение.Синоним + " Кт");
// КонецЕсли
// КонецЦикла;
// Для К = 1 По 3 Цикл
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СубконтоКт" + К, "СубконтоКт" + К);
// КонецЦикла;
// Иначе
// Если ЭлементСтруктуры.ПоляГруппировки.ДоступныеПоляПолейГруппировок.Элементы.Найти("Счет")<> Неопределено Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Счет", "Счет");
// Иначе
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СчетДт", "СчетДт");
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СчетКт", "СчетКт");
// КонецЕсли;
// КонецЕсли;
// Иначе
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка,
// ОбъектМД.Измерения[0].Имя,
// ОбъектМД.Измерения[0].Синоним);
// КонецЕсли
//КонецЕсли;
ЭлементПорядка = ЭлементСтруктуры.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
КонецПроцедуры
Функция ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВыражениеПараметраПериодичность = Неопределено, ДобавитьАвтополеКоличествоСтрок = Истина,
Знач ИндексПараметраПериодичность = Неопределено, Знач ПсевдонимТаблицы = "Т", ИменаВместоПредставлений = Ложь, РасширенноеЗаполнение = Ложь, КоличествоПервых = 0) Экспорт
СхемаКомпоновки = СоздатьСхемуКомпоновкиЛкс();
#Если Сервер И Не Сервер Тогда
СхемаКомпоновки = Новый СхемаКомпоновкиДанных;
#КонецЕсли
НаборДанных = ДобавитьНаборДанныхЗапросЛкс(СхемаКомпоновки.НаборыДанных, СхемаКомпоновки.ИсточникиДанных[0]);
#Если Сервер И Не Сервер Тогда
НаборДанных = СхемаКомпоновки.НаборыДанных.Добавить();
#КонецЕсли
НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина;
НаборДанных.Запрос = ПолучитьТекстЗапросаПолейТаблицыБДЛкс(ПолноеИмяТаблицыБД, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность, ПсевдонимТаблицы, Ложь, КоличествоПервых);
Если ДобавитьАвтополеКоличествоСтрок Тогда
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновки);
КонецЕсли;
Если Ложь
Или ИменаВместоПредставлений
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_1 // Антибаг платформы в режиме совместимости. Предопределенные реквизиты имеют англ. имена полей
Тогда
Построитель = Новый ПостроительЗапроса(НаборДанных.Запрос);
Построитель.ЗаполнитьНастройки();
Для Каждого ДоступноеПоле Из Построитель.ДоступныеПоля Цикл
ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНабора.Поле = ДоступноеПоле.ПутьКДанным;
//ПолеНабора.ПутьКДанным = ДоступноеПоле.ПутьКДанным;
Если ИменаВместоПредставлений Тогда
ПолеНабора.Заголовок = ДоступноеПоле.Имя;
Иначе
ПолеНабора.Заголовок = ДоступноеПоле.Представление;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если РасширенноеЗаполнение Тогда
ДобавитьПоляНабораДанныхЛкс(ПолноеИмяТаблицыБД, СхемаКомпоновки);
ЗаполнитьСтруктуруКомпоновкиПоУмолчаниюПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, СхемаКомпоновки.НастройкиПоУмолчанию);
ДобавитьВыбранныеПоляКомпоновкиПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, СхемаКомпоновки.НастройкиПоУмолчанию);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "Title", Метаданные[Отчет.ТипДанных][Отчет.ИмяОбъекта].Синоним);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "TitleOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "FilterOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "DataParametersOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить);
КонецЕсли;
Возврат СхемаКомпоновки;
КонецФункции
Функция ПолучитьТекстЗапросаПолейТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, Знач ИндексПараметраПериодичность = Неопределено, Знач ВыражениеПараметраПериодичность = Неопределено, ПсевдонимТаблицы = "Т",
Знач БлокироватьПолучениеДанных = Истина, КоличествоПервых = 0, ИменаВыбранныхПолей = Неопределено) Экспорт
ТипТаблицы = ПервыйФрагментЛкс(ПолноеИмяТаблицыБД);
// Оптимизация. Первые 2 ветки предотвращают вызов тяжелой функции ОписаниеТаблицыБДЛкс, но не являются логически необходимыми
Если СтрЧислоВхождений(ПолноеИмяТаблицыБД, ".") = 1 Тогда
Если ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяТаблицыБД) <> Неопределено Тогда
ОписаниеТаблицы = Новый Структура("ИндексПараметраОтбора");
КонецЕсли;
ИначеЕсли СтрокиРавныЛкс(ПолноеИмяТаблицыБД, "Константы") Тогда
ОписаниеТаблицы = Новый Структура("ИндексПараметраОтбора");
Иначе
ОписаниеТаблицы = ОписаниеТаблицыБДЛкс(ПолноеИмяТаблицыБД);
КонецЕсли;
Если ОписаниеТаблицы = Неопределено Тогда
ВызватьИсключение "Таблица БД с именем " + ПолноеИмяТаблицыБД + " не найдена";
КонецЕсли;
ПараметрыВиртуальнойТаблицы = "";
Если БлокироватьПолучениеДанных И ОписаниеТаблицы <> Неопределено Тогда
ИндексПараметраОтбора = ОписаниеТаблицы.ИндексПараметраОтбора;
Иначе
ИндексПараметраОтбора = Неопределено;
КонецЕсли;
МаксимальныйИндекс = ИндексПараметраОтбора;
Если ИндексПараметраПериодичность <> Неопределено Тогда
Если МаксимальныйИндекс <> Неопределено Тогда
МаксимальныйИндекс = Макс(МаксимальныйИндекс, ИндексПараметраПериодичность);
Иначе
МаксимальныйИндекс = ИндексПараметраПериодичность;
КонецЕсли;
КонецЕсли;
Если МаксимальныйИндекс <> Неопределено Тогда
МассивВыраженийПараметров = Новый Массив;
Для Счетчик = 0 По МаксимальныйИндекс Цикл
МассивВыраженийПараметров.Добавить("");
КонецЦикла;
Если ИндексПараметраОтбора <> Неопределено Тогда
МассивВыраженийПараметров[ИндексПараметраОтбора] = "ЛОЖЬ";
КонецЕсли;
Если ИндексПараметраПериодичность <> Неопределено Тогда
МассивВыраженийПараметров[ИндексПараметраПериодичность] = ВыражениеПараметраПериодичность;
КонецЕсли;
ПараметрыВиртуальнойТаблицы = ирОбщий.СтрСоединитьЛкс(МассивВыраженийПараметров);
КонецЕсли;
Если ЗначениеЗаполнено(ПараметрыВиртуальнойТаблицы) Тогда
ПолноеИмяТаблицыБД = ПолноеИмяТаблицыБД + "(" + ПараметрыВиртуальнойТаблицы + ")";
КонецЕсли;
Если Не ЗначениеЗаполнено(ПсевдонимТаблицы) Тогда
ПсевдонимТаблицы = "Т";
КонецЕсли;
ТекстЗапроса = "ВЫБРАТЬ ";
Если ЗначениеЗаполнено(КоличествоПервых) Тогда
ТекстЗапроса = ТекстЗапроса + "ПЕРВЫЕ " + XMLСтрока(КоличествоПервых) + " ";
КонецЕсли;
Если ИменаВыбранныхПолей <> Неопределено Тогда
ВыраженияПолей = Новый Массив;
Для Каждого ИмяПоля Из ИменаВыбранныхПолей Цикл
ВыраженияПолей.Добавить(ПсевдонимТаблицы + "." + ИмяПоля);
КонецЦикла;
ТекстВыбораПолей = СтрСоединитьЛкс(ВыраженияПолей, ", ");
Иначе
ТекстВыбораПолей = ПсевдонимТаблицы + ".*";
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + ТекстВыбораПолей + " ИЗ " + ПолноеИмяТаблицыБД + " КАК " + ПсевдонимТаблицы;
Возврат ТекстЗапроса;
КонецФункции
Функция ДобавитьДоступнуюТаблицуБДЛкс(ДоступныеТаблицыБД, ПолноеИмя, ПолноеИмяМД = "", ТипТаблицы = "", Имя = "", Представление = "", СхемаТаблицы = "", ПроверятьУникальность = Ложь,
ОбъектМД = Неопределено, ИндексПараметраОтбора = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(ПолноеИмя) Тогда
ПолноеИмя = ПолноеИмяМД;
КонецЕсли;
Фрагменты = ирОбщий.СтрРазделитьЛкс(ПолноеИмя);
Если Фрагменты.Количество() > 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;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции
Функция НайтиДобавитьЭлементНастроекКомпоновкиПоПредставлениюЛкс(Знач ЭлементыНастройки, Знач Представление = "", Знач ПроверятьУникальность = Истина,
Знач ИспользованиеДляНового = Истина) Экспорт
Попытка
ЭлементыНастройки = ЭлементыНастройки.Элементы;
Исключение
КонецПопытки;
Если ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовОтбораКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ЭлементОтбораКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда
ТипЭлемента = Неопределено;
КонецЕсли;
Если ПроверятьУникальность Тогда
ЭлементНастроек = НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(ЭлементыНастройки, "Представление", Представление, ТипЭлемента);
КонецЕсли;
Если ЭлементНастроек = Неопределено Тогда
Если ТипЭлемента <> Неопределено Тогда
ЭлементНастроек = ЭлементыНастройки.Добавить(ТипЭлемента);
Иначе
ЭлементНастроек = ЭлементыНастройки.Добавить();
КонецЕсли;
ЭлементНастроек.Представление = Представление;
ЭлементНастроек.Использование = ИспользованиеДляНового;
КонецЕсли;
Возврат ЭлементНастроек;
КонецФункции
// Параметры:
// ЭлементыНастройки - ТабличноеПоле, ЭлементыНастроек
Функция НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(Знач ЭлементыНастройки, Знач Поле = "", Знач ПроверятьУникальность = Истина,
Знач ИспользованиеДляНового = Истина, выхСтандартнаяОбработка = Истина) Экспорт
ТабличноеПоле = Неопределено;
#Если Клиент Тогда
Если ТипЗнч(ЭлементыНастройки) = Тип("ТабличноеПоле") Тогда
ТабличноеПоле = ЭлементыНастройки;
ЭлементыНастройки = ТабличноеПоле.Значение;
КонецЕсли;
#КонецЕсли
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
Попытка
ЭлементыНастройки = ЭлементыНастройки.Элементы;
Исключение
КонецПопытки;
ТипЭлемента = ТипЭлементаИзТипаКоллекцииКомпоновкиЛкс(ЭлементыНастройки);
Если ПроверятьУникальность Тогда
ЭлементНастроек = НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементыНастройки, Поле,, ТипЭлемента);
КонецЕсли;
Если ЭлементНастроек = Неопределено Тогда
Если ТипЭлемента <> Неопределено Тогда
ЭлементНастроек = ЭлементыНастройки.Добавить(ТипЭлемента);
Иначе
ЭлементНастроек = ЭлементыНастройки.Добавить();
КонецЕсли;
ЭлементНастроек.Поле = Поле;
ЭлементНастроек.Использование = ИспользованиеДляНового;
КонецЕсли;
Если ТабличноеПоле <> Неопределено Тогда
ТабличноеПоле.ТекущаяСтрока = ЭлементНастроек;
выхСтандартнаяОбработка = Ложь;
КонецЕсли;
Возврат ЭлементНастроек;
КонецФункции
Функция ТипЭлементаИзТипаКоллекцииКомпоновкиЛкс(ЭлементыНастройки) Экспорт
Если ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовПорядкаКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ЭлементПорядкаКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияВыбранныхПолейКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ВыбранноеПолеКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияПолейГруппировкиКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ПолеГруппировкиКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда
ТипЭлемента = Неопределено;
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовОтбораКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ЭлементОтбораКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("ОформляемыеПоляКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ОформляемоеПолеКомпоновкиДанных");
КонецЕсли;
Возврат ТипЭлемента;
КонецФункции
// Параметры:
// Поле - ПолеКомпоновкиДанных, Строка - если не заполнено, то подходит любое имя поля
// ВсеНайденныеПоля - Массив - если Массив, то находим все поля
Функция НайтиЭлементНастроекКомпоновкиПоПолюЛкс(Знач ЭлементыНастройки, Знач Поле = Неопределено, Знач ТолькоВключенный = Ложь, ТипЭлементаРекурсия = Неопределено, ВсеНайденныеПоля = Неопределено) Экспорт
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
Если ТипЭлементаРекурсия = Неопределено Тогда
ТипЭлементаРекурсия = ТипЭлементаИзТипаКоллекцииКомпоновкиЛкс(ЭлементыНастройки);
КонецЕсли;
//ИскомоеПолеЗаполнено = ЗначениеЗаполнено(Поле); // Не поддерживается в 8.2 http://www.hostedredmine.com/issues/878299
ИскомоеПолеЗаполнено = ЗначениеЗаполнено("" + Поле);
Для Каждого ЭлементНастроек Из ЭлементыНастройки Цикл
Если Истина
И ТипЭлементаРекурсия <> Неопределено
И ТипЗнч(ЭлементНастроек) <> ТипЭлементаРекурсия
Тогда
Попытка
ДочерниеЭлементыНастройки = ЭлементНастроек.Элементы;
Исключение
ДочерниеЭлементыНастройки = Неопределено;
КонецПопытки;
Если ДочерниеЭлементыНастройки <> Неопределено Тогда
НайденныйЭлемент = НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ДочерниеЭлементыНастройки, Поле, ТолькоВключенный, ТипЭлементаРекурсия, ВсеНайденныеПоля);
Если НайденныйЭлемент <> Неопределено Тогда
Если ВсеНайденныеПоля <> Неопределено Тогда
ВсеНайденныеПоля.Добавить(НайденныйЭлемент);
Иначе
Прервать;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Если ТипЭлементаРекурсия = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
ПолеЭлемента = ЭлементНастроек.ЛевоеЗначение;
Иначе
ПолеЭлемента = ЭлементНастроек.Поле;
КонецЕсли;
Если Истина
И (Ложь
Или ПолеЭлемента = Поле
Или Не ИскомоеПолеЗаполнено)
И (Ложь
Или Не ТолькоВключенный
Или ЭлементНастроек.Использование)
Тогда
НайденныйЭлемент = ЭлементНастроек;
Если ВсеНайденныеПоля <> Неопределено Тогда
ВсеНайденныеПоля.Добавить(НайденныйЭлемент);
Иначе
Прервать;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ВсеНайденныеПоля <> Неопределено И ВсеНайденныеПоля.Количество() > 0 Тогда
НайденныйЭлемент = ВсеНайденныеПоля[0];
КонецЕсли;
Возврат НайденныйЭлемент;
КонецФункции
Функция НайтиЭлементУсловногоОформленияПоПолюЛкс(Знач УсловноеОформление, Знач Поле, Знач ТолькоВключенный = Ложь, выхЭлементПоля = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
УсловноеОформление = Новый НастройкиКомпоновкиДанных;
УсловноеОформление = УсловноеОформление.УсловноеОформление;
#КонецЕсли
Для Каждого ЭлементОформления Из УсловноеОформление.Элементы Цикл
ЭлементПоля = ирОбщий.НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементОформления.Поля.Элементы, Поле, ТолькоВключенный);
Если ЭлементПоля <> Неопределено Тогда
выхЭлементПоля = ЭлементПоля;
Возврат ЭлементОформления;
КонецЕсли;
ЭлементОтбора = ирОбщий.НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементОформления.Отбор.Элементы, Поле, ТолькоВключенный);
Если ЭлементОтбора <> Неопределено Тогда
выхЭлементПоля = ЭлементОтбора;
Возврат ЭлементОформления;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Функция НайтиЭлементНастроекКомпоновкиПоПолюПоВсейСтруктуреЛкс(Знач КорневойЭлементСтруктуры, Знач Поле, Знач ТолькоВключенный = Ложь, Знач ТипНастроек = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
КорневойЭлементСтруктуры = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
ВсеГруппировки = ВсеГруппировкиКомпоновкиЛкс(КорневойЭлементСтруктуры.Структура);
ВсеГруппировки.Добавить(КорневойЭлементСтруктуры);
Результат = Новый Структура("ЭлементСтруктуры, ЭлементНастройки, ЭлементНастройки2");
Для Каждого ЭлементСтруктуры Из ВсеГруппировки Цикл
ПолеНайдено = Ложь;
Если Истина
И Не ПолеНайдено
И ТипЗнч(ЭлементСтруктуры) <> Тип("НастройкиКомпоновкиДанных")
И (Ложь
Или ТипНастроек = Неопределено
Или ТипНастроек = Тип("ПолеГруппировкиКомпоновкиДанных"))
Тогда
ПолеГруппировки = ирОбщий.НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементСтруктуры.ПоляГруппировки.Элементы, Поле, ТолькоВключенный);
Если ПолеГруппировки <> Неопределено Тогда
Результат.ЭлементСтруктуры = ЭлементСтруктуры;
Результат.ЭлементНастройки = ПолеГруппировки;
Возврат Результат;
КонецЕсли;
КонецЕсли;
Если Истина
И Не ПолеНайдено
И (Ложь
Или ТипНастроек = Неопределено
Или ТипНастроек = Тип("ВыбранныеПоляКомпоновкиДанных"))
Тогда
ВыбранноеПоле = ирОбщий.НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементСтруктуры.Выбор.Элементы, Поле, ТолькоВключенный);
Если ВыбранноеПоле <> Неопределено Тогда
Результат.ЭлементСтруктуры = ЭлементСтруктуры;
Результат.ЭлементНастройки = ВыбранноеПоле;
Возврат Результат;
КонецЕсли;
КонецЕсли;
Если Истина
И Не ПолеНайдено
И (Ложь
Или ТипНастроек = Неопределено
Или ТипНастроек = Тип("ПорядокКомпоновкиДанных"))
Тогда
ЭлементПорядка = ирОбщий.НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементСтруктуры.Порядок.Элементы, Поле, ТолькоВключенный);
Если ЭлементПорядка <> Неопределено Тогда
Результат.ЭлементСтруктуры = ЭлементСтруктуры;
Результат.ЭлементНастройки = ЭлементПорядка;
Возврат Результат;
КонецЕсли;
КонецЕсли;
Если Истина
И Не ПолеНайдено
И (Ложь
Или ТипНастроек = Неопределено
Или ТипНастроек = Тип("ОтборКомпоновкиДанных"))
Тогда
ЭлементОтбора = ирОбщий.НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементСтруктуры.Отбор.Элементы, Поле, ТолькоВключенный);
Если ЭлементОтбора <> Неопределено Тогда
Результат.ЭлементСтруктуры = ЭлементСтруктуры;
Результат.ЭлементНастройки = ЭлементОтбора;
Возврат Результат;
КонецЕсли;
КонецЕсли;
Если Истина
И Не ПолеНайдено
И (Ложь
Или ТипНастроек = Неопределено
Или ТипНастроек = Тип("УсловноеОформлениеКомпоновкиДанных"))
Тогда
ЭлементПоля = Неопределено;
ЭлементОФормления = ирОбщий.НайтиЭлементУсловногоОформленияПоПолюЛкс(ЭлементСтруктуры.УсловноеОформление, Поле, ТолькоВключенный, ЭлементПоля);
Если ЭлементОФормления <> Неопределено Тогда
Результат.ЭлементСтруктуры = ЭлементСтруктуры;
Результат.ЭлементНастройки = ЭлементОФормления;
Результат.ЭлементНастройки2 = ЭлементПоля;
Возврат Результат;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Функция ВсеГруппировкиКомпоновкиЛкс(Группировки, Знач ТолькоВключенный = Ложь, МассивЭлементов = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Группировки = Новый НастройкиКомпоновкиДанных;
Группировки = Группировки.Структура;
#КонецЕсли
Если МассивЭлементов = Неопределено Тогда
МассивЭлементов = Новый Массив;
КонецЕсли;
Для Каждого Группировка Из Группировки Цикл
ТипЭлемента = Тип(Группировка);
Если Ложь
Или ТипЭлемента = Тип("ГруппировкаДиаграммыКомпоновкиДанных")
Или ТипЭлемента = Тип("ГруппировкаКомпоновкиДанных")
Или ТипЭлемента = Тип("ГруппировкаТаблицыКомпоновкиДанных")
Тогда
ВсеГруппировкиКомпоновкиЛкс(Группировка.Структура, ТолькоВключенный, МассивЭлементов);
Если Ложь
Или ТолькоВключенный
Или Группировка.Использование
Тогда
МассивЭлементов.Добавить(Группировка);
КонецЕсли;
ИначеЕсли ТипЭлемента = Тип("ТаблицаКомпоновкиДанных") Тогда
ВсеГруппировкиКомпоновкиЛкс(Группировка.Строки, ТолькоВключенный, МассивЭлементов);
ВсеГруппировкиКомпоновкиЛкс(Группировка.Колонки, ТолькоВключенный, МассивЭлементов);
Иначе
Продолжить;
КонецЕсли;
КонецЦикла;
Возврат МассивЭлементов;
КонецФункции
// Параметры:
// ВыбранныеПоля - -
// ТолькоВключенные - -
// МассивРезультата - -
// ВернутьТолькоПоля - Булево - вместо выбранных полей вернуть поля
//
// Возвращаемое значение:
// -
//
Функция ВсеВыбранныеПоляГруппировкиКомпоновкиЛкс(Знач ВыбранныеПоля, Знач ТолькоВключенные = Ложь, МассивРезультата = Неопределено, ВернутьТолькоПоля = Ложь) Экспорт
Если МассивРезультата <> Неопределено Тогда
Результат = МассивРезультата;
Иначе
Результат = Новый Массив();
КонецЕсли;
Для Каждого ВыбранноеПоле Из ВыбранныеПоля.Элементы Цикл
Если ТипЗнч(ВыбранноеПоле) = Тип("ГруппаВыбранныхПолейКомпоновкиДанных") Тогда
РезультатВложенный = ВсеВыбранныеПоляГруппировкиКомпоновкиЛкс(ВыбранноеПоле, ТолькоВключенные, Результат, ВернутьТолькоПоля);
ИначеЕсли ТипЗнч(ВыбранноеПоле) = Тип("АвтоВыбранноеПолеКомпоновкиДанных") Тогда
Пустышка = 0;
Иначе
Если Ложь
Или Не ТолькоВключенные
Или ВыбранноеПоле.Использование
Тогда
Если ВернутьТолькоПоля Тогда
Результат.Добавить(ВыбранноеПоле.Поле);
Иначе
Результат.Добавить(ВыбранноеПоле);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ПолеИзОписанияОшибкиЛкс(ОписаниеОшибки) Экспорт
// {Обработка.ирКонсольКомпоновокДанных.Форма.Форма.Форма(503)}: Ошибка при вызове метода контекста (Выполнить): Ошибка компоновки макета: Поле не найдено "НомерВерсииПлатформы"
Результат = СтрокаМеждуМаркерамиЛкс(ОписаниеОшибки, "Поле не найдено """, """", Ложь);
Возврат Результат;
КонецФункции
Функция НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(Знач Группировки, Знач Поле = "", Добавлять = Истина, НовоеИспользование = Истина) Экспорт
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
Группировка = НайтиГруппировкуКомпоновкиПоПолюЛкс(Группировки, Поле);
ЭлементСуществует = Группировка <> Неопределено;
Если Истина
И Не ЭлементСуществует
И Добавлять
Тогда
Если ТипЗнч(Группировки) = Тип("КоллекцияЭлементовСтруктурыНастроекКомпоновкиДанных") Тогда
Группировка = Группировки.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Иначе
Группировка = Группировки.Добавить();
КонецЕсли;
Группировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
Группировка.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
Если "" + Поле <> "" Тогда
ПолеГруппировки = Группировка.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
ПолеГруппировки.Поле = Поле;
КонецЕсли;
ЭлементСуществует = Истина;
КонецЕсли;
Если ЭлементСуществует Тогда
Если НовоеИспользование <> Неопределено Тогда
Группировка.Использование = НовоеИспользование;
КонецЕсли;
Результат = Группировка;
Иначе
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НайтиГруппировкуКомпоновкиПоПолюЛкс(Знач Группировки, Знач Поле) Экспорт
ГруппировкаПоИскомомуПолю = Неопределено;
Для Каждого Группировка Из Группировки Цикл
Поля = Группировка.ПоляГруппировки.Элементы;
Если Ложь
Или (Истина
И "" + Поле = ""
И Поля.Количество() = 0)
Или (Истина
И Поля.Количество() = 1
И ТипЗнч(Поля[0]) = Тип("ПолеГруппировкиКомпоновкиДанных")
И Поля[0].Поле = Поле)
Тогда
ГруппировкаПоИскомомуПолю = Группировка;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат ГруппировкаПоИскомомуПолю;
КонецФункции
// Функция - Найти элемент отбора компоновки лкс
//
// Параметры:
// Отбор - -
// ИменаПолей - -
// НайденныеЭлементы - Соответствие* -
// ТолькоВключенныеНаРавенствоЗначению - -
// ВключатьПодчиненные - -
//
// Возвращаемое значение:
// -
//
Функция НайтиЭлементОтбораКомпоновкиЛкс(Знач Отбор, Знач ИменаПолей = Неопределено, Знач НайденныеЭлементы = Неопределено, Знач ТолькоВключенныеНаРавенствоЗначению = Ложь,
Знач ВключатьПодчиненные = Ложь, Знач МассивПолейРекурсия = Неопределено) Экспорт
Если ТипЗнч(Отбор) = Тип("ОтборКомпоновкиДанных") Тогда
ЭлементыОтбора = Отбор.Элементы;
Иначе
ЭлементыОтбора = Отбор;
КонецЕсли;
Если МассивПолейРекурсия = Неопределено Тогда
Если ТипЗнч(ИменаПолей) = Тип("Строка") Тогда
МассивИменПолей = СтрРазделитьЛкс(ИменаПолей, ",", Истина);
Иначе
МассивИменПолей = ИменаПолей;
КонецЕсли;
МассивПолейРекурсия = Новый Массив;
Если МассивИменПолей <> Неопределено Тогда
Для Каждого ИмяПоля Из МассивИменПолей Цикл
МассивПолейРекурсия.Добавить(Новый ПолеКомпоновкиДанных(ИмяПоля));
КонецЦикла;
КонецЕсли;
КонецЕсли;
МассивПолейПуст = МассивПолейРекурсия.Количество() = 0;
Если НайденныеЭлементы = Неопределено Тогда
НайденныеЭлементы = Новый Соответствие;
КонецЕсли;
Для Каждого ЭлементОтбора ИЗ ЭлементыОтбора Цикл
Если Истина
И ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных")
И (Ложь
Или Не ТолькоВключенныеНаРавенствоЗначению
Или (Истина
И ЭлементОтбора.Использование
И ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно
И ТипЗнч(ЭлементОтбора.ЛевоеЗначение) = Тип("ПолеКомпоновкиДанных")
И ТипЗнч(ЭлементОтбора.ПравоеЗначение) <> Тип("ПолеКомпоновкиДанных")))
Тогда
Если Ложь
Или МассивПолейПуст
Или МассивПолейРекурсия.Найти(ЭлементОтбора.ЛевоеЗначение) <> Неопределено
Тогда
НайденныеЭлементы.Вставить("" + ЭлементОтбора.ЛевоеЗначение, ЭлементОтбора);
КонецЕсли;
ИначеЕсли Истина
И ВключатьПодчиненные
И ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
Тогда
НайтиЭлементОтбораКомпоновкиЛкс(ЭлементОтбора.Элементы,, НайденныеЭлементы, ТолькоВключенныеНаРавенствоЗначению, МассивПолейРекурсия);
КонецЕсли;
КонецЦикла;
Если МассивИменПолей <> Неопределено И МассивИменПолей.Количество() = 1 Тогда
Результат = НайденныеЭлементы[МассивИменПолей[0]];
Иначе
Результат = НайденныеЭлементы;
КонецЕсли;
Возврат Результат;
КонецФункции
// При ИспользованиеДляНового=Ложь для существующего элемента отбора не меняется правое значение
Функция НайтиДобавитьЭлементОтбораКомпоновкиЛкс(Знач ЭлементыОтбора, Знач Поле = "", Знач Значение = Неопределено, Знач Сравнение = "", Знач ДоступныеПоляОтбора = Неопределено,
Знач ПроверятьУникальность = Истина, Знач ИспользованиеДляНового = Истина, Знач СообщитьОДобавлении = Ложь) Экспорт
Если ТипЗнч(ЭлементыОтбора) = Тип("НастройкиКомпоновкиДанных") Тогда
ЭлементыОтбора = ЭлементыОтбора.Отбор;
КонецЕсли;
Если ТипЗнч(ЭлементыОтбора) = Тип("ОтборКомпоновкиДанных") Тогда
ДоступныеПоляОтбора = ЭлементыОтбора.ДоступныеПоляОтбора;
ЭлементыОтбора = ЭлементыОтбора.Элементы;
ИначеЕсли ТипЗнч(ЭлементыОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
ЭлементыОтбора = ЭлементыОтбора.Элементы;
Иначе
ЭлементыОтбора = ЭлементыОтбора;
КонецЕсли;
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
Если ПроверятьУникальность Тогда
ЭлементОтбора = НайтиЭлементОтбораКомпоновкиЛкс(ЭлементыОтбора, "" + Поле);
КонецЕсли;
Если ЭлементОтбора = Неопределено Тогда
ЭлементОтбора = ЭлементыОтбора.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.Использование = ИспользованиеДляНового;
ЭлементОтбора.ЛевоеЗначение = Поле;
ИначеЕсли Не ИспользованиеДляНового Тогда // Опасно
Возврат ЭлементОтбора;
КонецЕсли;
Если ТипЗнч(Значение) = Тип("ФиксированныйМассив") Тогда
Значение = Новый Массив(Значение);
КонецЕсли;
Если ТипЗнч(Значение) = Тип("Массив") Тогда
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(Значение);
Значение = СписокЗначений;
КонецЕсли;
// Вид сравнения
Если ТипЗнч(Сравнение) = Тип("ВидСравненияКомпоновкиДанных") Тогда
Иначе
Если ТипЗнч(Значение) = Тип("СписокЗначений") Тогда
Сравнение = ВидСравненияКомпоновкиДанных.ВСписке;
Иначе
Сравнение = ВидСравненияКомпоновкиДанных.Равно;
КонецЕсли;
КонецЕсли;
Если Истина
И Сравнение = ВидСравненияКомпоновкиДанных.Равно
И Значение = Неопределено
И ДоступныеПоляОтбора <> Неопределено
Тогда
ДоступноеПолеОтбора = ДоступныеПоляОтбора.НайтиПоле(Поле);
Если ДоступноеПолеОтбора <> Неопределено Тогда
Значение = ДоступноеПолеОтбора.Тип.ПривестиЗначение(Значение);
Если Истина
И Значение = ""
И ДоступноеПолеОтбора.Тип.КвалификаторыСтроки.Длина = 0
Тогда
Сравнение = ВидСравненияКомпоновкиДанных.Содержит;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ЭлементОтбора.ВидСравнения = Сравнение;
ЭлементОтбора.ПравоеЗначение = Значение;
Если СообщитьОДобавлении Тогда
СообщитьЛкс("В отбор установлен элемент """ + ПредставлениеЭлементаОтбораЛкс(ЭлементОтбора) + """");
КонецЕсли;
Возврат ЭлементОтбора;
КонецФункции
Функция ПредставлениеЭлементаОтбораЛкс(ЭлементОтбора) Экспорт
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
Результат = "" + ЭлементОтбора.Представление + " " + ЭлементОтбора.ВидСравнения + " " + ЭлементОтбора.Значение;
Иначе
Результат = "" + ЭлементОтбора.ЛевоеЗначение + " " + ЭлементОтбора.ВидСравнения + " " + ЭлементОтбора.ПравоеЗначение;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НайтиДоступноеПолеКомпоновкиПоИмениКолонкиЛкс(Знач ДоступныеПоля, Знач ДанныеКолонки) Экспорт
#Если Сервер И Не Сервер Тогда
ДоступныеПоля = Новый НастройкиКомпоновкиДанных;
ДоступныеПоля = ДоступныеПоля.ДоступныеПоляОтбора;
#КонецЕсли
ДоступноеПоле = ДоступныеПоля.НайтиПоле(Новый ПолеКомпоновкиДанных(ДанныеКолонки));
Если ДоступноеПоле = Неопределено Тогда
ДоступноеПоле = ДоступныеПоля.НайтиПоле(Новый ПолеКомпоновкиДанных(СтрЗаменить(ДанныеКолонки, "_", ".")));
КонецЕсли;
Возврат ДоступноеПоле;
КонецФункции
// Таблица - ТаблицаЗначений, ТабличнаяЧасть, НаборЗаписей
Функция НеуникальныеЗначенияКолонкиТаблицыЛкс(Таблица, ИмяКолонки, ИгнорироватьРегистрДляПростогоСтрокогоТипа = Истина, ОтборСтрок = Неопределено) Экспорт
Если ТипЗнч(Таблица) = Тип("ТаблицаЗначений") Тогда
КопияТаблицы = Таблица.Скопировать(ОтборСтрок, ИмяКолонки);
Иначе
КопияТаблицы = Таблица.Выгрузить(ОтборСтрок, ИмяКолонки);
КонецЕсли;
Типы = КопияТаблицы.Колонки[ИмяКолонки].ТипЗначения.Типы();
Если Истина
И Типы.Количество() = 1
И Типы[0] = Тип("Строка")
И ИгнорироватьРегистрДляПростогоСтрокогоТипа
Тогда
ИмяКолонкиНрег = ИмяКолонки + "_Нрег777233464645";
КопияТаблицы.Колонки.Добавить(ИмяКолонкиНрег);
Для Каждого СтрокаКопииТаблицы Из КопияТаблицы Цикл
СтрокаКопииТаблицы[ИмяКолонкиНрег] = НРег(СтрокаКопииТаблицы[ИмяКолонки]);
КонецЦикла;
Иначе
ИмяКолонкиНрег = ИмяКолонки;
КонецЕсли;
КолонкаКоличества = ИмяКолонки + "7773534765"; //гарантировано уникальное имя колонки
КопияТаблицы.Колонки.Добавить(КолонкаКоличества);
КопияТаблицы.ЗаполнитьЗначения(1, КолонкаКоличества);
КопияТаблицы.Свернуть(ИмяКолонкиНрег, КолонкаКоличества);
КопияТаблицы.Сортировать(КолонкаКоличества + " Убыв");
МассивНеуникальных = Новый Массив;
Для Индекс = 0 По КопияТаблицы.Количество() - 1 Цикл
СтрокаКопии = КопияТаблицы[Индекс];
Если СтрокаКопии[КолонкаКоличества] > 1 Тогда
МассивНеуникальных.Добавить(СтрокаКопии[ИмяКолонкиНрег]);
КонецЕсли;
КонецЦикла;
Возврат МассивНеуникальных;
КонецФункции // ПолучитьНеуникальныеЗначенияКолонки()
// Таблица - ТаблицаЗначений, ТабличнаяЧасть, НаборЗаписей
// ИменаКолонок - Строка - имена колонок через запятую
Функция НеуникальныеКлючиТаблицыЛкс(Таблица, Знач ИменаКолонок = "", ИсключаяОтбор = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Таблица = Новый ТаблицаЗначений;
#КонецЕсли
Если Не ЗначениеЗаполнено(ИменаКолонок) Тогда
ИменаКолонок = "";
Для Каждого КолонкаТаблицы Из Таблица.Колонки Цикл
Если Ложь
Или КолонкаТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений"))
Или КолонкаТаблицы.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения"))
Тогда
Продолжить;
КонецЕсли;
Если ИменаКолонок <> "" Тогда
ИменаКолонок = ИменаКолонок + ",";
КонецЕсли;
ИменаКолонок = ИменаКолонок + КолонкаТаблицы.Имя;
КонецЦикла;
КонецЕсли;
Если ТипЗнч(Таблица) <> Тип("ТаблицаЗначений") Тогда
КопияТаблицы = Таблица.Выгрузить(, ИменаКолонок);
Иначе
КопияТаблицы = Таблица.Скопировать(, ИменаКолонок);
КонецЕсли;
Если ИсключаяОтбор <> Неопределено Тогда
Для Каждого УдаляемаяСтрока Из КопияТаблицы.НайтиСтроки(ИсключаяОтбор) Цикл
КопияТаблицы.Удалить(УдаляемаяСтрока);
КонецЦикла;
КонецЕсли;
КолонкаКоличества = "Количество7773534765"; //гарантировано уникальное имя колонки
КопияТаблицы.Колонки.Добавить(КолонкаКоличества);
КопияТаблицы.ЗаполнитьЗначения(1, КолонкаКоличества);
КопияТаблицы.Свернуть(ИменаКолонок, КолонкаКоличества);
КопияТаблицы.Сортировать(КолонкаКоличества + " Убыв");
МассивНеуникальных = Новый Массив;
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Для Индекс = 0 По КопияТаблицы.Количество() - 1 Цикл
СтрокаКопии = КопияТаблицы[Индекс];
Если СтрокаКопии[КолонкаКоличества] > 1 Тогда
НеуникальныйКлюч = Новый Структура(ИменаКолонок);
ЗаполнитьЗначенияСвойств(НеуникальныйКлюч, СтрокаКопии);
МассивНеуникальных.Добавить(НеуникальныйКлюч);
КонецЕсли;
КонецЦикла;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Индекс = 0 По КопияТаблицы.Количество() - 1 Цикл СтрокаКопии = КопияТаблицы[Индекс]; Если СтрокаКопии[КолонкаКоличества] > 1 Тогда НеуникальныйКлюч = Новый Структура(ИменаКолонок); ЗаполнитьЗначенияСвойств(НеуникальныйКлюч, СтрокаКопии); МассивНеуникальных.Добавить(НеуникальныйКлюч); КонецЕсли; КонецЦикла;
Возврат МассивНеуникальных;
КонецФункции // ПолучитьНеуникальныеЗначенияКолонки()
Функция ПредставлениеОтбораЛкс(Знач Отбор) Экспорт
ПредставлениеОтбора = "" + Отбор;
Если Не ЗначениеЗаполнено(ПредставлениеОтбора) Тогда
ПредставлениеОтбора = "Без отбора";
КонецЕсли;
Возврат ПредставлениеОтбора;
КонецФункции
Функция ПредставлениеДлительностиЛкс(Знач ДлительностьСекунд) Экспорт
Результат = "";
КолвоЧасов = Цел(ДлительностьСекунд / 3600);
ДлительностьДата = '00010101' + ДлительностьСекунд - КолвоЧасов * 3600;
Если КолвоЧасов > 0 Тогда
Результат = Результат + Формат(КолвоЧасов, "ЧН=; ЧГ=0") + ":";
КонецЕсли;
Результат = Результат + Формат(ДлительностьДата, "ДФ=мм:сс; ДП=");
Возврат Результат;
КонецФункции
Функция ЛитеральноеПредставлениеЗначенияВЯзыкеЗапросовЛкс(ЗначениеПараметра, ВыводитьСообщения = Ложь) Экспорт
ТекстЗамены = "";
ТипЗначенияПараметра = ТипЗнч(ЗначениеПараметра);
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗначенияПараметра);
Если ОбъектМД <> Неопределено Тогда
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ОбъектМД.ПолноеИмя());
Если ирОбщий.ЛиКорневойТипСсылкиЛкс(КорневойТип) Тогда
Если ирОбщий.ЛиТипСсылкиТочкиМаршрутаЛкс(ТипЗначенияПараметра) Тогда
ТекстЗамены = "ТочкаМаршрута." + ЗначениеПараметра.Имя;
ИначеЕсли ЗначениеПараметра.Пустая() Тогда
ТекстЗамены = "ПустаяСсылка";
ИначеЕсли ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТип) Тогда
ТекстЗамены = XMLСтрока(ЗначениеПараметра);
ИначеЕсли ирОбщий.ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда
Если ЗначениеПараметра.Предопределенный Тогда
ТекстЗамены = ирОбщий.ПолучитьМенеджерЛкс(ОбъектМД).ПолучитьИмяПредопределенного(ЗначениеПараметра);
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗначенияПараметра = Тип("ВидДвиженияБухгалтерии") Тогда
ТекстЗамены = "ВидДвиженияБухгалтерии." + ЗначениеПараметра;
ИначеЕсли ТипЗначенияПараметра = Тип("ВидДвиженияНакопления") Тогда
ТекстЗамены = "ВидДвиженияНакопления." + ЗначениеПараметра;
КонецЕсли;
Если ТекстЗамены = "" Тогда
Если ВыводитьСообщения Тогда
СообщитьЛкс("Представление значения """ + ирОбщий.РасширенноеПредставлениеЗначенияЛкс(ЗначениеПараметра) + """ в языке запросов через ЗНАЧЕНИЕ() невозможно")
КонецЕсли;
Иначе
Если ОбъектМД <> Неопределено Тогда
ТекстЗамены = ОбъектМД.ПолноеИмя() + "." + ТекстЗамены;
КонецЕсли;
ТекстЗамены = "ЗНАЧЕНИЕ(" + ТекстЗамены + ")";
КонецЕсли;
Возврат ТекстЗамены;
КонецФункции
Функция ЛитеральноеПредставлениеЗначенияВоВстроенномЯзыкеЛкс(Значение) Экспорт
Если ТипЗнч(Значение) = Тип("Неопределено") Тогда
Результат = ПеревестиСтроку("Неопределено");
ИначеЕсли ТипЗнч(Значение) = Тип("Null") Тогда
Результат = "Null";
Иначе
Если ТипЗнч(Значение) = Тип("Дата") Тогда
Результат = ПеревестиСтроку("Дата") + "(" + XMLСтрока(Год(Значение)) + ", " + XMLСтрока(Месяц(Значение)) + ", " + XMLСтрока(День(Значение));
Если НачалоДня(Значение) <> Значение Тогда
Результат = Результат + ", " + XMLСтрока(Час(Значение)) + ", " + XMLСтрока(Минута(Значение)) + ", " + XMLСтрока(Секунда(Значение));
КонецЕсли;
Результат = Результат + ")";
ИначеЕсли ТипЗнч(Значение) = Тип("Число") Тогда
Результат = XMLСтрока(Значение);
ИначеЕсли ТипЗнч(Значение) = Тип("Булево") Тогда
Если Значение Тогда
Результат = ПеревестиСтроку("Истина");
Иначе
Результат = ПеревестиСтроку("Ложь");
КонецЕсли;
ИначеЕсли ТипЗнч(Значение) = Тип("Строка") Тогда
Результат = """" + СтрЗаменить(Значение, """", """""") + """";
Иначе
ВызватьИсключение "Для типа значения """ + ТипЗнч(Значение) + """ не определено литеральное представление во встроенном языке";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция РазличныеЗначенияКолонкиТаблицыЛкс(Таблица, ИмяКолонки, ОтборСтрок = Неопределено) Экспорт
Если ТипЗнч(Таблица) = Тип("ТаблицаЗначений") Тогда
#Если Сервер И Не Сервер Тогда
Таблица = Новый ТаблицаЗначений;
#КонецЕсли
КопияТаблицы = Таблица.Скопировать(ОтборСтрок, ИмяКолонки);
Иначе
КопияТаблицы = Таблица.Выгрузить(ОтборСтрок, ИмяКолонки);
КонецЕсли;
#Если Сервер И Не Сервер Тогда
КопияТаблицы = Новый ТаблицаЗначений;
#КонецЕсли
КопияТаблицы.Свернуть(ИмяКолонки);
РазличныеЗначения = КопияТаблицы.ВыгрузитьКолонку(ИмяКолонки);
Возврат РазличныеЗначения;
КонецФункции // ПолучитьНеуникальныеЗначенияКолонки()
Функция СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, ОбъектыНаСервере = Неопределено) Экспорт
СтруктураНабораЗаписей = ОбъектБДПоКлючуЛкс(ПолноеИмяТаблицыБД,,, Ложь, ОбъектыНаСервере);
Возврат СтруктураНабораЗаписей;
КонецФункции
// Переводит системный идентификатор на язык варианта встроенного языка
Функция ПеревестиСтроку(Русский) Экспорт
// Для ускорения
//Если Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский Тогда
Если "" + Метаданные.ВариантВстроенногоЯзыка = "Русский" Тогда
Возврат Русский;
Иначе
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Локальный = мПлатформа.ПеревестиСтроку("" + Русский, Истина);
Возврат Локальный;
КонецЕсли;
КонецФункции
// Переводит системный идентификатор на русский язык
Функция ПеревестиВРусский(Локальный) Экспорт
//Если Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский Тогда // Долго
Если КодСимвола(Локальный, 1) >= 128 Тогда
Возврат Локальный;
Иначе
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Русский = мПлатформа.ПеревестиВРусский("" + Локальный, Истина);
Возврат Русский;
КонецЕсли;
КонецФункции
// Переводит системный идентификатор на английский язык
Функция ПеревестиИзРусскогоВАнглийскийЛкс(Локальный) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Русский = мПлатформа.ПеревестиСтроку("" + Локальный, Истина);
Возврат Русский;
КонецФункции
Функция ПеревестиПолноеИмяМДВАнглийскийЛкс(ПолноеИмяМД) Экспорт
Фрагменты = ирОбщий.СтрРазделитьЛкс(ПолноеИмяМД);
Результат = "";
Для Счетчик = 1 По Фрагменты.Количество() / 2 Цикл
Если Результат <> "" Тогда
Результат = Результат + ".";
КонецЕсли;
Английский = ПеревестиИзРусскогоВАнглийскийЛкс(Фрагменты[(Счетчик-1)*2]);
Результат = Результат + Английский + "." + Фрагменты[(Счетчик-1)*2+1];
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ТипКлючаЗаписиТаблицыЛкс(ПолноеИмяТаблицы) Экспорт
ТипТаблицы = ирОбщий.ТипТаблицыБДЛкс(ПолноеИмяТаблицы);
Если ирОбщий.ЛиКорневойТипСсылкиЛкс(ТипТаблицы) Тогда
Результат = Тип(ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяТаблицы));
ИначеЕсли Истина
И ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы)
И ТипТаблицы <> "Перерасчет"
И ТипТаблицы <> "Последовательность"
Тогда
Результат = Тип(СтрЗаменить(ПолноеИмяТаблицы, ".", "КлючЗаписи."));
Иначе
Результат = Тип("Неопределено");
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ВернутьСтруктуру - Булево - возвращать структуру иначе список значений
// ДляНабораЗаписейРегистраСведений - Булево - для регистров сведений подчиненных регистратору вернуть ключ записываемого объекта
//
Функция СтруктураКлючаТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, ВключатьНомерСтроки = Истина, ВернутьСтруктуру = Истина, ДляПодчиненногоРегистраСведенийНомерСтроки = Истина) Экспорт
ТипТаблицы = ТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
МассивФрагментов = СтрРазделитьЛкс(ПолноеИмяТаблицыБД);
СписокПолей = Новый СписокЗначений;
Если Ложь
Или ЛиТипТаблицыМетассылкиЛкс(ТипТаблицы)
Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы)
Тогда
СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), ПеревестиСтроку("Ссылка"));
ИначеЕсли ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда
ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
НаборЗаписей = ирКэш.ЭталонныйНаборЗаписейЛкс(ПолноеИмяТаблицыБД);
#Если Сервер И Не Сервер Тогда
НаборЗаписей = РегистрыСведений.ВерсииОбъектов.СоздатьНаборЗаписей();
#КонецЕсли
Если Истина
И ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору
И Не ДляПодчиненногоРегистраСведенийНомерСтроки
Тогда
Если ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
СписокПолей.Добавить(Новый ОписаниеТипов("Дата"), ПеревестиСтроку("Период"));
КонецЕсли;
Если ОбъектМД.ПериодичностьРегистраСведений = Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.ПозицияРегистратора Тогда
СписокПолей.Добавить(НаборЗаписей.Отбор.Регистратор.ТипЗначения, ПеревестиСтроку("Регистратор"));
КонецЕсли;
Для Каждого Измерение Из ОбъектМД.Измерения Цикл
СписокПолей.Добавить(Измерение.Тип, Измерение.Имя);
КонецЦикла;
КонецЕсли;
Если СписокПолей.Количество() = 0 Тогда
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
Если Ложь
Или ЭлементОтбора.Использование
Или ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
Тогда
СписокПолей.Добавить(ЭлементОтбора.ТипЗначения, ЭлементОтбора.Имя);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ВключатьНомерСтроки Тогда
Если ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы) Тогда
Для Каждого Измерение Из ОбъектМД.Измерения Цикл
СписокПолей.Добавить(Измерение.Тип, Измерение.Имя);
КонецЦикла;
ИначеЕсли Истина
И ТипТаблицы <> "Перерасчет"
И (Ложь
Или Не ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
Или (ДляПодчиненногоРегистраСведенийНомерСтроки И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору))
Тогда
СписокПолей.Добавить(Новый ОписаниеТипов("Число"), ПеревестиСтроку("НомерСтроки"));
КонецЕсли;
КонецЕсли;
ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), ПеревестиСтроку("Ссылка"));
Если ВключатьНомерСтроки Тогда
СписокПолей.Добавить(Новый ОписаниеТипов("Число"), ПеревестиСтроку("НомерСтроки"));
КонецЕсли;
ИначеЕсли ТипТаблицы = "Изменения" Тогда
// Такой способ может быть долгим при частых вызовах
ПостроительЗапроса = Новый ПостроительЗапроса;
ПостроительЗапроса.Текст = "ВЫБРАТЬ * ИЗ " + ПолноеИмяТаблицыБД + " КАК _Таблица_";
ПостроительЗапроса.ЗаполнитьНастройки();
Для Каждого ДоступноеПоле Из ПостроительЗапроса.ДоступныеПоля Цикл
Если Ложь
Или СтрокиРавныЛкс(ДоступноеПоле.ПутьКДанным, ПеревестиСтроку("НомерСообщения"))
Тогда
Продолжить;
КонецЕсли;
СписокПолей.Добавить(ДоступноеПоле.ТипЗначения, ДоступноеПоле.ПутьКДанным);
КонецЦикла;
ИначеЕсли ТипТаблицы = "Внешняя" Тогда
ТаблицаМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяТаблицыБД);
Если ТаблицаМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные Тогда
СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), ПеревестиСтроку("Ссылка"));
Иначе
НаборЗаписей = ирКэш.ЭталонныйНаборЗаписейЛкс(ПолноеИмяТаблицыБД);
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
СписокПолей.Добавить(ЭлементОтбора.ТипЗначения, ЭлементОтбора.Имя);
КонецЦикла;
КонецЕсли;
ИначеЕсли ТипТаблицы = "ЖурналДокументов" Тогда
Поля = ПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Поле = Поля.Найти(ПеревестиСтроку("Ссылка"), "Имя");
СписокПолей.Добавить(Поле.ТипЗначения, Поле.Имя);
Иначе
ВызватьИсключение "Получение структуры ключа таблицы БД типа """ + ТипТаблицы + """ не поддерживается";
КонецЕсли;
Если ВернутьСтруктуру Тогда
Результат = Новый Структура();
Для Каждого ЭлементСписка Из СписокПолей Цикл
Результат.Вставить(ЭлементСписка.Представление, ЭлементСписка.Значение);
КонецЦикла;
Иначе
Результат = СписокПолей;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ДанныеСтрокиРегистраИзКлючаЗаписиЛкс(Знач КлючЗаписи, Знач ИмяТаблицыРегистра = "") Экспорт
Если Не ЗначениеЗаполнено(ИмяТаблицыРегистра) Тогда
ИмяТаблицыРегистра = ирКэш.ИмяТаблицыИзМетаданныхЛкс(Метаданные.НайтиПоТипу(ТипЗнч(КлючЗаписи)).ПолноеИмя());
КонецЕсли;
СтруктураКлючаСтроки = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ИмяТаблицыРегистра,,, Ложь);
ЗаполнитьЗначенияСвойств(СтруктураКлючаСтроки, КлючЗаписи);
СхемаКомпоновки = ирОбщий.ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ИмяТаблицыРегистра);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, СтруктураКлючаСтроки);
ПоляТаблицыБД = ирКэш.ПоляТаблицыБДЛкс(ИмяТаблицыРегистра);
Для Каждого СтрокаПоля Из ПоляТаблицыБД Цикл
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, СтрокаПоля.Имя);
КонецЦикла;
ДанныеСтроки = ирОбщий.СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки);
Результат = Неопределено;
Если ДанныеСтроки.Количество() > 0 Тогда
Результат = ДанныеСтроки[0];
КонецЕсли;
Возврат Результат;
КонецФункции
Функция УдалитьМутабельныеЗначенияВСтруктуреЛкс(Знач ДополнительныеСвойстваЛ) Экспорт
// Убираем неудобные типы значений из дополнительных свойств объекта http://devtool1c.ucoz.ru/forum/2-832-1#3587
//УдаляемыеКлючи = Новый Массив;
//Для Каждого КлючИЗначение Из ДополнительныеСвойстваЛ Цикл
// Если ТипЗнч(КлючИЗначение.Значение) = Тип("МенеджерВременныхТаблиц") Тогда
// УдаляемыеКлючи.Добавить(КлючИЗначение.Ключ);
// КонецЕсли;
//КонецЦикла;
//Для Каждого Ключ Из УдаляемыеКлючи Цикл
// ДополнительныеСвойстваЛ.Удалить(Ключ);
//КонецЦикла;
Результат = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(ДополнительныеСвойстваЛ));
Возврат Результат;
КонецФункции
// Функция - Заполнить значения свойств обязательно.
//
// Параметры:
// Объект - -
// Структура - -
// выхИменаСвойств - Строка - передается для ускорения, заполняется автоматически
//
// Возвращаемое значение:
// -
//
Функция ЗаполнитьЗначенияСвойствОбязательноЛкс(Объект, Структура, выхИменаСвойств = "") Экспорт
#Если Сервер И Не Сервер Тогда
Структура = Новый Структура;
#КонецЕсли
Если Не ЗначениеЗаполнено(выхИменаСвойств) Тогда
выхИменаСвойств = ИменаСвойствСтруктурыЛкс(Структура);
КонецЕсли;
ЗаполнитьЗначенияСвойств(Объект, Структура, выхИменаСвойств);
КонецФункции
Функция ИменаСвойствСтруктурыЛкс(Знач СтруктураИлиСтрокаТаблицы) Экспорт
ИменаСвойств = "";
Если ТипЗнч(СтруктураИлиСтрокаТаблицы) <> Тип("Структура") Тогда
СтруктураИлиСтрокаТаблицы = СтруктураИлиСтрокаТаблицы.Владелец().Колонки;
КонецЕсли;
Для Каждого КлючИЗначение Из СтруктураИлиСтрокаТаблицы Цикл
Если ТипЗнч(КлючИЗначение) = Тип("КлючИЗначение") Тогда
ИмяСвойства = КлючИЗначение.Ключ;
Иначе
ИмяСвойства = КлючИЗначение.Имя;
КонецЕсли;
ИменаСвойств = ИменаСвойств + "," + ИмяСвойства;
КонецЦикла;
ИменаСвойств = Сред(ИменаСвойств, 2);
Возврат ИменаСвойств
КонецФункции
Функция ЦветТекстаНеактивностиЛкс() Экспорт
Возврат Новый Цвет(100, 100, 100);
КонецФункции
Функция ЦветТекстаТекущегоЭлементаЛкс() Экспорт
Возврат Новый Цвет(20, 40, 160);
КонецФункции
Функция ЦветТекстаИзмененныхДанныхЛкс() Экспорт
Возврат WebЦвета.КожаноКоричневый;
КонецФункции
Функция ЦветФонаАкцентаЛкс() Экспорт
Возврат Новый Цвет(250, 245, 230);
КонецФункции
Функция ЦветФонаОшибкиЛкс() Экспорт
Возврат Новый Цвет(250, 240, 240);
КонецФункции
// Для подчиненного регистра сведений выполняет чтение из БД
// Параметры:
// Результат - Структура
Функция СтруктураИзКлючаЗаписиЛкс(КлючЗаписи, ПолноеИмяМДЭлемента = "", ДляПодчиненногоРегистраСведенийНомерСтроки = Ложь) Экспорт
Если Не ЗначениеЗаполнено(ПолноеИмяМДЭлемента) Тогда
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(КлючЗаписи));
ПолноеИмяМДЭлемента = ОбъектМД.ПолноеИмя();
Иначе
ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяМДЭлемента);
КонецЕсли;
СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяМДЭлемента, Истина,, Ложь);
ЗаполнитьЗначенияСвойств(СтруктураКлюча, КлючЗаписи);
Если ДляПодчиненногоРегистраСведенийНомерСтроки Тогда
ТипТаблицы = ТипТаблицыБДЛкс(ПолноеИмяМДЭлемента);
Если Истина
И ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору
Тогда
ДанныеСтроки = СтрокаТаблицыБДПоКлючуЛкс(ПолноеИмяМДЭлемента, СтруктураКлюча);
СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяМДЭлемента);
ЗаполнитьЗначенияСвойств(СтруктураКлюча, ДанныеСтроки);
КонецЕсли;
КонецЕсли;
Возврат СтруктураКлюча;
КонецФункции
Функция XMLКлючОбъектаБДЛкс(Знач ОбъектДанных, Знач ИспользоватьСсылкуДляСсылочных = Ложь) Экспорт
Если ОбъектДанных = Неопределено Тогда
Результат = "Неопределено";
Возврат Результат;
КонецЕсли;
ПредставлениеОбъекта = "";
Если ТипЗнч(ОбъектДанных) = Тип("УдалениеОбъекта") Тогда
Класс = "Удаление";
Иначе
Попытка
ЭтоНовый = ОбъектДанных.ЭтоНовый();
Класс = "Ссылочный";
ПредставлениеОбъекта = "" + ОбъектДанных + ",";
Исключение
Попытка
ИдентификаторСсылки = ОбъектДанных.УникальныйИдентификатор();
Класс = "Ссылочный";
Исключение
Попытка
Пустышка = ОбъектДанных.Количество();
Класс = "НаборЗаписей";
Исключение
Попытка
Пустышка = ОбъектДанных.Значение;
Класс = "Константы";
Исключение
Класс = "Примитив";
КонецПопытки;
КонецПопытки;
КонецПопытки;
КонецПопытки;
Если Истина
И Класс = "Ссылочный"
И ИспользоватьСсылкуДляСсылочных
Тогда
Результат = ОбъектДанных;
Возврат Результат;
КонецЕсли;
КонецЕсли;
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если ТипЗнч(ОбъектДанных) = Тип("ОбработкаОбъект.ирИмитаторНаборЗаписей") Тогда
Класс = "НаборЗаписей";
ИначеЕсли ТипЗнч(ОбъектДанных) = Тип("ОбработкаОбъект.ирИмитаторКонстантаМенеджер") Тогда
Класс = "Константы";
КонецЕсли;
КонецЕсли;
// Антибаг 8.3.11 На перерасчетах ЗаписьXML ошибку выдает. https://partners.v8.1c.ru/forum/t/1674609/m/1674609
//XMLКлюч = "" + XMLТип(ТипОбъектаБДЛкс(ОбъектДанных)).ИмяТипа + "(";
XMLКлюч = "" + СериализаторXDTO.XMLТип(ТипОбъектаБДЛкс(ОбъектДанных)).ИмяТипа + "(";
Если Класс = "Ссылочный" Тогда
Если ЭтоНовый = Истина Тогда
ИдентификаторСсылки = "!" + ИдентификаторСсылки = ИдентификаторСсылкиЛкс(ОбъектДанных.ПолучитьСсылкуНового());
КонецЕсли;
Если ИдентификаторСсылки = Неопределено Тогда
ИдентификаторСсылки = ИдентификаторСсылкиЛкс(ОбъектДанных.Ссылка);
КонецЕсли;
XMLКлюч = XMLКлюч + ПредставлениеОбъекта + ИдентификаторСсылки;
ИначеЕсли Класс = "Удаление" Тогда
XMLКлюч = XMLКлюч + XMLКлючОбъектаБДЛкс(ОбъектДанных.Ссылка);
ИначеЕсли Класс = "НаборЗаписей" Тогда
ПредставлениеОтбора = "";
Разделитель = ", ";
Для Каждого ЭлементОтбора Из ОбъектДанных.Отбор Цикл
Если ЭлементОтбора.Использование Тогда
ПредставлениеОтбора = ПредставлениеОтбора + Разделитель + ЭлементОтбора.Имя
+ ":" + XMLКлючОбъектаБДЛкс(ЭлементОтбора.Значение);
КонецЕсли;
КонецЦикла;
XMLКлюч = XMLКлюч + Сред(ПредставлениеОтбора, СтрДлина(Разделитель) + 1);
ИначеЕсли Класс = "Константы" Тогда
//
Иначе
// Примитивный тип
XMLКлюч = XMLКлюч + ОбъектДанных;
КонецЕсли;
XMLКлюч = XMLКлюч + ")";
Результат = XMLКлюч;
Возврат Результат;
КонецФункции
Функция ИдентификаторСсылкиЛкс(Знач Ссылка) Экспорт
Попытка
ИдентификаторСсылки = Ссылка.УникальныйИдентификатор();
Исключение
// Внешний источник данных
ИдентификаторСсылки = Ссылка.Значение();
КонецПопытки;
Возврат ИдентификаторСсылки;
КонецФункции
// Параметры:
// Объект - ОбъектБД, ОбъектМД
Функция ТабличныеЧастиОбъектаЛкс(Объект) Экспорт
СтруктураТЧ = Новый Структура();
Если Истина
И Не ирКэш.ЛиПортативныйРежимЛкс()
И ТипЗнч(Объект) = Тип("ОбработкаОбъект.ирИмитаторСсылочныйОбъект")
Тогда
ОбъектМД = Метаданные.НайтиПоТипу(Объект._Тип);
ОбъектБД = Объект.Данные;
ИначеЕсли ТипЗнч(Объект) = Тип("ОбъектМетаданных") Тогда
ОбъектМД = Объект;
ОбъектБД = Неопределено;
Иначе
Если ЛиТипСсылкиТочкиМаршрутаЛкс(ТипЗнч(Объект)) Тогда
Возврат СтруктураТЧ;
КонецЕсли;
ОбъектМД = Объект.Метаданные();
ОбъектБД = Объект;
КонецЕсли;
Если Не ЛиМетаданныеСсылочногоОбъектаЛкс(ОбъектМД, Ложь, Истина, Истина) Тогда
Возврат СтруктураТЧ;
КонецЕсли;
Для Каждого МетаТЧ из ОбъектМД.ТабличныеЧасти Цикл
// Для реквизитов справочников, принадлежащих только группе или только элементу нужно игнорировать те объекты, для которых эти реквизиты не используются
Если Истина
И ОбъектБД <> Неопределено
И ирОбщий.ЛиМетаданныеОбъектаСГруппамиЛкс(ОбъектМД)
Тогда
Если Ложь
Или (Истина
И ОбъектБД.ЭтоГруппа
И МетаТЧ.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента)
Или (Истина
И Не ОбъектБД.ЭтоГруппа
И МетаТЧ.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы)
Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
СтруктураТЧ.Вставить(МетаТЧ.Имя, МетаТЧ.Представление());
КонецЦикла;
Если Метаданные.ПланыСчетов.Индекс(ОбъектМД) >= 0 Тогда
Если ОбъектМД.ВидыСубконто <> Неопределено Тогда
СтруктураТЧ.Вставить(ПеревестиСтроку("ВидыСубконто"), "Виды субконто");
КонецЕсли;
КонецЕсли;
Если Метаданные.ПланыВидовРасчета.Индекс(ОбъектМД) >= 0 Тогда
Если ОбъектМД.ЗависимостьОтВидовРасчета <> Метаданные.СвойстваОбъектов.ИспользованиеБазыПланаВидовРасчета.НеИспользовать Тогда
СтруктураТЧ.Вставить(ПеревестиСтроку("БазовыеВидыРасчета"), "Базовые виды расчета");
КонецЕсли;
СтруктураТЧ.Вставить(ПеревестиСтроку("ВедущиеВидыРасчета"), "Ведущие виды расчета");
Если ОбъектМД.ИспользованиеПериодаДействия Тогда
СтруктураТЧ.Вставить(ПеревестиСтроку("ВытесняющиеВидыРасчета"), "Вытесняющие виды расчета");
КонецЕсли;
КонецЕсли;
Возврат СтруктураТЧ;
КонецФункции
Функция ЛиСтрокаСодержитВсеПодстрокиЛкс(Знач Строка, Знач Подстроки) Экспорт
Если ТипЗнч(Подстроки) = Тип("Строка") Тогда
Подстроки = СтрРазделитьЛкс(НРег(Подстроки), " ", Истина);
КонецЕсли;
НСтрока = НРег(Строка);
Для Каждого Фрагмент Из Подстроки Цикл
Если Найти(НСтрока, Фрагмент) = 0 Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Функция СтрокаТаблицыБДПоКлючуЛкс(ПолноеИмяТаблицы, СтруктураКлюча) Экспорт
Запрос = Новый Запрос;
ТекстЗапроса = "ВЫБРАТЬ Т.* ИЗ " + ПолноеИмяТаблицы + " КАК Т ГДЕ ИСТИНА ";
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
ТекстЗапроса = ТекстЗапроса + " И Т." + КлючИЗначение.Ключ + " = &" + КлючИЗначение.Ключ;
КонецЦикла;
СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураКлюча, Запрос.Параметры);
Запрос.Текст = ТекстЗапроса;
Таблица = Запрос.Выполнить().Выгрузить();
Если Таблица.Количество() > 1 Тогда
ВызватьИсключение "По переданному ключу (" + ПолучитьПредставлениеСтруктурыЛкс(СтруктураКлюча) + ") найдено несколько строк таблицы";
ИначеЕсли Таблица.Количество() > 0 Тогда
СтрокаРезультата = Таблица[0];
Иначе
СтрокаРезультата = Неопределено;
КонецЕсли;
Возврат СтрокаРезультата;
КонецФункции
// Присваивает ячейке по указателю значение. Если после этого ячейка получает другое значение, то ячейке присваивается ее старое значение.
Функция БезопасноПрисвоитьПроизвольнуюСсылкуЛкс(П1, П2) Экспорт
СтароеП1 = П1;
П1 = П2;
Если П1 <> П2 Тогда
П1 = СтароеП1;
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции // БезопасноПрисвоитьПроизвольнуюСсылку()
// ЛиНаходитьОбразующий - Булево - находить ближайший объект метаданных, если точный найти не удается
Функция ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, ЛиНаходитьОбразующий = Ложь) Экспорт
Результат = Неопределено;
Если Истина
И Не ПустаяСтрока(ПолноеИмяТаблицыБД)
И ПолноеИмяТаблицыБД <> "Константы"
Тогда
Фрагменты = СтрРазделитьЛкс(ПолноеИмяТаблицыБД);
Если Фрагменты.Количество() < 2 Тогда
Возврат Неопределено;
КонецЕсли;
ОбразующийМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(Фрагменты[0] + "." + Фрагменты[1]);
Если Ложь
Или ОбразующийМД = Неопределено
Или Фрагменты.Количество() = 2
Тогда
Результат = ОбразующийМД;
Иначе
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(Фрагменты[0]) Тогда
ДочерняяКоллекция = ОбразующийМД.ТабличныеЧасти;
ИначеЕсли Фрагменты[0] = ПеревестиСтроку("РегистрРасчета") Тогда
ДочерняяКоллекция = ОбразующийМД.Перерасчеты;
ИначеЕсли ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(Фрагменты[0]) Тогда
ДочерняяКоллекция = ОбразующийМД.Таблицы;
Если Фрагменты.Количество() = 4 Тогда
Результат = ДочерняяКоллекция.Найти(Фрагменты[3]);
КонецЕсли;
//ИначеЕсли Фрагменты[0] = "РегистрБухгалтерии" Тогда
ИначеЕсли Ложь
Или ЛиКорневойТипРегистраБДЛкс(Фрагменты[0])
Или Фрагменты[0] = ПеревестиСтроку("Константа")
Тогда
Результат = ОбразующийМД;
Иначе
ВызватьИсключение "Неизвестный корневой тип метаданных(" + Фрагменты[0] + ") с дочерней таблицей";
КонецЕсли;
Если Результат = Неопределено И Фрагменты.Количество() = 3 Тогда
ДочернийОбъектМД = ДочерняяКоллекция.Найти(Фрагменты[2]);
Если ДочернийОбъектМД <> Неопределено Тогда
Результат = ДочернийОбъектМД;
ИначеЕсли ЛиНаходитьОбразующий Тогда
// ВидыСубконто, Изменения, Точки
Результат = ОбразующийМД;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОписаниеТипов1ВходитВОписаниеТипов2Лкс(ОписаниеТипов1, ОписаниеТипов2, ИгнорироватьNULL = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов1 = Новый ОписаниеТипов;
ОписаниеТипов2 = Новый ОписаниеТипов;
#КонецЕсли
Результат = Не (ОписаниеТипов2.Типы().Количество() > 0 И ОписаниеТипов1.Типы().Количество() = 0);
Если Результат Тогда
Для Каждого Тип Из ОписаниеТипов1.Типы() Цикл
Если Истина
И ИгнорироватьNULL
И Тип = Тип("Null")
Тогда
Продолжить;
КонецЕсли;
Если Не ОписаниеТипов2.СодержитТип(Тип) Тогда
Результат = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОписаниеТаблицыБДЛкс(ИмяТаблицыБД) Экспорт
Возврат ирКэш.ТаблицаВсехТаблицБДЛкс().Найти(НРег(ИмяТаблицыБД), "НПолноеИмя");
КонецФункции
Функция ЛиТаблицаБДСуществуетЛкс(ИмяТаблицыБД, СообщитьОшибку = Ложь) Экспорт
Результат = Ложь;
Если ЗначениеЗаполнено(ИмяТаблицыБД) Тогда
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ 1 ИЗ " + ИмяТаблицыБД + " ГДЕ ЛОЖЬ";
Попытка
Запрос.Выполнить();
Результат = Истина;
Исключение
Результат = Ложь;
Если ЗначениеЗаполнено(ИмяТаблицыБД) И СообщитьОшибку Тогда
ирОбщий.СообщитьЛкс(ОписаниеОшибки());
КонецЕсли;
КонецПопытки;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПредставлениеТаблицыБДЛкс(ИмяТаблицыБД) Экспорт
ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ИмяТаблицыБД);
Если ОбъектМД <> Неопределено Тогда
Результат = ОбъектМД.Представление();
Иначе
Результат = ОписаниеТаблицыБДЛкс(ИмяТаблицыБД).Представление;
КонецЕсли;
Возврат Результат;
КонецФункции
// Возвращаемое значение - всегда русский вариант
Функция ТипТаблицыБДЛкс(ПолноеИмяТаблицыБД) Экспорт
//ОписаниеТаблицы = ирКэш.ТаблицаВсехТаблицБДЛкс().Найти(НРег(ПолноеИмяТаблицыБД), "НПолноеИмя");
//Если ОписаниеТаблицы <> Неопределено Тогда
// Возврат ОписаниеТаблицы.Тип;
//КонецЕсли;
Фрагменты = СтрРазделитьЛкс(ПолноеИмяТаблицыБД);
ТипТаблицы = Фрагменты[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.Закрыть();
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Возврат ТекстЗапроса;
КонецФункции
// https://www.hostedredmine.com/issues/896348
// Параметры:
// ВыражениеПоля - Строка -
// ОписаниеТиповПоля - ОписаниеТипов -
Функция ВыражениеПоляСУчетомСоставногоТипаЛкс(Знач ВыражениеПоля, ОписаниеТиповПоля) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТиповПоля = Новый ОписаниеТипов;
#КонецЕсли
Если Истина
И ОписаниеТиповПоля.Типы().Количество() > 1
И ОписаниеТиповПоля.СодержитТип(Тип("Строка"))
Тогда
// https://www.hostedredmine.com/issues/896348
ВыражениеПоля = "
| ВЫБОР КОГДА ЛОЖЬ ТОГДА """" ИНАЧЕ
| " + ВыражениеПоля + " КОНЕЦ"
КонецЕсли;
Возврат ВыражениеПоля;
КонецФункции
Функция ТекстЗапросаПоместитьИзПараметраЛкс(Знач ИмяТаблицы = "ВТ", Знач ИмяПараметра = "ТЗ", Знач ЯвноВыбратьКаждоеПоле = Ложь, Знач Колонки = Неопределено, ДобавитьЗапросВыборки = Ложь,
ДекларироватьТипы = Ложь) Экспорт
Если ЯвноВыбратьКаждоеПоле Тогда
#Если Сервер И Не Сервер Тогда
Колонки = Новый ТаблицаЗначений;
Колонки = Колонки.Колонки;
#КонецЕсли
ВыраженияПолей = Новый Массив;
Для Каждого Колонка Из Колонки Цикл
ВыражениеПоля = "Т." + Колонка.Имя;
Если ДекларироватьТипы Тогда
ВыражениеПоля =
"ВЫБОР
| КОГДА ИСТИНА
| ТОГДА " + ВыражениеПоля;
Для Каждого ТипПоля Из Колонка.ТипЗначения.Типы() Цикл
ВыражениеПоля = ВыражениеПоля + "
| КОГДА ЛОЖЬ
| ТОГДА " + ирОбщий.ПустоеЗначениеПоТипуНаЯзыкеЗапросовЛкс(ТипПоля, Колонка.ТипЗначения);
КонецЦикла;
ВыражениеПоля = ВыражениеПоля + "
|КОНЕЦ КАК " + Колонка.Имя;
КонецЕсли;
ВыраженияПолей.Добавить(ВыражениеПоля);
КонецЦикла;
ВыраженияПолей = "
| " + ирОбщий.СтрСоединитьЛкс(ВыраженияПолей, "," + Символы.ПС);
Иначе
ВыраженияПолей = "*";
КонецЕсли;
ТекстЗапросаПоместить =
"ВЫБРАТЬ " + ВыраженияПолей + "
|ПОМЕСТИТЬ " + ИмяТаблицы + " ИЗ &" + ИмяПараметра + " КАК Т";
Если ДобавитьЗапросВыборки Тогда
ТекстЗапросаПоместить = ТекстЗапросаПоместить + ";
|ВЫБРАТЬ * ИЗ " + ИмяТаблицы + " КАК " + ИмяТаблицы;
КонецЕсли;
Возврат ТекстЗапросаПоместить;
КонецФункции
Функция ЕстьТаблицаИзмененийОбъектаМетаданных(ПолноеИмяИлиОбъектМетаданных) Экспорт
ЕстьТаблицаИзменений = Ложь;
Если ТипЗнч(ПолноеИмяИлиОбъектМетаданных) = Тип("Строка") Тогда
ОбъектМетаданных = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяИлиОбъектМетаданных);
Если ОбъектМетаданных = Неопределено Тогда
ВызватьИсключение "Объект метаданных не найден """ + ПолноеИмяИлиОбъектМетаданных + """";
КонецЕсли;
Иначе
ОбъектМетаданных = ПолноеИмяИлиОбъектМетаданных;
КонецЕсли;
//// Способ 1
//Для Каждого МетаПланОбмена Из Метаданные.ПланыОбмена Цикл
// Если МетаПланОбмена.Состав.Содержит(ОбъектМетаданных) Тогда // Долго на больших конфигурациях
// ЕстьТаблицаИзменений = Истина;
// Прервать;
// КонецЕсли;
//КонецЦикла;
//// Способ 2
//Запрос = Новый Запрос("ВЫБРАТЬ 1 ИЗ " + ирКэш.ИмяТаблицыИзМетаданныхЛкс(ОбъектМетаданных.ПолноеИмя(), Истина) + " КАК Т");
//Попытка
// Запрос.НайтиПараметры(); // Долго, но стабильно. Длительность не зависит от количества планов обмена
// ЕстьТаблицаИзменений = Истина;
//Исключение
// //Описание = ОписаниеОшибки();
// Пустышка = 1;
//КонецПопытки;
//// Способ 3
//Массив = Новый Массив;
//Массив.Добавить(ОбъектМетаданных);
//СтруктураХранения = ПолучитьСтруктуруХраненияБазыДанных(Массив); // очень долго
//ЕстьТаблицаИзменений = СтруктураХранения.Найти("РегистрацияИзменений", "Назначение") <> Неопределено;
// Способ 4 Быстрый при небольшом количестве планов обмена, а при большом?
ОбъектыМетаданныхСРегистрациейИзменений = ирКэш.ОбъектыМетаданныхСРегистрациейИзменений();
ЕстьТаблицаИзменений = ОбъектыМетаданныхСРегистрациейИзменений[ОбъектМетаданных.ПолноеИмя()] <> Неопределено;
Возврат ЕстьТаблицаИзменений;
КонецФункции
Функция ПрочитатьНаборЗаписейВТаблицуЛкс(НаборЗаписей, НовыйРежимБлокировки = Неопределено) Экспорт
Если НовыйРежимБлокировки <> Неопределено Тогда
ирОбщий.ЗаблокироватьНаборЗаписейПоОтборуЛкс(НаборЗаписей, Истина, НовыйРежимБлокировки);
КонецЕсли;
ЭтоИмитатор = Истина
И Не ирКэш.ЛиПортативныйРежимЛкс()
И (Ложь
Или ТипЗнч(НаборЗаписей) = Тип("ОбработкаОбъект.ирИмитаторНаборЗаписей"));
Если ЭтоИмитатор Тогда
#Если Сервер И Не Сервер Тогда
НаборЗаписей = Обработки.ирИмитаторНаборЗаписей.Создать();
#КонецЕсли
НаборЗаписей.Прочитать(, Ложь);
Результат = НаборЗаписей.Выгрузить();
Иначе
#Если Сервер И Не Сервер Тогда
НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
#КонецЕсли
Данные = НаборЗаписей;
ПолноеИмяМД = НаборЗаписей.Метаданные().ПолноеИмя();
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ПолноеИмяМД);
Если ЛиКорневойТипРегистраБухгалтерииЛкс(КорневойТип) Тогда
// Чтобы в таблице правильно расставились субконто https://partners.v8.1c.ru/forum/t/1168440/m/1711008
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ Т.*
|ИЗ " + ПолноеИмяМД + "." + ПеревестиСтроку("ДвиженияССубконто") + "(,, Регистратор = &Регистратор) КАК Т
|";
Запрос.УстановитьПараметр("Регистратор", НаборЗаписей.Отбор.Регистратор.Значение);
ирОбщий.ЗаблокироватьНаборЗаписейПоОтборуЛкс(НаборЗаписей, Истина, РежимБлокировкиДанных.Разделяемый);
// Избавиться от NULL в колонках видов субконто надо, чтобы потом метод Загрузить не выдавал ошибку
Результат = ирОбщий.ТаблицаСКолонкамиБезТипаNullЛкс(Запрос.Выполнить().Выгрузить());
Иначе
НаборЗаписей.Прочитать();
Результат = НаборЗаписей.Выгрузить();
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект, ВызыватьИсключение = Истина) Экспорт
Структура = Новый Структура;
СтруктураОбменаДанными = СтруктураОбменаДаннымиОбъектаЛкс(Объект);
Если СтруктураОбменаДанными <> Неопределено Тогда
Структура.Вставить("ОбменДанными", СтруктураОбменаДанными);
КонецЕсли;
Если ТипЗнч(Объект) <> Тип("УдалениеОбъекта") Тогда
ДополнительныеСвойстваXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект.ДополнительныеСвойства,,, ВызыватьИсключение);
Структура.Вставить("ДополнительныеСвойстваXML", ДополнительныеСвойстваXML);
КонецЕсли;
Возврат Структура;
КонецФункции
Функция СтруктураОбменаДаннымиОбъектаЛкс(Знач Объект = Неопределено) Экспорт
Попытка
ОбменДанными = Объект.ОбменДанными;
Исключение
// Элемент плана обмена в 8.3.4-
ОбменДанными = Неопределено;
КонецПопытки;
Узлы = Новый Массив;
Если ОбменДанными <> Неопределено Тогда
Попытка
Получатели = ОбменДанными.Получатели;
Исключение
// Элемент плана обмена в 8.3.5+
Получатели = Неопределено;
КонецПопытки;
Если Получатели <> Неопределено Тогда
Для Каждого Получатель Из ОбменДанными.Получатели Цикл
Узлы.Добавить(Получатель);
КонецЦикла;
Автозаполнение = ОбменДанными.Получатели.Автозаполнение;
Отправитель = ОбменДанными.Отправитель;
Загрузка = ОбменДанными.Загрузка;
КонецЕсли;
КонецЕсли;
Получатели = Новый Структура;
Получатели.Вставить("Автозаполнение", Автозаполнение = Ложь);
Получатели.Вставить("Узлы", Узлы);
Результат = Новый Структура;
Результат.Вставить("Загрузка", Загрузка = Истина);
Результат.Вставить("Отправитель", Отправитель);
Результат.Вставить("Получатели", Получатели);
Возврат Результат;
КонецФункции // СериализоватьПараметрыОбменаДанными()
Процедура ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, СтруктураДополнительныхСвойств) Экспорт
Если СтруктураДополнительныхСвойств.Свойство("ОбменДанными") Тогда
ВосстановитьСтруктуруОбменаДаннымиОбъектаЛкс(Объект, СтруктураДополнительныхСвойств.ОбменДанными);
КонецЕсли;
Если ТипЗнч(Объект) <> Тип("УдалениеОбъекта") Тогда
ДополнительныеСвойства = ВосстановитьОбъектИзСтрокиXMLЛкс(СтруктураДополнительныхСвойств.ДополнительныеСвойстваXML);
Если ДополнительныеСвойства <> Неопределено Тогда
СкопироватьУниверсальнуюКоллекциюЛкс(ДополнительныеСвойства, Объект.ДополнительныеСвойства);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ВосстановитьСтруктуруОбменаДаннымиОбъектаЛкс(Знач Объект, Знач СтруктураОбменаДанными) Экспорт
Если СтруктураОбменаДанными = Неопределено Тогда
Возврат;
КонецЕсли;
Попытка
ОбменДанными = Объект.ОбменДанными;
Исключение
// Элемент плана обмена в 8.3.4-
Возврат;
КонецПопытки;
ЗаполнитьЗначенияСвойств(ОбменДанными, СтруктураОбменаДанными, "Загрузка");
Попытка
Получатели = Объект.Получатели;
Исключение
// Элемент плана обмена в 8.3.5+
Возврат;
КонецПопытки;
Если СтруктураОбменаДанными.Свойство("Получатели") Тогда
ЗаполнитьЗначенияСвойств(ОбменДанными.Получатели, СтруктураОбменаДанными.Получатели);
ОбменДанными.Получатели.Очистить();
Для Каждого Получатель Из СтруктураОбменаДанными.Получатели.Узлы Цикл
ОбменДанными.Получатели.Добавить(Получатель);
КонецЦикла;
КонецЕсли;
КонецПроцедуры // ВосстановитьПараметрыОбменаДаннымиЛкс()
// Записывает объект с параметризованным контекстом (клиент/сервер).
// Обеспечивает запись объекта с попытками. Позволяет обойти неинтенсивные дедлоки и превышения ожиданий блокировки.
// Также обеспечивает обход оптимистичных объектных блокировок в случае, если в БД пишутся точно те же данные объекта, что и актуальные.
// Эффективно для многопоточной записи объектов.
//
// Параметры:
// Объект - ОбъектБД - может вернуться другой экземпляр объекта, если имитаторы недоступны и объект записывается на сервере
// НаСервере - -
// РежимЗаписи - -
// РежимПроведения - -
// ОтключатьКонтрольЗаписи - -
// БезАвторегистрацииИзменений - -
// ПривилегированныйРежим - -
// ОтключатьЗаписьВерсии - -
//
Процедура ЗаписатьОбъектЛкс(Объект, Знач НаСервере = Неопределено, Знач РежимЗаписи = Неопределено, Знач РежимПроведения = Неопределено, Знач ОтключатьКонтрольЗаписи = Неопределено,
Знач БезАвторегистрацииИзменений = Неопределено, Знач ПривилегированныйРежим = Неопределено, ОтключатьЗаписьВерсии = Неопределено) Экспорт
//#Если Сервер И Не Клиент Тогда
// НаСервере = Ложь;
//#КонецЕсли
Если НаСервере = Неопределено Тогда
ПараметрыЗаписи = ирКэш.ПараметрыЗаписиОбъектовЛкс();
Если НаСервере = Неопределено Тогда
НаСервере = ПараметрыЗаписи.ОбъектыНаСервере;
КонецЕсли;
Если ОтключатьКонтрольЗаписи = Неопределено Тогда
ОтключатьКонтрольЗаписи = ПараметрыЗаписи.ОтключатьКонтрольЗаписи;
КонецЕсли;
Если ОтключатьЗаписьВерсии = Неопределено Тогда
ОтключатьЗаписьВерсии = ПараметрыЗаписи.ОтключатьЗаписьВерсии;
КонецЕсли;
Если БезАвторегистрацииИзменений = Неопределено Тогда
БезАвторегистрацииИзменений = ПараметрыЗаписи.БезАвторегистрацииИзменений;
КонецЕсли;
Если ПривилегированныйРежим = Неопределено Тогда
ПривилегированныйРежим = ПараметрыЗаписи.ПривилегированныйРежим;
КонецЕсли;
Для Каждого СтрокаДопСвойства Из ПараметрыЗаписи.ДополнительныеСвойства Цикл
Объект.ДополнительныеСвойства.Вставить(СтрокаДопСвойства.Имя, СтрокаДопСвойства.РасширенноеЗначение);
КонецЦикла;
Иначе
Если ОтключатьКонтрольЗаписи = Неопределено Тогда
ОтключатьКонтрольЗаписи = Ложь;
КонецЕсли;
Если ОтключатьЗаписьВерсии = Неопределено Тогда
ОтключатьЗаписьВерсии = Ложь;
КонецЕсли;
Если БезАвторегистрацииИзменений = Неопределено Тогда
БезАвторегистрацииИзменений = Ложь;
КонецЕсли;
Если ПривилегированныйРежим = Неопределено Тогда
ПривилегированныйРежим = Ложь;
КонецЕсли;
КонецЕсли;
Если Ложь
#Если Не Сервер Тогда
Или НаСервере
#КонецЕсли
Тогда
ТипОбъекта = ТипЗнч(Объект);
ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта);
Если ЭтоИмитатор Тогда
Объект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
Тогда
НужноВызватьИсключение = Ложь;
КонецЕсли;
КонецЕсли;
Если Не НужноВызватьИсключение Тогда
Если СчетчикПопыток = ПопытокЗаписиОбъекта Тогда
//НовоеОписаниеОшибки = "Кончились попытки записи" + Символы.ПС + ОписаниеОшибки;
НужноВызватьИсключение = Истина;
ИначеЕсли ТекущаяДата() - НачалоПопыток >= ПредельнаяДлительность Тогда
//НовоеОписаниеОшибки = "Кончилось время записи" + Символы.ПС + ОписаниеОшибки;
НужноВызватьИсключение = Истина;
ИначеЕсли СчетчикПопыток = ПопытокЗаписиОбъекта Тогда
//НовоеОписаниеОшибки = "Кончились попытки записи" + Символы.ПС + ОписаниеОшибки;
НужноВызватьИсключение = Истина;
КонецЕсли;
КонецЕсли;
#Если Клиент Тогда
Если ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(НОписаниеОшибки, Ложь) Тогда
ВызватьИсключение;
КонецЕсли;
#КонецЕсли
Если НужноВызватьИсключение Тогда
СостояниеОбъекта = ПредставлениеДопСвойствОбъектаЛкс(Объект);
Если ЗначениеЗаполнено(СостояниеОбъекта) Тогда
Если ЗначениеЗаполнено(НовоеОписаниеОшибки) Тогда
НовоеОписаниеОшибки = НовоеОписаниеОшибки + СостояниеОбъекта;
Иначе
НовоеОписаниеОшибки = ОписаниеОшибки + СостояниеОбъекта;
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(НовоеОписаниеОшибки) Тогда
ВызватьИсключение НовоеОписаниеОшибки;
Иначе
ВызватьИсключение;
КонецЕсли;
КонецЕсли;
КонецПопытки;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта) Экспорт
ЭтоИмитатор = Истина
И Не ирКэш.ЛиПортативныйРежимЛкс()
И (Ложь
Или ТипОбъекта = Тип("ОбработкаОбъект.ирИмитаторНаборЗаписей")
Или ТипОбъекта = Тип("ОбработкаОбъект.ирИмитаторКонстантаМенеджер")
Или ТипОбъекта = Тип("ОбработкаОбъект.ирИмитаторСсылочныйОбъект"));
Возврат ЭтоИмитатор;
КонецФункции
// Параметры:
// НаборЗаписейКуда - НаборЗаписей, ирИмитаторНаборЗаписей
// КоллекцияПолученаВыгрузкойНабора - Булево - используется при ЗаполнитьВидыСубконто = Истина
Процедура ЗагрузитьКоллекциюВНаборЗаписейЛкс(КоллекцияСтрокДвижений, НаборЗаписейКуда, ЗаполнитьВидыСубконто = Ложь, КоллекцияПолученаВыгрузкойНабора = Ложь) Экспорт
ТаблицаДляЗагрузки = НаборЗаписейКуда.ВыгрузитьКолонки();
Для Каждого СтрокаНовойТаблицы Из КоллекцияСтрокДвижений Цикл
ЗаполнитьЗначенияСвойств(ТаблицаДляЗагрузки.Добавить(), СтрокаНовойТаблицы);
КонецЦикла;
Если ЗаполнитьВидыСубконто Тогда
ОбъектМД = Метаданные.НайтиПоТипу(ТипОбъектаБДЛкс(НаборЗаписейКуда));
КорневойТип = ПервыйФрагментЛкс(ОбъектМД.ПолноеИмя());
Если ЛиКорневойТипРегистраБухгалтерииЛкс(КорневойТип) Тогда
ЗаполнитьВидыСубконтоВТаблицеЛкс(ТаблицаДляЗагрузки, ОбъектМД, КоллекцияПолученаВыгрузкойНабора);
КонецЕсли;
КонецЕсли;
НаборЗаписейКуда.Загрузить(ТаблицаДляЗагрузки);
//ирОбщий.НаборЗаписейПослеЗагрузкиИзТаблицыЗначенийЛкс(НаборЗаписейКуда); //Теперь это делается в ирОбщий.ЗаписатьОбъектЛкс()
КонецПроцедуры
Процедура ЗаполнитьВидыСубконтоВТаблицеЛкс(ТаблицаДляЗагрузки, ОбъектМД, ТаблицаПолученаВыгрузкойНабора = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаДляЗагрузки = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
ОбъектМД = ТаблицаДляЗагрузки.Метаданные();
#КонецЕсли
СписокСчетов = Новый Массив;
Для Каждого Проводка Из ТаблицаДляЗагрузки Цикл
СписокСчетов.Добавить(Проводка.СчетДт);
СписокСчетов.Добавить(Проводка.СчетКт);
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Т.НомерСтроки КАК НомерСтроки,
| Т.ВидСубконто КАК ВидСубконто,
| Т.Ссылка КАК Ссылка
|ИЗ
| " + ОбъектМД.ПланСчетов.ПолноеИмя() + ".ВидыСубконто КАК Т
|ГДЕ
| Т.Ссылка В(&Счет)
|УПОРЯДОЧИТЬ ПО ВидСубконто
|";
// Порядок видов субконто в Набор.Выгрузить() и "ВЫБРАТЬ * ИЗ Регистр" могут не совпадать https://partners.v8.1c.ru/forum/t/1168440/m/1711008
Запрос.УстановитьПараметр("Счет", СписокСчетов);
ТаблицаВидовСубконто = Запрос.Выполнить().Выгрузить();
МассивСторон = Новый Массив;
МассивСторон.Добавить("Дт");
МассивСторон.Добавить("Кт");
Для Каждого Проводка Из ТаблицаДляЗагрузки Цикл
Для Каждого Сторона Из МассивСторон Цикл
СтрокиВидовСубконто = ТаблицаВидовСубконто.НайтиСтроки(Новый Структура("Ссылка", Проводка["Счет" + Сторона]));
Счетчик = 1;
Для Каждого СтрокаВидаСубконто Из СтрокиВидовСубконто Цикл
Если ТаблицаПолученаВыгрузкойНабора Тогда
НомерСубконто = Счетчик;
Иначе
НомерСубконто = СтрокаВидаСубконто.НомерСтроки;
КонецЕсли;
Проводка["ВидСубконто" + Сторона + НомерСубконто] = СтрокаВидаСубконто.ВидСубконто;
Счетчик = Счетчик + 1;
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура УстановитьПометкуУдаленияОбъектаЛкс(Объект, НаСервере = Неопределено, ЗначениеПометки = Истина, БезАвторегистрацииИзменений = Неопределено,
ПривилегированныйРежим = Неопределено, ОтключатьЗаписьВерсии = Неопределено) Экспорт
Если НаСервере = Неопределено Тогда
ПараметрыЗаписи = ирКэш.ПараметрыЗаписиОбъектовЛкс();
Если НаСервере = Неопределено Тогда
НаСервере = ПараметрыЗаписи.ОбъектыНаСервере;
КонецЕсли;
Если БезАвторегистрацииИзменений = Неопределено Тогда
БезАвторегистрацииИзменений = ПараметрыЗаписи.БезАвторегистрацииИзменений;
КонецЕсли;
Если ПривилегированныйРежим = Неопределено Тогда
ПривилегированныйРежим = ПараметрыЗаписи.ПривилегированныйРежим;
КонецЕсли;
Если ОтключатьЗаписьВерсии = Неопределено Тогда
ОтключатьЗаписьВерсии = ПараметрыЗаписи.ОтключатьЗаписьВерсии;
КонецЕсли;
Для Каждого СтрокаДопСвойства Из ПараметрыЗаписи.ДополнительныеСвойства Цикл
Объект.ДополнительныеСвойства.Вставить(СтрокаДопСвойства.Имя, СтрокаДопСвойства.РасширенноеЗначение);
КонецЦикла;
КонецЕсли;
Если НаСервере Тогда
ТипОбъекта = ТипЗнч(Объект);
ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта);
Если ЭтоИмитатор Тогда
#Если Сервер И Не Сервер Тогда
Объект = Обработки.ирИмитаторСсылочныйОбъект.Создать();
#КонецЕсли
ОбъектXML = Объект.Снимок();
Иначе
ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект);
ОбъектXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
КонецЕсли;
ирСервер.УстановитьПометкуУдаленияОбъектаЛкс(ОбъектXML, ДополнительныеСвойства, ЗначениеПометки, БезАвторегистрацииИзменений, ТипОбъекта, ПривилегированныйРежим, ОтключатьЗаписьВерсии);
Если ЭтоИмитатор Тогда
Объект.ЗагрузитьСнимок(ОбъектXML);
Иначе
Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(ОбъектXML);
ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, ДополнительныеСвойства);
КонецЕсли;
#Если Клиент Тогда
ОповеститьОбИзменении(Объект.Ссылка);
#КонецЕсли
Иначе
Если ПривилегированныйРежим Тогда
УстановитьПривилегированныйРежим(Истина);
КонецЕсли;
УстановитьПараметрыЗаписиОбъектаЛкс(Объект, , БезАвторегистрацииИзменений, ОтключатьЗаписьВерсии);
//Если РежимЗаписи = Неопределено Тогда
// Объект.УстановитьПометкуУдаления(ЗначениеПометки);
//Иначе
Объект.УстановитьПометкуУдаления(ЗначениеПометки);
//КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура УдалитьОбъектЛкс(Знач Объект, Знач НаСервере = Неопределено, Знач ОтключатьКонтрольЗаписи = Неопределено, Знач БезАвторегистрацииИзменений = Неопределено,
ПривилегированныйРежим = Неопределено, ОтключатьЗаписьВерсии = Неопределено) Экспорт
Если НаСервере = Неопределено Тогда
ПараметрыЗаписи = ирКэш.ПараметрыЗаписиОбъектовЛкс();
Если НаСервере = Неопределено Тогда
НаСервере = ПараметрыЗаписи.ОбъектыНаСервере;
КонецЕсли;
Если ОтключатьКонтрольЗаписи = Неопределено Тогда
ОтключатьКонтрольЗаписи = ПараметрыЗаписи.ОтключатьКонтрольЗаписи;
КонецЕсли;
Если ОтключатьЗаписьВерсии = Неопределено Тогда
ОтключатьЗаписьВерсии = ПараметрыЗаписи.ОтключатьЗаписьВерсии;
КонецЕсли;
Если БезАвторегистрацииИзменений = Неопределено Тогда
БезАвторегистрацииИзменений = ПараметрыЗаписи.БезАвторегистрацииИзменений;
КонецЕсли;
Если ПривилегированныйРежим = Неопределено Тогда
ПривилегированныйРежим = ПараметрыЗаписи.ПривилегированныйРежим;
КонецЕсли;
Для Каждого СтрокаДопСвойства Из ПараметрыЗаписи.ДополнительныеСвойства Цикл
Объект.ДополнительныеСвойства.Вставить(СтрокаДопСвойства.Имя, СтрокаДопСвойства.РасширенноеЗначение);
КонецЦикла;
КонецЕсли;
УстановитьПараметрыЗаписиОбъектаЛкс(Объект, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений, ОтключатьЗаписьВерсии);
Если НаСервере Тогда
ТипОбъекта = ТипЗнч(Объект);
ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта);
Если ЭтоИмитатор Тогда
#Если Сервер И Не Сервер Тогда
Объект = Обработки.ирИмитаторСсылочныйОбъект.Создать();
#КонецЕсли
ОбъектXML = Объект.Снимок(, Ложь);
Иначе
ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект);
ОбъектXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
КонецЕсли;
ирСервер.УдалитьОбъектXMLЛкс(ОбъектXML, ДополнительныеСвойства, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений, ТипОбъекта, ПривилегированныйРежим, ОтключатьЗаписьВерсии);
//// https://partners.v8.1c.ru/forum/t/1728509/m/1728509 , https://www.hostedredmine.com/issues/893636
//// Вероятно теперь этот антибаг платформы больше не нужен, т.к. сделан другой - в самих имитаторах
//Если ЭтоИмитатор Тогда
//// Объект.ЗагрузитьСнимок(ОбъектXML);
// Объект.СброситьМодифицированность();
////Иначе
//// Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(ОбъектXML);
//// ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, ДополнительныеСвойства);
//КонецЕсли;
#Если Клиент Тогда
ОповеститьОбИзменении(Объект.Ссылка);
#КонецЕсли
Иначе
Если ПривилегированныйРежим Тогда
УстановитьПривилегированныйРежим(Истина);
КонецЕсли;
Объект.Удалить();
КонецЕсли;
КонецПроцедуры
// Продублирована в ирПортативныйСервер
Процедура УстановитьПараметрыЗаписиОбъектаЛкс(Знач Объект, ОтключатьКонтрольЗаписи = Неопределено, БезАвторегистрацииИзменений = Неопределено, ОтключатьЗаписьВерсии = Неопределено) Экспорт
Попытка
ОбменДанными = Объект.ОбменДанными;
Исключение
// Элемент плана обмена в 8.3.4-
ОбменДанными = Неопределено;
КонецПопытки;
Если ОбменДанными <> Неопределено Тогда
Если ОтключатьКонтрольЗаписи <> Неопределено Тогда
ОбменДанными.Загрузка = ОтключатьКонтрольЗаписи;
КонецЕсли;
Если БезАвторегистрацииИзменений <> Неопределено Тогда
Попытка
Получатели = ОбменДанными.Получатели;
Исключение
// Элемент плана обмена в 8.3.5+
Получатели = Неопределено;
КонецПопытки;
Если Получатели <> Неопределено Тогда
Получатели.Автозаполнение = Не БезАвторегистрацииИзменений;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Попытка
ЗаписьИсторииДанных = Объект.ЗаписьИсторииДанных;
Исключение
// 8.3.14-
ЗаписьИсторииДанных = Неопределено;
КонецПопытки;
Если ЗаписьИсторииДанных <> Неопределено Тогда
Если ОтключатьЗаписьВерсии <> Неопределено Тогда
ЗаписьИсторииДанных.Отказ = ОтключатьЗаписьВерсии;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Параметры:
// КлючОбъекта - Произвольный, *Неопределено - для нового ссылочного объекта Истина=Папка, для регистров передается Структура
// ЧитатьДанныеРегистраИлиКонстанты - Булево - применяется только если задан КлючОбъекта
Функция ОбъектБДПоКлючуЛкс(Знач ИмяОсновнойТаблицы, Знач КлючОбъекта = Неопределено, Знач СохранятьИдентификаторСсылки = Ложь, Знач ЧитатьДанныеРегистраИлиКонстанты = Истина,
Знач ОбъектыНаСервере = Неопределено, выхИдентификаторСсылки = Неопределено, РазрешитьВложенныйВызов = Истина, НомерВерсии = Неопределено) Экспорт
Если ОбъектыНаСервере = Неопределено Тогда
ПараметрыЗаписи = ирКэш.ПараметрыЗаписиОбъектовЛкс();
#Если Сервер И Не Клиент Тогда
ОбъектыНаСервере = Ложь;
#Иначе
//ОбъектыНаСервере = ирОбщий.ПолучитьРежимОбъектыНаСервереПоУмолчаниюЛкс();
ОбъектыНаСервере = ПараметрыЗаписи.ОбъектыНаСервере;
#КонецЕсли
КонецЕсли;
ТипОсновнойТаблицы = ирОбщий.ТипТаблицыБДЛкс(ИмяОсновнойТаблицы);
ЭтоМетаСсылка = ирОбщий.ЛиТипТаблицыМетассылкиЛкс(ТипОсновнойТаблицы);
РазрешитьИмитаторы = ОбъектыНаСервере <> Ложь И Не ирКэш.ЭтоФайловаяБазаЛкс() И Не ирКэш.ЛиПортативныйРежимЛкс() И Не ЭтоМетаСсылка И Не ирКэш.ПараметрыЗаписиОбъектовЛкс().НеИспользоватьИмитаторыОбъектовДанных;
мМетаданныеОбъекта = ирОбщий.ОбъектМДПоПолномуИмениТаблицыБДЛкс(ИмяОсновнойТаблицы, Истина);
Если мМетаданныеОбъекта = Неопределено Тогда
Если ЗначениеЗаполнено(ИмяОсновнойТаблицы) Тогда
ИмяОсновнойТаблицы = Неопределено;
КонецЕсли;
Иначе
мПолноеИмяМД = мМетаданныеОбъекта.ПолноеИмя();
КонецЕсли;
ЭтоСсылочныйОбъект = Ложь
Или ирОбщий.ЛиКорневойТипСсылкиЛкс(ТипОсновнойТаблицы)
Или (Истина
И ТипОсновнойТаблицы = "Внешняя"
И мМетаданныеОбъекта.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные);
Если Истина
И РазрешитьИмитаторы
И РазрешитьВложенныйВызов
И (Ложь
Или ЭтоСсылочныйОбъект
Или ОбъектыНаСервере = "Обязательно")
Тогда
СтруктураСнимка = ирСервер.ПолучитьСнимокОбъектаБДПоКлючуЛкс(ИмяОсновнойТаблицы, КлючОбъекта, СохранятьИдентификаторСсылки, ЧитатьДанныеРегистраИлиКонстанты, выхИдентификаторСсылки, НомерВерсии);
Если СтруктураСнимка <> Неопределено Тогда
Имитатор = Новый (СтруктураСнимка.ТипОбъекта);
#Если Сервер И Не Сервер Тогда
Имитатор = Обработки.ирИмитаторСсылочныйОбъект.Создать();
#КонецЕсли
Имитатор.ЗагрузитьСнимок(СтруктураСнимка.Снимок);
Результат = Новый Структура;
Результат.Вставить("Методы", Имитатор);
Результат.Вставить("Данные", Имитатор.Данные);
КонецЕсли;
Иначе
ЭтоКонстанта = ирОбщий.ЛиКорневойТипКонстантыЛкс(ТипОсновнойТаблицы);
ЭтоПланОбмена = ирОбщий.ЛиКорневойТипПланаОбменаЛкс(ТипОсновнойТаблицы);
ЭтоДокумент = ирОбщий.ЛиКорневойТипДокументаЛкс(ТипОсновнойТаблицы);
//ЭтоВнешнийОбъект = ТипОсновнойТаблицы = "Внешняя";
Если Ложь
Или Не ЗначениеЗаполнено(ТипОсновнойТаблицы)
Или (Истина
И ЭтоСсылочныйОбъект
И ТипЗнч(КлючОбъекта) = Тип("Строка"))
Тогда
Возврат Неопределено;
КонецЕсли;
Результат = Новый Структура;
Если ЭтоСсылочныйОбъект Тогда
Если ЭтоМетаСсылка Тогда
Объект = КлючОбъекта;
выхСтруктураОбъекта = КлючОбъекта;
Данные = Объект;
Методы = Объект;
Иначе
Если Истина
//И ЧитатьДанные
И ЛиТипСсылкиБДЛкс(ТипЗнч(КлючОбъекта))
И ЗначениеЗаполнено(КлючОбъекта)
Тогда
Если ЗначениеЗаполнено(НомерВерсии) Тогда
ИсторияДанныхМоя = Вычислить("ИсторияДанных");
#Если Сервер И Не Сервер Тогда
ИсторияДанныхМоя = ИсторияДанных;
#КонецЕсли
Объект = ИсторияДанныхМоя.СформироватьПоВерсии(КлючОбъекта, НомерВерсии);
Объект.ДополнительныеСвойства.Вставить("НомерЗагруженнойВерсии", НомерВерсии);
Иначе
Попытка
Объект = КлючОбъекта.ПолучитьОбъект();
Исключение
ПроверитьОшибкуПодписокНаКлиентеЛкс(ОписаниеОшибки());
ВызватьИсключение;
КонецПопытки;
//Если Объект <> Неопределено Тогда
// Объект.Прочитать(); // Получаем гарантировано свежие данные мимо объектного кэша, но объектный кэш не обновится https://partners.v8.1c.ru/forum/topic/1383852
//КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Объект = Неопределено Тогда
Если ЛиТипСсылкиБДЛкс(ТипЗнч(КлючОбъекта)) Тогда
Если ТипОсновнойТаблицы = "Внешняя" Тогда
#Если Сервер И Не Сервер Тогда
КлючОбъекта = ВнешниеИсточникиДанных.ВнешнийИсточникДанных1.Таблицы.Таблица1.ПустаяСсылка();
#КонецЕсли
выхИдентификаторСсылки = КлючОбъекта.Значение();
Иначе
#Если Сервер И Не Сервер Тогда
КлючОбъекта = Справочники.Валюты.ПустаяСсылка();
#КонецЕсли
выхИдентификаторСсылки = КлючОбъекта.УникальныйИдентификатор();
КонецЕсли;
ИначеЕсли Не СохранятьИдентификаторСсылки Тогда
выхИдентификаторСсылки = Неопределено;
КонецЕсли;
Если КлючОбъекта <> "" Тогда
ЭтоГруппаДляНового = КлючОбъекта = Истина;
Попытка
Объект = ирОбщий.СоздатьСсылочныйОбъектПоМетаданнымЛкс(мПолноеИмяМД, ЭтоГруппаДляНового, выхИдентификаторСсылки);
Исключение
// Может не быть прав на создание объекта
СообщитьЛкс("Ошибка создания объекта: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
КонецЕсли;
КонецЕсли;
Данные = Объект;
Методы = Объект;
//#Если Не Клиент И Сервер Тогда
Если РазрешитьИмитаторы Тогда
ИмитаторОбъекта = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИмитаторСсылочныйОбъект");
#Если Сервер И Не Сервер Тогда
ИмитаторОбъекта = Обработки.ирИмитаторСсылочныйОбъект.Создать();
#КонецЕсли
ИмитаторОбъекта.Конструктор(Объект);
Данные = ИмитаторОбъекта.Данные;
Методы = ИмитаторОбъекта;
КонецЕсли;
//#КонецЕсли
КонецЕсли;
Иначе
Если РазрешитьИмитаторы Тогда
Если ЭтоКонстанта Тогда
ИмитаторОбъекта = Обработки.ирИмитаторКонстантаМенеджер.Создать();
ИмитаторОбъекта.КонструкторПоКлючу(ИмяОсновнойТаблицы);
Иначе
ИмитаторОбъекта = Обработки.ирИмитаторНаборЗаписей.Создать();
ИмитаторОбъекта.КонструкторПоКлючу(ИмяОсновнойТаблицы, КлючОбъекта);
КонецЕсли;
Данные = ИмитаторОбъекта.Данные;
Методы = ИмитаторОбъекта;
Иначе
Если ЭтоКонстанта Тогда
Объект = Новый (СтрЗаменить(ИмяОсновнойТаблицы, ".", "МенеджерЗначения."));
Иначе
Объект = Новый (ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ИмяОсновнойТаблицы));
#Если Сервер И Не Сервер Тогда
Объект = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
#КонецЕсли
Если КлючОбъекта <> Неопределено Тогда
ЗаполнитьОтборПоКлючуЛкс(Объект.Отбор, КлючОбъекта);
КонецЕсли;
КонецЕсли;
Данные = Объект;
Методы = Объект;
КонецЕсли;
Если КлючОбъекта <> Неопределено И ЧитатьДанныеРегистраИлиКонстанты Тогда
Методы.Прочитать();
КонецЕсли;
КонецЕсли;
Результат.Вставить("Данные", Данные);
Результат.Вставить("Методы", Методы);
Возврат Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ЗаполнитьОтборПоКлючуЛкс(Знач Отбор, Знач КлючОбъекта) Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый ПостроительЗапроса;
Отбор = Пустышка.Отбор;
#КонецЕсли
Для Каждого ЭлементОтбора Из Отбор Цикл
СтруктураЧтенияЗначения = Новый Структура(ЭлементОтбора.Имя, null);
ЗаполнитьЗначенияСвойств(СтруктураЧтенияЗначения, КлючОбъекта);
Если СтруктураЧтенияЗначения[ЭлементОтбора.Имя] <> Null Тогда
Отбор[ЭлементОтбора.Имя].Установить(КлючОбъекта[ЭлементОтбора.Имя]);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция МетаданныеОбъектаБДЛкс(Знач ОбъектБД) Экспорт
Если ТипЗнч(ОбъектБД) = Тип("УдалениеОбъекта") Тогда
ОбъектМД = ОбъектБД.Ссылка.Метаданные();
Иначе
ТипОбъекта = ТипОбъектаБДЛкс(ОбъектБД);
ОбъектМД = Метаданные.НайтиПоТипу(ТипОбъекта);
КонецЕсли;
Возврат ОбъектМД;
КонецФункции
Функция ТипОбъектаБДЛкс(ОбъектБД) Экспорт
Результат = ТипЗнч(ОбъектБД);
Если Результат = Тип("Структура") Тогда
Имитатор = ОбъектБД.Методы;
Иначе
Имитатор = ОбъектБД;
КонецЕсли;
Результат = ТипЗнч(Имитатор);
Если ЭтоТипИмитатораОбъектаЛкс(Результат) Тогда
Результат = Имитатор._Тип;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция КопияОбъектаБДЛкс(СтруктураОбъекта) Экспорт
СтруктураОбъекта = СтруктураОбъекта.Методы.Скопировать();
Если ТипЗнч(СтруктураОбъекта) <> Тип("Структура") Тогда
СтруктураОбъектаНовая = Новый Структура;
СтруктураОбъектаНовая.Вставить("Методы", СтруктураОбъекта);
СтруктураОбъектаНовая.Вставить("Данные", СтруктураОбъекта);
СтруктураОбъекта = СтруктураОбъектаНовая;
КонецЕсли;
Возврат СтруктураОбъекта;
КонецФункции
// Функция - Скопировать таблицу
//
// Параметры:
// ТаблицаИлиТабличнаяЧасть - -
// ПараметрыОтбора - -
// Колонки - -
// БезТиповКолонок - Булево - полезно для создания максимально компактной таблицы
//
// Возвращаемое значение:
// - ТаблицаЗначений
//
Функция СкопироватьТаблицуЛкс(ТаблицаИлиТабличнаяЧасть, ПараметрыОтбора = Неопределено, Колонки = Неопределено, БезТиповКолонок = Ложь) Экспорт
Если ТипЗнч(ТаблицаИлиТабличнаяЧасть) = Тип("ТаблицаЗначений") Тогда
Результат = ТаблицаИлиТабличнаяЧасть.Скопировать(ПараметрыОтбора, Колонки);
Иначе
Результат = ТаблицаИлиТабличнаяЧасть.Выгрузить(ПараметрыОтбора, Колонки);
КонецЕсли;
#Если Сервер И Не Сервер Тогда
Результат = Новый ТаблицаЗначений;
#КонецЕсли
Если БезТиповКолонок Тогда
//РезультатБезТипов = СкопироватьКолонкиКоллекцииЛкс(Результат,, Истина);
//ЗагрузитьВТаблицуЗначенийЛкс(РезультатБезТипов, Результат);
Для Каждого Колонка Из Результат.Колонки Цикл
Если Колонка.ТипЗначения.Типы().Количество() > 0 Тогда
ИзменитьТипКолонкиТаблицыЗначенийЛкс(Результат, Колонка.Имя, Новый ОписаниеТипов);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПредставлениеДопСвойствОбъектаЛкс(Объект)
Попытка
ДополнительныеСвойства = Объект.ДополнительныеСвойства;
Исключение
ДополнительныеСвойства = Новый Структура;
КонецПопытки;
СостояниеОбъекта = "";
Для Каждого КлючИЗначение Из ДополнительныеСвойства Цикл
Если ЛиСсылкаНаОбъектБДЛкс(КлючИЗначение.Значение) И ТранзакцияАктивна() Тогда
// На случай сломанной транзакции
ПредставлениеЗначения = ирОбщий.ПолныйИдентификаторСсылкиЛкс(КлючИЗначение.Значение);
Иначе
ПредставлениеЗначения = "" + КлючИЗначение.Значение;
КонецЕсли;
СостояниеОбъекта = СостояниеОбъекта + Символы.ПС + КлючИЗначение.Ключ + ": " + ПредставлениеЗначения;
КонецЦикла;
Возврат СостояниеОбъекта;
КонецФункции
Функция ПрочитатьДвиженияДокументаПакетноЛкс(Ссылка, ОбъектыНаСервере = Неопределено, ТолькоКоличествоСтрок = Ложь) Экспорт
ОбъектМД = Ссылка.Метаданные();
ОбъектыМД = ирОбщий.ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(ОбъектМД, Истина, Истина);
Результат = Новый Соответствие;
Если ОбъектыМД.Количество() > 0 Тогда
Текст = "";
Для Каждого МетаРегистр из ОбъектыМД Цикл
Если Текст <> "" Тогда
Текст = Текст + ";" + Символы.ПС;
КонецЕсли;
ПолноеИмяМДРегистра = МетаРегистр.ПолноеИмя();
ИмяТаблицыБДРегистра = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМДРегистра);
Если ТолькоКоличествоСтрок Тогда
Текст = Текст + "ВЫБРАТЬ Количество(*)";
Иначе
Текст = Текст + "ВЫБРАТЬ Т.*";
КонецЕсли;
Если ТипТаблицыБДЛкс(ИмяТаблицыБДРегистра) = "ДвиженияССубконто" Тогда
Текст = Текст + "
|ИЗ " + ИмяТаблицыБДРегистра + "(,, Регистратор = &Ссылка) КАК Т";
Иначе
ИмяПоляОтбора = ИмяПоляОтбораПодчиненногоНабораЗаписейЛкс(ИмяТаблицыБДРегистра);
Текст = Текст + "
|ИЗ " + ИмяТаблицыБДРегистра + " КАК Т
|ГДЕ Т." + ИмяПоляОтбора + " = &Ссылка";
КонецЕсли;
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Текст = Текст;
Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатПакета = Запрос.ВыполнитьПакет();
ИндексВПакете = 0;
Для Каждого МетаРегистр из ОбъектыМД Цикл
ПолноеИмяМДРегистра = МетаРегистр.ПолноеИмя();
ИмяТаблицыБДРегистра = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМДРегистра);
Результат[ПолноеИмяМДРегистра] = ТаблицаСКолонкамиБезТипаNullЛкс(РезультатПакета[ИндексВПакете].Выгрузить());
Если ТолькоКоличествоСтрок Тогда
Результат[ПолноеИмяМДРегистра] = Результат[ПолноеИмяМДРегистра][0][0];
КонецЕсли;
ИндексВПакете = ИндексВПакете + 1;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ИмяПоляОтбораПодчиненногоНабораЗаписейЛкс(Знач ИмяТаблицыБДРегистра) Экспорт
ТипТаблицы = ТипТаблицыБДЛкс(ИмяТаблицыБДРегистра);
Если ТипТаблицы = "Перерасчет" Тогда
ИмяПоля = "ОбъектПерерасчета";
Иначе
ИмяПоля = "Регистратор";
КонецЕсли;
ИмяПоля = ирОбщий.ПеревестиСтроку(ИмяПоля);
Возврат ИмяПоля;
КонецФункции
// Позволяет перечитать объект грязным чтением, т.е. без учета блокировок. Не перечитывает свойство ВерсияДанных!
// На выходе объект имеет модифицированноть. Для удаленного объекта возвращает Неопределено.
Функция ПеречитатьОбъектЗапросомЛкс(Знач Объект) Экспорт
ОбъектМД = Объект.Метаданные();
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ * ИЗ " + ОбъектМД.ПолноеИмя() + " КАК Т ГДЕ Т.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка);
ТаблицаОбъекта = Запрос.Выполнить().Выгрузить();
Если ТаблицаОбъекта.Количество() > 0 Тогда
СтрокаДанных = ТаблицаОбъекта[0];
Для Каждого КолонкаТаблицы Из ТаблицаОбъекта.Колонки Цикл
ЗначениеРеквизита = СтрокаДанных[КолонкаТаблицы.Имя];
Если ЗначениеРеквизита = Null Тогда
// Реквизит (но не табличная часть) недоступен по признаку ЭтоГруппа. Если к нему обратиться у объекта, то будет ошибка "Ошибка установки значения свойства '...': Реквизит недоступен для группы"
Продолжить;
КонецЕсли;
Пустышка = Объект[КолонкаТаблицы.Имя]; // Проверяем корректность вычисления выражения перед его использованием в попытке
Если КолонкаТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
Попытка
Объект[КолонкаТаблицы.Имя].Загрузить(ЗначениеРеквизита);
Исключение
// Табличная часть недоступна по признаку ЭтоГруппа. Выдается ошибка "Ошибка при вызове метода контекста (Загрузить): Объект недоступен для изменения"
КонецПопытки;
Иначе
Попытка
Объект[КолонкаТаблицы.Имя] = ЗначениеРеквизита;
Исключение
// Реквизит предназначен только для чтения
КонецПопытки;
КонецЕсли;
КонецЦикла;
Иначе
Объект = Неопределено;
КонецЕсли;
Возврат Объект;
КонецФункции
// Антибаг платформы https://partners.v8.1c.ru/forum/topic/1168440
Процедура НаборЗаписейПослеЗагрузкиИзТаблицыЗначенийЛкс(Знач НаборЗаписей) Экспорт
ЭтоИмитатор = Истина
И Не ирКэш.ЛиПортативныйРежимЛкс()
И (Ложь
Или ТипЗнч(НаборЗаписей) = Тип("ОбработкаОбъект.ирИмитаторНаборЗаписей"));
Если ЭтоИмитатор Тогда
Возврат;
Иначе
#Если Сервер И Не Сервер Тогда
НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
#КонецЕсли
Данные = НаборЗаписей;
ОбъектМД = НаборЗаписей.Метаданные();
КонецЕсли;
КорневойТип = ПервыйФрагментЛкс(ОбъектМД.ПолноеИмя());
Если ЛиКорневойТипРегистраБухгалтерииЛкс(КорневойТип) Тогда
Для Каждого Проводка Из Данные Цикл
ОчиститьПоляРегистраБухгалтерииПоПризнакамУчетаЛкс(Проводка, ОбъектМД.Ресурсы, ОбъектМД);
ОчиститьПоляРегистраБухгалтерииПоПризнакамУчетаЛкс(Проводка, ОбъектМД.Измерения, ОбъектМД);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ОчиститьПоляРегистраБухгалтерииПоПризнакамУчетаЛкс(Проводка, КоллекцияПолей, ОбъектМД) Экспорт
#Если Сервер И Не Сервер Тогда
Проводка = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей().Добавить();
ОбъектМД = Метаданные.РегистрыБухгалтерии.Хозрасчетный;
#КонецЕсли
Для Каждого Поле Из КоллекцияПолей Цикл
Если Истина
И Не Поле.Балансовый
И Поле.ПризнакУчета <> Неопределено
Тогда
ИмяПризнакаУчета = Поле.ПризнакУчета.Имя;
Если ОбъектМД.Корреспонденция Тогда
Если Не Проводка.СчетДт[ИмяПризнакаУчета] Тогда
ПрисвоитьЕслиНеРавноЛкс(Проводка[Поле.Имя + "Дт"], Неопределено);
КонецЕсли;
Если Не Проводка.СчетКт[ИмяПризнакаУчета] Тогда
ПрисвоитьЕслиНеРавноЛкс(Проводка[Поле.Имя + "Кт"], Неопределено);
КонецЕсли;
Иначе
Если Не Проводка.Счет[ИмяПризнакаУчета] Тогда
ПрисвоитьЕслиНеРавноЛкс(Проводка[Поле.Имя], Неопределено);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Источник - 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";
Если ВариантРасположенияФайлаНастроек = ВариантыРасположения.ПеренаправлениеТекущейВерсии Тогда
ФайлУказатель = Новый Файл(КаталогКонфигурацииПриложения + "\conf.cfg");
Если ФайлУказатель.Существует() Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ФайлУказатель.ПолноеИмя);
Текст = ТекстовыйДокумент.ПолучитьТекст();
НовыйКаталогКонфигурацииПриложения = СтрокаМеждуМаркерамиЛкс(Текст, "ConfLocation=", Символы.ПС);
НовыйКаталог = Новый Файл(НовыйКаталогКонфигурацииПриложения);
Если НовыйКаталог.Существует() Тогда
КаталогКонфигурацииПриложения = НовыйКаталогКонфигурацииПриложения;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СоздатьЕслиОтсутствует Тогда
Файл = Новый Файл(КаталогКонфигурацииПриложения);
Если Не Файл.Существует() Тогда
СоздатьКаталог(КаталогКонфигурацииПриложения);
КонецЕсли;
КонецЕсли;
Результат = КаталогКонфигурацииПриложения;
КонецЕсли;
Возврат Результат;
КонецФункции
// выхВариантРасположенияФайлаНастроек -
// ДляТекущейВерсии
// ПеренаправлениеТекущейВерсии - использовать значение ключа ConfLocation из файла conf.cfg
// ДляТекущегоПользователя
Функция ПолноеИмяФайлаНастройкиПриложения1СЛкс(КраткоеИмяФайла, НаСервере = Ложь, выхВариантРасположенияФайлаНастроек = Неопределено, выхДатаИзменения = Неопределено) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ПолучитьПолноеИмяФайлаНастройкиПриложения1СЛкс(КраткоеИмяФайла,, выхВариантРасположенияФайлаНастроек, выхДатаИзменения);
Иначе
ВариантыРасположения = ВариантыРасположенияКонфигурационногоФайлаЛкс();
выхВариантРасположенияФайлаНастроек = ВариантыРасположения.ДляТекущегоПользователя;
КаталогКонфигурацииПриложения = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс() + "\conf";
Результат = КаталогКонфигурацииПриложения + "\" + КраткоеИмяФайла;
Файл = Новый Файл(Результат);
ФайлСуществует = Файл.Существует();
Если Не ФайлСуществует Тогда
выхВариантРасположенияФайлаНастроек = ВариантыРасположения.ДляТекущейВерсии;
КаталогКонфигурацииПриложения = КаталогПрограммы() + "conf";
Результат = КаталогКонфигурацииПриложения + "\" + КраткоеИмяФайла;
Файл = Новый Файл(Результат);
ФайлСуществует = Файл.Существует();
Если Не ФайлСуществует Тогда
выхВариантРасположенияФайлаНастроек = ВариантыРасположения.ПеренаправлениеТекущейВерсии;
ФайлУказатель = Новый Файл(КаталогКонфигурацииПриложения + "\conf.cfg");
Если ФайлУказатель.Существует() Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ФайлУказатель.ПолноеИмя);
Текст = ТекстовыйДокумент.ПолучитьТекст();
НовыйКаталогКонфигурацииПриложения = СтрокаМеждуМаркерамиЛкс(Текст, "ConfLocation=", Символы.ПС);
НовыйКаталог = Новый Файл(НовыйКаталогКонфигурацииПриложения);
Если НовыйКаталог.Существует() Тогда
КаталогКонфигурацииПриложения = НовыйКаталогКонфигурацииПриложения;
Результат = КаталогКонфигурацииПриложения + "\" + КраткоеИмяФайла;
Файл = Новый Файл(Результат);
ФайлСуществует = Файл.Существует();
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ФайлСуществует Тогда
Результат = Неопределено;
выхВариантРасположенияФайлаНастроек = Неопределено;
Иначе
выхДатаИзменения = Файл.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс();
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ТекстКонфигурационногоФайлаВнешнихСоединенийЛкс(АдресОтладчика = "") Экспорт
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст("
|
//|
|
|"
);
Возврат ТекстовыйДокумент;
КонецФункции
Функция ИмяФайлаАктивнойНастройкиТехноЖурналаЛкс(НаСервере = Ложь) Экспорт
Результат = ПолноеИмяФайлаНастройкиПриложения1СЛкс("logcfg.xml", НаСервере);
Возврат Результат;
КонецФункции
Функция КаталогТехножурналаЛкс(НаСервере = Ложь) Экспорт
ИмяФайлаНастроекЖурнала = ИмяФайлаАктивнойНастройкиТехноЖурналаЛкс(НаСервере);
Если ЗначениеЗаполнено(ИмяФайлаНастроекЖурнала) Тогда
ТекстХМЛ = ПрочитатьТекстИзФайлаЛкс(ИмяФайлаНастроекЖурнала, , НаСервере);
ЧтениеХМЛ = Новый ЧтениеXML;
ЧтениеХМЛ.УстановитьСтроку(ТекстХМЛ);
ПостроительДом = Новый ПостроительDOM();
Попытка
ДокументДОМ = ПостроительДом.Прочитать(ЧтениеХМЛ);
Исключение
СообщитьЛкс("Ошибка чтения настройки техножурнала: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
Если ДокументДОМ <> Неопределено Тогда
Узлы = ДокументДом.ПолучитьЭлементыПоИмени("log");
Если Узлы.Количество() > 0 Тогда
Атрибут = Узлы.Элемент(0).Атрибуты.ПолучитьИменованныйЭлемент("location");
Если Атрибут <> Неопределено Тогда
Результат = Атрибут.ТекстовоеСодержимое;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиТехножурналВключенЛкс(НаСервере = Ложь, ВыводитьСообщения = Ложь, РазрешитьИспользоватьПутьСКлиентаНаСервер = Ложь) Экспорт
КаталогЖурнала = "";
КаталогЖурналаВзятИзНастроекЧтения = Ложь;
Если НаСервере И РазрешитьИспользоватьПутьСКлиентаНаСервер Тогда
#Если Клиент Тогда
КаталогЖурнала = ирОбщий.ВосстановитьЗначениеЛкс("ирАнализТехножурнала.КаталогЖурналаСервера");
КаталогЖурналаВзятИзНастроекЧтения = Истина;
#КонецЕсли
КонецЕсли;
Если Не ЗначениеЗаполнено(КаталогЖурнала) Тогда
КаталогЖурнала = КаталогТехножурналаЛкс(НаСервере);
КаталогЖурналаВзятИзНастроекЧтения = Ложь;
КонецЕсли;
Если ЗначениеЗаполнено(КаталогЖурнала) Тогда
Если Не ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала, НаСервере, ВыводитьСообщения) Тогда
Возврат Истина;
Иначе
Если ВыводитьСообщения Тогда
Если КаталогЖурналаВзятИзНастроекЧтения Тогда
СообщитьЛкс("Каталог техножурнала """ + КаталогЖурнала + """ недоступен. Использован каталог, заданный в настройках чтения анализа техножурнала", СтатусСообщения.Внимание);
Иначе
СообщитьЛкс("Каталог техножурнала """ + КаталогЖурнала + """ недоступен. Использован каталог, заданный в текущей настройке техножурнала", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Если ВыводитьСообщения Тогда
Если НаСервере Тогда
СообщитьЛкс("Каталог техножурнала сервера не удалось прочитать из текущей настройки техножурнала и не задан в настройках чтения инструмента ""Анализ техножурнала""");
Иначе
СообщитьЛкс("Каталог техножурнала клиента не удалось прочитать из текущей настройки техножурнала");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала, НаСервере = Ложь, ВыводитьСообщения = Истина) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала);
Иначе
Результат = Ложь;
ФайлКаталог = Новый Файл(КаталогЖурнала);
Если Не ФайлКаталог.Существует() Тогда
Результат = Истина;
Иначе
БлокирующиеФайлы = НайтиФайлы(КаталогЖурнала, "*.*");
Счетчик = 0;
Для Каждого БлокирующийФайл Из БлокирующиеФайлы Цикл
Счетчик = Счетчик + 1;
Если Счетчик > 100 Тогда
// Ускорена проверка доступности каталога техножурнала при очень большом числе подкаталогов в нем http://www.hostedredmine.com/issues/850582
Прервать;
КонецЕсли;
Если Не БлокирующийФайл.ЭтоКаталог() Тогда
Если ВыводитьСообщения Тогда
ТекстСообщения = "В корне каталога """ + КаталогЖурнала + """ техножурнала ";
Если НаСервере Тогда
ТекстСообщения = ТекстСообщения + "сервера";
Иначе
ТекстСообщения = ТекстСообщения + "клиента";
КонецЕсли;
СообщитьЛкс(ТекстСообщения + " обнаружены блокирующие файлы. Для работы журнала их необходимо удалить.", СтатусСообщения.Внимание);
КонецЕсли;
Результат = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиКлиентЗапущенНаКомпьютереСервераЛкс() Экспорт
Результат = НРег(ирСервер.ИмяКомпьютераЛкс()) = НРег(ИмяКомпьютера());
Возврат Результат;
КонецФункции
Функция ЗаписатьТекстВФайлЛкс(ПолноеИмяФайла, Текст, Кодировка = Неопределено, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
ирСервер.ЗаписатьТекстВФайлЛкс(ПолноеИмяФайла, Текст, Кодировка);
Иначе
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(Текст);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
ТекстовыйДокумент.Записать(ИмяВременногоФайла, Кодировка);
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
мПлатформа.ПереместитьФайлКакАдминистратор(ИмяВременногоФайла, ПолноеИмяФайла);
КонецЕсли;
КонецФункции
Функция ПрочитатьТекстИзФайлаЛкс(ПолноеИмяФайла, Кодировка = Неопределено, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ПрочитатьТекстИзФайлаЛкс(ПолноеИмяФайла, Кодировка);
Иначе
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ПолноеИмяФайла, Кодировка);
Результат = ТекстовыйДокумент.ПолучитьТекст();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НайтиИменаФайловЛкс(Путь, Маска = Неопределено, ИскатьВПодкаталогах = Истина, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
Результат = ирСервер.НайтиИменаФайловЛкс(Путь, Маска, ИскатьВПодкаталогах);
Иначе
Файлы = НайтиФайлы(Путь, Маска, ИскатьВПодкаталогах);
Результат = Новый Массив;
Для Каждого Файл Из Файлы Цикл
Результат.Добавить(Файл.ПолноеИмя);
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ИзданиеПлатформы - Строка(0,П)
//
Функция КаталогПустойИнфобазыЛкс(Знач ИзданиеПлатформы = "") Экспорт
Если Не ЗначениеЗаполнено(ИзданиеПлатформы) Тогда
ИзданиеПлатформы = ирКэш.НомерИзданияПлатформыЛкс();
КонецЕсли;
КаталогПустойИнфобазы = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс(, ИзданиеПлатформы) + "\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=""" + КаталогПустойИнфобазы + """;";
КонецЕсли;
КодВозврата = Неопределено;
ИмяФайлаЛога = ПолучитьИмяВременногоФайла("txt");
Если Не ЗначениеЗаполнено(ПолноеИмяИсполняемогоФайла) Тогда
ПолноеИмяИсполняемогоФайла = ПолноеИмяИсполняемогоФайлаКонфигуратораЛкс();
КонецЕсли;
ДополнительныеПараметры = "/Out""" + ИмяФайлаЛога + """ " + КомандаКонфигуратора;
ПараметрыПакетногоЗапуска = ПараметрыЗапускаПриложения1СЛкс(ИмяПользователя, ПарольПользователя,, Истина,,,, ДополнительныеПараметры, СообщитьСтрокуПараметров,
СтрокаСоединенияБазы,,,, ЗначениеЗаполнено(ИмяПользователя), КодЯзыка);
Если ПодавлятьДиалоги Тогда
ПараметрыПакетногоЗапуска = ПараметрыПакетногоЗапуска + " /DisableStartupDialogs /DisableStartupMessages";
КонецЕсли;
#Если Клиент Тогда
Если СтрокиРавныЛкс(СтрокаСоединенияБазы, СтрокаСоединенияИнформационнойБазы()) И Не ЗначениеЗаполнено(ИмяПользователя) Тогда
Если ирКэш.НомерВерсииПлатформыЛкс() > 802014 Тогда
Выполнить("ЗапуститьСистему(ПараметрыПакетногоЗапуска, ДождатьсяЗавершения, КодВозврата)");
Иначе
ЗапуститьСистему(ПараметрыПакетногоЗапуска, ДождатьсяЗавершения);
КодВозврата = 0;
КонецЕсли;
Иначе
#КонецЕсли
СтрокаКоманды = """" + ПолноеИмяИсполняемогоФайла + """ " + ПараметрыПакетногоЗапуска;
Если ирКэш.НомерВерсииПлатформыЛкс() > 802014 Тогда
Выполнить("ЗапуститьПриложение(СтрокаКоманды,, ДождатьсяЗавершения, КодВозврата)");
Иначе
ЗапуститьПриложение(СтрокаКоманды,, ДождатьсяЗавершения);
КодВозврата = 0;
КонецЕсли;
#Если Клиент Тогда
КонецЕсли;
#КонецЕсли
ФайлЛога = Новый Файл(ИмяФайлаЛога);
Если ФайлЛога.Существует() Тогда
ТекстовыйДокументЛога = Новый ТекстовыйДокумент;
ТекстовыйДокументЛога.Прочитать(ФайлЛога.ПолноеИмя);
выхТекстЛога = ТекстовыйДокументЛога.ПолучитьТекст();
КонецЕсли;
Возврат КодВозврата = 0;
КонецФункции
Процедура ЗаполнитьСписокАдминистраторовБазыЛкс(Знач СписокАдминистраторов) Экспорт
#Если Сервер И Не Сервер Тогда
СписокАдминистраторов = Новый СписокЗначений;
#КонецЕсли
СписокАдминистраторов.Очистить();
Для Каждого Пользователь Из ПользователиИнформационнойБазы.ПолучитьПользователей() Цикл
#Если Сервер И Не Сервер Тогда
Пользователь = ПользователиИнформационнойБазы.СоздатьПользователя();
#КонецЕсли
Если ПравоДоступа("Администрирование", Метаданные, Пользователь) Тогда
СписокАдминистраторов.Добавить(Пользователь.Имя);
КонецЕсли;
КонецЦикла;
СписокАдминистраторов.СортироватьПоПредставлению();
КонецПроцедуры
// р5яф67оыйи
Функция ПараметрыЗапускаСеансаТекущиеЛкс(Знач ИдентификаторПроцессаОС = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(ИдентификаторПроцессаОС) Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ИдентификаторПроцессаОС = мПлатформа.ИдентификаторПроцессаОС();
КонецЕсли;
Результат = "";
ТекущийПроцесс = ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2:Win32_Process.Handle='" + XMLСтрока(ИдентификаторПроцессаОС) + "'");
КоманднаяСтрокаПроцесса = ТекущийПроцесс.CommandLine;
ВычислительРегулярныхВыражений = Новый COMОбъект("VBScript.RegExp");
ВычислительРегулярныхВыражений.IgnoreCase = Истина;
ВычислительРегулярныхВыражений.Global = Истина;
ВычислительРегулярныхВыражений.Pattern = "(/DebuggerUrl\s*.+?)(?: /|$)";
Вхождения = ВычислительРегулярныхВыражений.Execute(КоманднаяСтрокаПроцесса);
Если Вхождения.Count > 0 Тогда
Результат = Вхождения.Item(Вхождения.Count - 1).SubMatches(0);
КонецЕсли;
ВычислительРегулярныхВыражений.Pattern = "(/Debug\s+.+?)(?: /|$)";
Вхождения = ВычислительРегулярныхВыражений.Execute(КоманднаяСтрокаПроцесса);
Если Вхождения.Count > 0 Тогда
СтрокаОтладчика = Вхождения.Item(Вхождения.Count - 1).SubMatches(0);
Иначе
СтрокаОтладчика = "/Debug";
КонецЕсли;
Результат = Результат + " " + СтрокаОтладчика;
СохраняемыеПараметры = Новый Массив;
СохраняемыеПараметры.Добавить("TechnicalSpecialistMode");
СохраняемыеПараметры.Добавить("UseHwLicenses");
СохраняемыеПараметры.Добавить("L");
СохраняемыеПараметры.Добавить("VL");
//СохраняемыеПараметры.Добавить("C"); // Нельзя сохранять парамерт запуска, т.к. он часто разовый
СохраняемыеПараметры.Добавить("UC");
Для Каждого ИмяПараметра Из СохраняемыеПараметры Цикл
ВычислительРегулярныхВыражений.Pattern = "(/" + ИмяПараметра + ".*?)(?: /|$)";
Вхождения = ВычислительРегулярныхВыражений.Execute(КоманднаяСтрокаПроцесса);
Если Вхождения.Count > 0 Тогда
ПараметрКоманднойСтроки = Вхождения.Item(Вхождения.Count - 1).SubMatches(0);
Результат = Результат + " " + ПараметрКоманднойСтроки;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
// Создает 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 По 10 Цикл
ОбработкаПрерыванияПользователя();
Попытка
Соединение.Visible = Видимость;
Прервать;
Исключение
// Тонкий клиент еще не готов
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
ПаузаЛкс(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 = Истина, ИмяФайла = "", ВызыватьИсключение = Истина, Поток = Неопределено, Знач Сериализатор = Неопределено) Экспорт
Если Сериализатор = Неопределено Тогда
Сериализатор = СериализаторXDTO;
КонецЕсли;
ЭтоВременныйПоток = Поток = Неопределено;
Если ЭтоВременныйПоток Тогда
Поток = Новый ЗаписьXML;
Если ЗначениеЗаполнено(ИмяФайла) Тогда
Попытка
Поток.ОткрытьФайл(ИмяФайла);
Исключение
ВызватьИсключение ОписаниеОшибки(); // Чтобы в диалоге "Вычислить выражение" полное описание показывалось
КонецПопытки;
Иначе
Поток.УстановитьСтроку();
КонецЕсли;
КонецЕсли;
Результат = Неопределено;
ТипОбъекта = ТипЗнч(Объект);
ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта);
Если ЭтоИмитатор Тогда
#Если Сервер И Не Сервер Тогда
Объект = Обработки.ирИмитаторСсылочныйОбъект.Создать();
#КонецЕсли
Результат = Объект.ДанныеВСтрокуXMLЧерезXDTO(ИспользоватьXDTO, ВызыватьИсключение, Сериализатор);
Поток.ЗаписатьБезОбработки(Результат); // Криво
Иначе
Попытка
Если ИспользоватьXDTO Тогда
Если Истина
И ТипЗнч(Объект) <> Тип("ОбъектXDTO")
И ТипЗнч(Объект) <> Тип("ЗначениеXDTO")
Тогда
Сериализатор.ЗаписатьXML(Поток, Объект);
Иначе
ФабрикаXDTO.ЗаписатьXML(Поток, Объект);
КонецЕсли;
Иначе
ЗаписатьXML(Поток, Объект);
КонецЕсли;
Исключение
Если ЭтоВременныйПоток Тогда
Поток.Закрыть();
КонецЕсли;
Если ВызыватьИсключение Тогда
ВызватьИсключение;
КонецЕсли;
Поток = Неопределено;
КонецПопытки;
Если Поток <> Неопределено Тогда
Если ЭтоВременныйПоток Тогда
Результат = Поток.Закрыть();
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ВосстановитьОбъектИзСтрокиJsonЛкс(СтрокаJSON) Экспорт
Результат = Неопределено;
ЧтениеJSON = МойЧтениеJSON();
#Если Сервер И Не Сервер Тогда
ЧтениеJSON = Новый ЧтениеJSON;
#КонецЕсли
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
// Метод ПрочитатьJSON появился в 8.3
Выполнить("Результат = ПрочитатьJSON(ЧтениеJSON)");
Возврат Результат;
КонецФункции
Функция СохранитьОбъектВСтрокуJsonЛкс(Объект) Экспорт
ЗаписьJSON = МойЗаписьJSON();
#Если Сервер И Не Сервер Тогда
ЗаписьJSON = Новый ЗаписьJSON;
#КонецЕсли
ЗаписьJSON.УстановитьСтроку();
// Метод ЗаписатьJSON появился в 8.3
Выполнить("ЗаписатьJSON(ЗаписьJSON, Объект)");
Результат = ЗаписьJSON.Закрыть();
Возврат Результат;
КонецФункции
Функция ФорматироватьТекстJsonЛкс(СтрокаJSON) Экспорт
Если Не ЗначениеЗаполнено(СтрокаJSON) Тогда
Возврат СтрокаJSON;
КонецЕсли;
СтруктураИзСтроки = ВосстановитьОбъектИзСтрокиJsonЛкс(СтрокаJSON);
Результат = СохранитьОбъектВСтрокуJsonЛкс(СтруктураИзСтроки);
Возврат Результат;
КонецФункции
Функция ПроверитьЦиклическиеСсылкиВстроенногоЯзыкаЛкс(Значение, Описание = "<Значение>", ВыводитьСообщение = Ложь) Экспорт
Если ирКэш.НомерВерсииПлатформыЛкс() < 803010 Тогда
Если ВыводитьСообщение Тогда
СообщитьЛкс("Проверка циклических ссылок доступна только на платформе 8.3.10 и выше");
КонецЕсли;
Возврат Новый ТаблицаЗначений;
КонецЕсли;
Попытка
Результат = Вычислить("ПроверитьЦиклическиеСсылкиВстроенногоЯзыка(Значение, Описание)");
Исключение
Результат = Новый ТаблицаЗначений;
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
Возврат Результат;
КонецФункции
Функция ЗаписатьОбъектДляОтладкиЛкс(Объект, АдресРезультата = Неопределено) Экспорт
Если ТранзакцияАктивна() Тогда
ирСервер.СтрокаСоединенияСервераЛкс(); // Проверка на автоостановку фоновых заданий отладчиком http://www.hostedredmine.com/issues/851201
лАдресРезультата = ПоместитьВоВременноеХранилище(Null, Новый УникальныйИдентификатор);
СтрокаХМЛ = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
Параметры = Новый Массив();
Параметры.Добавить(СтрокаХМЛ);
Параметры.Добавить(лАдресРезультата);
ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ЗаписатьОбъектДляОтладкиЛкс", Параметры,, "Запись объекта для отладки (ИР)");
ФоновоеЗадание.ОжидатьЗавершения(10);
Результат = ПолучитьИзВременногоХранилища(лАдресРезультата);
Иначе
Если ТипЗнч(Объект) = Тип("Строка") Тогда
Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(Объект);
КонецЕсли;
Если ТипЗнч(Объект) = Тип("Структура") Тогда
Результат = ИмяНастройкиХраненияОбъектаОтложеннойОтладкиЛкс();
ирОбщий.СохранитьЗначениеЛкс(Результат, Объект);
Иначе
ЗаписатьОбъектЛкс(Объект);
Результат = Объект.Ссылка;
КонецЕсли;
Если АдресРезультата <> Неопределено Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ИмяНастройкиХраненияОбъектаОтложеннойОтладкиЛкс() Экспорт
Возврат "Объект для отладки";
КонецФункции
// Параметры:
// КоллекцияСтрок - Структура, ТаблицаЗначений, КоллекцияСтрокДереваЗначений, ТабличнаяЧасть, НаборЗаписей
Функция АвтоУникальноеИмяВКоллекцииЛкс(КоллекцияСтрок, БазовоеИмяИлиСтрока, ИмяКлючевойКолонки = "Имя", ИмяДолжноБытьИдентификатором = Истина,
ЗаменаПустойСтроки = "_", Знач ДопустимаяДлинаИдентификатораЕслиНеЗаданаВКолонке = 50, КлючеваяКолонкаВНижнемРегистре = Ложь) Экспорт
ТекущийИндекс = 0;
Если ТипЗнч(БазовоеИмяИлиСтрока) = Тип("Строка") Или БазовоеИмяИлиСтрока = Неопределено Тогда
БазовоеИмя = БазовоеИмяИлиСтрока;
Иначе
ИсключаемаяСтрока = БазовоеИмяИлиСтрока;
БазовоеИмя = БазовоеИмяИлиСтрока[ИмяКлючевойКолонки];
//ТекущийИндекс = 1;
ПоследнийСимвол = Прав(БазовоеИмя, 1);
Если ЭтоЦифраЛкс(ПоследнийСимвол) И ПоследнийСимвол <> "0" Тогда
БазовоеИмя = СтрокаБезКонцаЛкс(БазовоеИмя, 1);
ТекущийИндекс = Число(ПоследнийСимвол);
КонецЕсли;
КонецЕсли;
Колонки = Неопределено;
Если ТипЗнч(КоллекцияСтрок) = Тип("ТаблицаЗначений") Тогда
Колонки = КоллекцияСтрок.Колонки;
ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияСтрокДереваЗначений") Тогда
Если КоллекцияСтрок.Количество() > 0 Тогда
Колонки = КоллекцияСтрок[0].Владелец().Колонки;
КонецЕсли;
ИначеЕсли Метаданные.НайтиПоТипу(ТипЗнч(КоллекцияСтрок)) <> Неопределено Тогда
Колонки = КоллекцияСтрок.ВыгрузитьКолонки().Колонки;
ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("Структура") Тогда
//
ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("СписокЗначений") Тогда
//
ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияКолонокТаблицыЗначений") Тогда
//
ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияКолонокДереваЗначений") Тогда
//
ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("НаборыДанныхСхемыКомпоновкиДанных") Тогда
//
Иначе
ВызватьИсключение "Неподдерживаемый тип (" + ТипЗнч(КоллекцияСтрок) + ") параметра КоллекцияСтрок";
КонецЕсли;
Если ИмяДолжноБытьИдентификатором Тогда
ДопустимаяДлинаИдентификатора = 0;
Если Колонки <> Неопределено Тогда
ДопустимаяДлинаИдентификатора = Колонки[ИмяКлючевойКолонки].ТипЗначения.КвалификаторыСтроки.Длина;
КонецЕсли;
Если Не ЗначениеЗаполнено(ДопустимаяДлинаИдентификатора) Тогда
ДопустимаяДлинаИдентификатора = ДопустимаяДлинаИдентификатораЕслиНеЗаданаВКолонке;
КонецЕсли;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
БазовоеИмя = мПлатформа.ИдентификаторИзПредставленияЛкс(БазовоеИмя, ЗаменаПустойСтроки);
Если ДопустимаяДлинаИдентификатора > 0 Тогда
БазовоеИмя = Лев(БазовоеИмя, ДопустимаяДлинаИдентификатора);
КонецЕсли;
Иначе
Если ПустаяСтрока(БазовоеИмя) Тогда
БазовоеИмя = ЗаменаПустойСтроки;
КонецЕсли;
КонецЕсли;
Пока Истина Цикл
ТекущийПсевдоним = БазовоеИмя + Формат(ТекущийИндекс, "ЧГ=");
Если ТипЗнч(КоллекцияСтрок) = Тип("Структура") Тогда
СтрокиОдноименных = Новый Массив;
Если КоллекцияСтрок.Свойство(ТекущийПсевдоним) Тогда
СтрокиОдноименных.Добавить(КоллекцияСтрок[ТекущийПсевдоним]);
КонецЕсли;
ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("СписокЗначений") Тогда
СтрокиОдноименных = Новый Массив;
Для Каждого ЭлементСписка Из КоллекцияСтрок Цикл
Если ЭлементСписка.Представление = ТекущийПсевдоним Тогда
СтрокиОдноименных.Добавить(ЭлементСписка);
КонецЕсли;
КонецЦикла;
ИначеЕсли Ложь
Или ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияКолонокТаблицыЗначений")
Или ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияКолонокДереваЗначений")
Или ТипЗнч(КоллекцияСтрок) = Тип("НаборыДанныхСхемыКомпоновкиДанных")
Тогда
СтрокиОдноименных = Новый Массив;
Для Каждого Колонка Из КоллекцияСтрок Цикл
Если Колонка.Имя = ТекущийПсевдоним Тогда
СтрокиОдноименных.Добавить(Колонка);
КонецЕсли;
КонецЦикла;
Иначе
ПроверочныйПсевдоним = ТекущийПсевдоним;
Если КлючеваяКолонкаВНижнемРегистре Тогда
ПроверочныйПсевдоним = НРег(ПроверочныйПсевдоним);
КонецЕсли;
СтрокиОдноименных = КоллекцияСтрок.НайтиСтроки(Новый Структура(ИмяКлючевойКолонки, ПроверочныйПсевдоним));
КонецЕсли;
Если Ложь
Или СтрокиОдноименных.Количество() = 0
Или (Истина
И СтрокиОдноименных.Количество() = 1
И ИсключаемаяСтрока <> Неопределено
И СтрокиРавныЛкс(ТекущийПсевдоним, ИсключаемаяСтрока[ИмяКлючевойКолонки])
)
Тогда
Прервать;
КонецЕсли;
ТекущийИндекс = ТекущийИндекс + 1;
КонецЦикла;
Возврат ТекущийПсевдоним;
КонецФункции
Функция ЭтоЦифраЛкс(Символ) Экспорт
КодСимвола = КодСимвола(Символ);
Результат = КодСимвола >= 48 И КодСимвола <= 57;
Возврат Результат;
КонецФункции
// Сравнение - Строка, ВидСравнения - "Авто" - для автоматического выбора, по умолчанию Равно или ВСписке
//
// Параметры:
// ЭлементОтбора - <тип> -
// Сравнение - <тип>, "" -
// Значение - <тип> -
// ЗначениеПо - <тип> -
// Использование - <тип>, Истина -
// ПриводитьТипДляНеопределено - <тип>, Истина -
//
// Возвращаемое значение:
//
Функция УстановитьЭлементОтбораЛкс(Знач ЭлементОтбора, Знач Сравнение = "", Знач Значение, Знач ЗначениеПо = Неопределено, Знач Использование = Истина,
Знач ПриводитьТипДляНеопределено = Истина) Экспорт
Если ТипЗнч(Значение) = Тип("ФиксированныйМассив") Тогда
Значение = Новый Массив(Значение);
КонецЕсли;
Если ТипЗнч(Значение) = Тип("Массив") Тогда
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(Значение);
Значение = СписокЗначений;
ИначеЕсли Истина
И ПриводитьТипДляНеопределено
И Значение = Неопределено
Тогда
Значение = ЭлементОтбора.ТипЗначения.ПривестиЗначение(Значение);
КонецЕсли;
// Вид сравнения
Если СтрокиРавныЛкс(Сравнение, "Авто") Тогда
Сравнение = ОпределитьВидСравненияПоЗначениюЛкс(Значение);
ИначеЕсли ТипЗнч(Сравнение) = Тип("ВидСравнения") Тогда
ИначеЕсли Истина
И Сравнение <> Неопределено
И Сравнение <> ""
Тогда // Добавлено 25.03.2012
ВызватьИсключение "Неверный тип сравнения """ + ТипЗнч(Сравнение) + """";
Иначе
Если ТипЗнч(Значение) = Тип("СписокЗначений") Тогда
Сравнение = ВидСравнения.ВСписке;
Иначе
Сравнение = ВидСравнения.Равно;
КонецЕсли;
КонецЕсли;
// Еще надо сделать автоопределение Содержит, как у компоновки
ЭлементОтбора.ВидСравнения = Сравнение;
Попытка
Если ЗначениеПо <> Неопределено Тогда
ЭлементОтбора.ЗначениеС = Значение;
ЭлементОтбора.ЗначениеПО = ЗначениеПо;
Иначе
ЭлементОтбора.Значение = Значение;
КонецЕсли;
Исключение
ВызватьИсключение "Ошибка установки значения типа """ + ТипЗнч(Значение) + """ элементу отбора """ + ЭлементОтбора.Имя + """: " + ОписаниеОшибки();
КонецПопытки;
Попытка
ЭлементОтбора.Использование = Использование;
Исключение
// Сюда попадаем для элемента отбора набора записей с регистратором
КонецПопытки;
КонецФункции
// Установить отбор по структуре
//
// Параметры:
// Отбор - <тип> -
// СтруктураОтбора - <тип> -
// Сравнение - <тип>, "Авто" -
// ДобавлятьСсылкуВПутьКДанным - <тип>, Ложь -
// СброситьПередУстановкой - <тип>, Истина -
//
// Возвращаемое значение:
//
Функция УстановитьОтборПоСтруктуреЛкс(Знач Отбор, Знач СтруктураОтбора, Знач Сравнение = "Авто", Знач ДобавлятьСсылкуВПутьКДанным = Ложь,
Знач СброситьПередУстановкой = Истина) Экспорт
Если СброситьПередУстановкой Тогда
Отбор.Сбросить();
КонецЕсли;
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
ПутьКДанным = КлючИЗначение.Ключ;
Если ДобавлятьСсылкуВПутьКДанным Тогда
ПутьКДанным = "Ссылка." + ПутьКДанным;
КонецЕсли;
НайтиДобавитьЭлементОтбораЛкс(Отбор, ПутьКДанным, Сравнение, КлючИЗначение.Значение, , , КлючИЗначение.Ключ);
КонецЦикла;
КонецФункции
Процедура УстановитьОтборПоПодстрокеЛкс(ЭлементОтбора, Подстрока) Экспорт
#Если Сервер И Не Сервер Тогда
ЭлементОтбора = Новый ПостроительЗапроса;
ЭлементОтбора = ЭлементОтбора.Отбор.Добавить();
#КонецЕсли
ЭлементОтбора.ВидСравнения = ВидСравнения.Содержит;
ЭлементОтбора.Значение = Подстрока;
ЭлементОтбора.Использование = ЗначениеЗаполнено(Подстрока);
КонецПроцедуры
Процедура ЗаполнитьНаборЗаписейПоОтборуЛкс(НаборЗаписей) Экспорт
#Если Сервер И Не Сервер Тогда
НаборЗаписей = РегистрыСведений.Журнал_АвтозаданияИис.СоздатьНаборЗаписей();
#КонецЕсли
СтруктураЗначенийОтбора = Новый Структура;
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
Если ЭлементОтбора.Использование Тогда
СтруктураЗначенийОтбора.Вставить(ЭлементОтбора.Имя, ЭлементОтбора.Значение);
КонецЕсли;
КонецЦикла;
Для Каждого СтрокаНабора Из НаборЗаписей Цикл
ЗаполнитьЗначенияСвойств(СтрокаНабора, СтруктураЗначенийОтбора);
КонецЦикла;
КонецПроцедуры
// Параметры:
// Объект - Ссылочный объект или запись регистра
// Отбор - Отбор, ОтборКомпоновкиДанных
//
Функция УстановитьЗначенияРеквизитовПоОтборуЛкс(Объект, Отбор) Экспорт
Если ТипЗнч(Отбор) = Тип("Отбор") Тогда
#Если Сервер И Не Сервер Тогда
Отбор = Новый ПостроительЗапроса;
Отбор = Отбор.Отбор;
#КонецЕсли
Для Каждого ЭлементОтбора Из Отбор Цикл
Если Ложь
Или Не ЭлементОтбора.Использование
Или ЭлементОтбора.ВидСравнения <> ВидСравнения.Равно
Тогда
Продолжить;
КонецЕсли;
ИмяРеквизита = ЭлементОтбора.Имя;
ЗначениеОтбора = ЭлементОтбора.Значение;
Попытка
Объект[ИмяРеквизита] = ЗначениеОтбора;
Исключение
// Сюда попадаем например для ЭтоГруппа
КонецПопытки;
КонецЦикла;
Иначе
#Если Сервер И Не Сервер Тогда
Отбор = Новый НастройкиКомпоновкиДанных;
Отбор = Отбор.Отбор;
#КонецЕсли
Для Каждого ЭлементОтбора Из Отбор.Элементы Цикл
Если Ложь
Или Не ЭлементОтбора.Использование
Или ЭлементОтбора.ВидСравнения <> ВидСравненияКомпоновкиДанных.Равно
Тогда
Продолжить;
КонецЕсли;
ИмяРеквизита = "" + ЭлементОтбора.ЛевоеЗначение;
Если Найти(ИмяРеквизита, ".") > 0 Тогда
Продолжить;
КонецЕсли;
ЗначениеОтбора = ЭлементОтбора.ПравоеЗначение;
Попытка
Объект[ИмяРеквизита] = ЗначениеОтбора;
Исключение
// Сюда попадаем например для ЭтоГруппа
КонецПопытки;
КонецЦикла;
КонецЕсли;
КонецФункции
// Определить вид сравнения по значению
//
// Параметры:
// Значение - <тип> -
// РежимКомпоновки - <тип>, Ложь -
// ДоступныеВидыСравнения - <тип>, Неопределено -
//
// Возвращаемое значение:
//
Функция ОпределитьВидСравненияПоЗначениюЛкс(Знач Значение, Знач РежимКомпоновки = Ложь, Знач ДоступныеВидыСравнения = Неопределено) Экспорт
ТипЗначения = ТипЗнч(Значение);
Если РежимКомпоновки Тогда
КоллекцияВидовСравнения = ВидСравненияКомпоновкиДанных;
Иначе
КоллекцияВидовСравнения = ВидСравнения;
КонецЕсли;
Если ТипЗначения = Тип("СписокЗначений") Тогда
Результат = КоллекцияВидовСравнения.ВСписке;
ИначеЕсли Истина
И ТипЗначения = Тип("Строка")
И ДоступныеВидыСравнения <> Неопределено
И ДоступныеВидыСравнения.НайтиПоЗначению(КоллекцияВидовСравнения.Содержит) <> Неопределено
Тогда
Результат = КоллекцияВидовСравнения.Содержит;
Иначе
Результат = КоллекцияВидовСравнения.Равно;
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗначения);
Если ОбъектМД <> Неопределено Тогда
ТипТаблицы = ТипТаблицыБДЛкс(ОбъектМД.ПолноеИмя());
Если ТипТаблицы = "Справочник" Тогда
Если ОбъектМД.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда
Если Значение.ЭтоГруппа Тогда
Результат = КоллекцияВидовСравнения.ВИерархии;
КонецЕсли;
Иначе // иерархия элементов
Результат = КоллекцияВидовСравнения.ВИерархии;
КонецЕсли;
ИначеЕсли ТипТаблицы = "ПланВидовХарактеристик" Тогда
Если Значение.ЭтоГруппа Тогда
Результат = КоллекцияВидовСравнения.ВИерархии;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Сравнение - Строка, ВидСравнения - "Авто" - для автоматического выбора, по умолчанию Равно или ВСписке
//
// Параметры:
// ОтборИлиОбъект - <тип> -
// ПутьКДанным - <тип>, "" -
// Сравнение - <тип>, "" -
// Значение - <тип>, Неопределено -
// ЗначениеПо - <тип>, Неопределено -
// Использование - <тип>, Истина -
// Имя - <тип>, "" -
// Представление - <тип>, "" -
//
// Возвращаемое значение:
//
Функция НайтиДобавитьЭлементОтбораЛкс(Знач ОтборИлиОбъект, Знач ПутьКДанным = "", Знач Сравнение = "", Знач Значение = Неопределено, Знач ЗначениеПо = Неопределено,
Знач Использование = Истина, Знач Имя = "", Знач Представление = "") Экспорт
Если ТипЗнч(ОтборИлиОбъект) = Тип("Отбор") Тогда
Отбор = ОтборИлиОбъект;
Иначе
Отбор = ОтборИлиОбъект.Отбор;
КонецЕсли;
// Ищем или добавляем новый элемент отбора
ЭлементОтбора = Неопределено;
//Если Имя <> Неопределено Тогда
// ЭлементОтбора= Отбор.Найти(Имя);
//КонецЕсли;
Если Имя <> Неопределено Тогда
Для Каждого ЭлОтбора Из Отбор Цикл
Если Ложь
Или ЭлОтбора.Имя = Имя
Или ЭлОтбора.Представление = Имя
Тогда
ЭлементОтбора = ЭлОтбора;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЭлементОтбора = Неопределено Тогда
Попытка
ЭлементОтбора = Отбор.Добавить(ПутьКДанным, Имя, Представление);
Исключение
ВызватьИсключение "Ошибка добавления элемента отбора """ + ПутьКДанным + """ построителя запроса: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
УстановитьЭлементОтбораЛкс(ЭлементОтбора, Сравнение, Значение, ЗначениеПо, Использование);
Результат = ЭлементОтбора;
Возврат Результат;
КонецФункции
Процедура ДобавитьПрефиксВсемПараметрамЗапросаЛкс(Запрос, Префикс = "Т") Экспорт
#Если Сервер И Не Сервер Тогда
Запрос = Новый Запрос;
#КонецЕсли
ТекстЗапроса = Запрос.Текст;
Параметры = Новый Структура;
СкопироватьУниверсальнуюКоллекциюЛкс(Запрос.Параметры, Параметры);
Для Каждого КлючИЗначение Из Параметры Цикл
Если Найти(КлючИЗначение.Ключ, Префикс) = 1 Тогда
ВызватьИсключение "Начало имени параметра " + КлючИЗначение.Ключ + " совпадает с префиксом " + Префикс;
КонецЕсли;
НовоеИмя = Префикс + КлючИЗначение.Ключ;
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&" + КлючИЗначение.Ключ, "&" + НовоеИмя);
Запрос.УстановитьПараметр(НовоеИмя, КлючИЗначение.Значение);
КонецЦикла;
Запрос.Текст = ТекстЗапроса;
КонецПроцедуры
// ТаблицаПараметров - ТаблицаЗначений, ТабличнаяЧасть
Функция НайтиДобавитьПараметрСсылкуВТаблицуЛкс(ТаблицаПараметров, ИмяКолонкиИмени = "Имя", ИмяКолонкиЗначения = "Значение", ЗначениеПараметра,
ИмяПараметра = Неопределено, ОбновитьКопиюСвойстваВНижнемРегистре = Ложь) Экспорт
Если ТипЗнч(ТаблицаПараметров) = Тип("ТаблицаЗначений") Тогда
МакетТаблицы = ТаблицаПараметров;
Иначе
МакетТаблицы = ТаблицаПараметров.ВыгрузитьКолонки();
КонецЕсли;
Строки = ТаблицаПараметров.НайтиСтроки(Новый Структура(ИмяКолонкиЗначения, ЗначениеПараметра));
Если Строки.Количество() > 0 Тогда
Результат = Строки[0];
Иначе
Если ТипЗнч(ЗначениеПараметра) = Тип("Строка") Тогда
ИмяПараметра = АвтоУникальноеИмяВКоллекцииЛкс(ТаблицаПараметров, "П", ИмяКолонкиИмени);
Иначе
ИмяТипа = ИмяТипаИзПолногоИмениМДЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеПараметра)));
//Префикс = НРег(Лев(ОбъектМД.Имя, 1));
Префикс = "";
Если ИмяПараметра = Неопределено Тогда
ИмяПараметра = "" + РасширенноеПредставлениеЗначенияЛкс(ЗначениеПараметра);
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяПараметра) Тогда
ИмяПараметра = СтрЗаменить(ИмяТипа, ".", "") + "Пустая";
КонецЕсли;
ИмяПараметра = Префикс + ирКэш.Получить().ИдентификаторИзПредставленияЛкс(ИмяПараметра);
ДопустимаяДлинаСтроки = МакетТаблицы.Колонки[ИмяКолонкиИмени].ТипЗначения.КвалификаторыСтроки.Длина;
Если ДопустимаяДлинаСтроки > 0 Тогда
ИмяПараметра = Лев(ИмяПараметра, ДопустимаяДлинаСтроки);
КонецЕсли;
КонецЕсли;
СтруктураСвойствПараметра = Новый Структура;
СтруктураСвойствПараметра.Вставить(ИмяКолонкиИмени, ИмяПараметра);
Счетчик = 0;
Пока ТаблицаПараметров.НайтиСтроки(СтруктураСвойствПараметра).Количество() > 0 Цикл
Счетчик = Счетчик + 1;
СтрокаНомера = "" + Счетчик;
Если ДопустимаяДлинаСтроки > 0 Тогда
лИмяПараметра = Лев(ИмяПараметра, ДопустимаяДлинаСтроки - СтрДлина(СтрокаНомера));
Иначе
лИмяПараметра = ИмяПараметра;
КонецЕсли;
СтруктураСвойствПараметра[ИмяКолонкиИмени] = лИмяПараметра + СтрокаНомера;
КонецЦикла;
СтруктураСвойствПараметра.Вставить("ЭтоВыражение", Ложь);
СтруктураСвойствПараметра.Вставить(ИмяКолонкиЗначения, ЗначениеПараметра);
СтрокаНовогоПараметра = ТаблицаПараметров.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаНовогоПараметра, СтруктураСвойствПараметра);
Если ОбновитьКопиюСвойстваВНижнемРегистре Тогда
ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаНовогоПараметра, ИмяКолонкиИмени);
КонецЕсли;
Результат = СтрокаНовогоПараметра;
КонецЕсли;
Возврат Результат;
КонецФункции // ДобавитьПараметрЗначение()
Функция _ПолучитьНаборЗаписейПоКлючуЛкс(ПолноеИмяТаблицыИлиНаборЗаписей, Знач КлючНабора, ДобавитьИЗаполнитьСтрокуНабора = Ложь) Экспорт
Если ТипЗнч(ПолноеИмяТаблицыИлиНаборЗаписей) = Тип("Строка") Тогда
СтруктураНабораЗаписей = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыИлиНаборЗаписей);
НаборЗаписей = СтруктураНабораЗаписей.Методы;
Иначе
НаборЗаписей = ПолноеИмяТаблицыИлиНаборЗаписей;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
НаборЗаписей = РегистрыСведений.Журнал_АвтозаданияИис.СоздатьНаборЗаписей();
#КонецЕсли
//СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ирКэш.ИмяТаблицыИзМетаданныхЛкс(НаборЗаписей.Метаданные().ПолноеИмя()), Ложь);
//Для Каждого ПолеКлюча Из СтруктураКлюча Цикл
// ИмяПоля = ПолеКлюча.Ключ;
// Попытка
// ЗначениеКлюча = КлючНабора[ИмяПоля];
// Исключение
// // Имеет смысл для регистров сведений
// Продолжить;
// КонецПопытки;
// ЭлементОтбора = НаборЗаписей.Отбор[ИмяПоля];
// ЭлементОтбора.Значение = ЗначениеКлюча;
// ЭлементОтбора.Использование = Истина;
//КонецЦикла;
Если ЛиКлючЗаписиРегистраЛкс(КлючНабора) Тогда
// Возможно эта строка лишена смысла
КлючНабора = СтруктураИзКлючаЗаписиЛкс(КлючНабора, ПолноеИмяТаблицыИлиНаборЗаписей);
КонецЕсли;
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
ИмяПоля = ЭлементОтбора.Имя;
Попытка
ЗначениеКлюча = КлючНабора[ИмяПоля];
Исключение
// Имеет смысл для регистров сведений
Продолжить;
КонецПопытки;
ЭлементОтбора.Значение = ЗначениеКлюча;
ЭлементОтбора.Использование = Истина;
КонецЦикла;
Если ДобавитьИЗаполнитьСтрокуНабора Тогда
ЗаполнитьЗначенияСвойств(НаборЗаписей.Добавить(), КлючНабора);
КонецЕсли;
Возврат НаборЗаписей;
КонецФункции
// Получает копию таблицы значений с минимальными типами колонок для содержания всех данных.
// Параметры:
// ТаблицаДанных - ТаблицаЗначений
// СужатьТолькоПроизвольныеКолонки - Булево - обрабатывать только колонки с пустым (произвольным) типом
// ИмяКолонки - Строка - нужна только эта колонка
//
Функция ТаблицаСМинимальнымиТипамиКолонокЛкс(Знач ТаблицаДанных, СужатьТолькоПроизвольныеКолонки = Ложь, ИмяКолонки = "") Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаДанных = Новый ТаблицаЗначений;
#КонецЕсли
ОставляемыеКолонки = "";
СужаемыеКолонки = Новый Массив();
Для Каждого КолонкаДанных Из ТаблицаДанных.Колонки Цикл
Если ЗначениеЗаполнено(ИмяКолонки) И Не СтрокиРавныЛкс(ИмяКолонки, КолонкаДанных.Имя) Тогда
Продолжить;
КонецЕсли;
КоличествоТипов = КолонкаДанных.ТипЗначения.Типы().Количество();
Если Ложь
Или КоличествоТипов = 1
Или (Истина
И СужатьТолькоПроизвольныеКолонки
И КоличествоТипов > 0)
Тогда
ОставляемыеКолонки = ОставляемыеКолонки + "," + КолонкаДанных.Имя;
Иначе
СужаемыеКолонки.Добавить(КолонкаДанных);
КонецЕсли;
КонецЦикла;
//СостояниеЛкс("Оптимизация типов колонок");
НовыеКолонки = Новый Структура;
МетаданныеТаблицыИзменены = Ложь;
ВсеРедактируемыеТипы = ирОбщий.ОписаниеТиповВсеРедактируемыеТипыЛкс();
#Если Сервер И Не Сервер Тогда
ВсеРедактируемыеТипы = Новый ОписаниеТипов;
#КонецЕсли
Если СужаемыеКолонки.Количество() * ТаблицаДанных.Количество() > 10000 Тогда
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(СужаемыеКолонки.Количество(), "Анализ колонок");
КонецЕсли;
Для Каждого КолонкаДанных Из СужаемыеКолонки Цикл
Если Индикатор <> Неопределено Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
ИмяКолонки = КолонкаДанных.Имя;
Типы = Новый Массив;
ТаблицаКолонки = ТаблицаДанных.Скопировать(, ИмяКолонки);
ТаблицаКолонки.Свернуть(ИмяКолонки);
СтароеОписаниеТипов = КолонкаДанных.ТипЗначения;
ПропуститьКолонку = Ложь;
Для Каждого СтрокаДанных Из ТаблицаКолонки Цикл
ТипЗначения = ТипЗнч(СтрокаДанных[ИмяКолонки]);
Если Не ВсеРедактируемыеТипы.СодержитТип(ТипЗначения) Тогда
// Антибаг платформы 8.2-8.3
#Если Сервер И Не Сервер Тогда
_БезопасноеОписаниеТиповЛкс();
#КонецЕсли
ПропуститьКолонку = Истина;
Прервать;
КонецЕсли;
Если Истина
И ТипЗначения <> Тип("Неопределено")
И Типы.Найти(ТипЗначения) = Неопределено
Тогда
Типы.Добавить(ТипЗначения);
КонецЕсли;
КонецЦикла;
Если ПропуститьКолонку Тогда
ОставляемыеКолонки = ОставляемыеКолонки + "," + КолонкаДанных.Имя;
Продолжить;
КонецЕсли;
Если Типы.Количество() = 0 Тогда
Типы = КолонкаДанных.ТипЗначения.Типы();
Если Типы.Количество() = 0 Тогда
Типы.ДОбавить(Тип("Булево"));
Типы.ДОбавить(Тип("Число"));
КонецЕсли;
// Чтобы от супертипов через точку не было много соединений, оставляем только 2 типа
Пока Типы.Количество() > 2 Цикл
Типы.Удалить(0);
КонецЦикла;
КонецЕсли;
Если Типы.Количество() <> СтароеОписаниеТипов.Типы().Количество() Тогда
МетаданныеТаблицыИзменены = Истина;
КонецЕсли;
НовоеОписаниеТипов = Новый ОписаниеТипов(Типы, , , СтароеОписаниеТипов.КвалификаторыЧисла, СтароеОписаниеТипов.КвалификаторыСтроки, СтароеОписаниеТипов.КвалификаторыДаты);
НовыеКолонки.Вставить(ИмяКолонки, НовоеОписаниеТипов);
КонецЦикла;
Если Индикатор <> Неопределено Тогда
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
Если МетаданныеТаблицыИзменены Тогда
Если ОставляемыеКолонки <> "" Тогда
ТипизированнаяТаблица = ТаблицаДанных.Скопировать(, ОставляемыеКолонки);
Иначе
ТипизированнаяТаблица = Новый ТаблицаЗначений;
КонецЕсли;
Если ТипизированнаяТаблица.Количество() = 0 Тогда
Для Счетчик = 1 По ТаблицаДанных.Количество() Цикл
ТипизированнаяТаблица.Добавить();
КонецЦикла;
КонецЕсли;
Для Каждого КлючИЗначение Из НовыеКолонки Цикл
ОригинальнаяКолонка = ТаблицаДанных.Колонки[КлючИЗначение.Ключ];
НоваяКолонка = ТипизированнаяТаблица.Колонки.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Значение, ОригинальнаяКолонка.Заголовок, ОригинальнаяКолонка.Ширина);
ТипизированнаяТаблица.ЗагрузитьКолонку(ТаблицаДанных.ВыгрузитьКолонку(КлючИЗначение.Ключ), КлючИЗначение.Ключ);
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ТипизированнаяТаблица.Колонки.Сдвинуть(НоваяКолонка, ТаблицаДанных.Колонки.Индекс(ОригинальнаяКолонка) - ТипизированнаяТаблица.Колонки.Индекс(НоваяКолонка));
КонецЕсли;
КонецЦикла;
Иначе
ТипизированнаяТаблица = ТаблицаДанных;
КонецЕсли;
Результат = ТипизированнаяТаблица;
Возврат Результат;
КонецФункции
Процедура ИзменитьТипКолонкиТаблицыЗначенийЛкс(Знач ТаблицаЗначений, Знач ИмяКолонки, Знач НовыйТипКолонки = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
Если НовыйТипКолонки = Неопределено Тогда
НовыйТипКолонки = Новый ОписаниеТипов;
КонецЕсли;
ИмяВременнойКолонки = ИмяКолонки + "_Вр31415926";
МассивДанныхКолонки = ТаблицаЗначений.ВыгрузитьКолонку(ИмяКолонки);
ТаблицаЗначений.Колонки.Добавить(ИмяВременнойКолонки, НовыйТипКолонки);
ТаблицаЗначений.ЗагрузитьКолонку(МассивДанныхКолонки, ИмяВременнойКолонки);
ТаблицаЗначений.Колонки.Удалить(ИмяКолонки);
ТаблицаЗначений.Колонки[ИмяВременнойКолонки].Имя = ИмяКолонки;
КонецПроцедуры
// ************************
// 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Объект") Тогда
ИмяТипа = ИмяТипа + " {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.BOF() = 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ВТаблицуЗначенийОбщийЛкс(РезультатRecordset, Типизировать1С = Истина, БинарныеВСтроку = Ложь, ЗагружатьЭлементов = 0, СмещениеГода = 0, ИспользованиеGWF = Истина,
Знач ADOUtils = Неопределено, МодальныйРежим = Ложь) Экспорт
ТаблицаИзADO = Неопределено;
Если ИспользованиеGWF Тогда
Если ADOUtils = Неопределено Тогда
мПлатформа = ирКэш.Получить();
ADOUtils = мПлатформа.ПолучитьADOUtils(, СмещениеГода, Истина);
КонецЕсли;
Если ADOUtils <> Неопределено Тогда
ТаблицаИзADO = ADOUtils.ADORecordsetToValueTable(РезультатRecordset);
Иначе
//ОписаниеОшибки = "Не удалось подключить ВК GameWithFire.dll! Выгрузка из ADO будет выполняться программой на встроенном языке.";
//СообщитьСУчетомМодальностиЛкс(ОписаниеОшибки, МодальныйРежим, СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
Если ТаблицаИзADO = Неопределено Тогда
ТаблицаИзADO = ПреобразоватьРезультатADOВТаблицуЗначенийЛкс(РезультатRecordset, Типизировать1С, БинарныеВСтроку,,, ЗагружатьЭлементов, СмещениеГода);
КонецЕсли;
Возврат ТаблицаИзADO;
КонецФункции
// *** УСТАНОВКА ПАРАМЕТРОВ ЗАПРОСА 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);
Возврат Строка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
Если Значение = ПараметрыСеанса Тогда
Возврат Истина;
КонецЕсли;
// Для ускорения
Если Значение = Неопределено Или Значение = Null Тогда
Возврат Ложь;
КонецЕсли;
ХмлТип = XMLТипЗнч(Значение);
Если ХмлТип <> Неопределено Тогда
ИмяТипа = ХмлТип.ИмяТипа;
Если Ложь
Или Найти(ИмяТипа, "Ref.") > 0
Или ИмяТипа = "decimal"
Или ИмяТипа = "boolean"
Или ИмяТипа = "dateTime"
Или ИмяТипа = "string"
Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
Попытка
Для Каждого _Элемент Из Значение Цикл // Это тяжелая операция и выполняется почему то минимум 2 раза судя по замеру
Прервать;
КонецЦикла;
ЭтоКоллекция = Истина;
Исключение
ЭтоКоллекция = Ложь;
КонецПопытки;
Возврат ЭтоКоллекция;
КонецФункции
Функция СоздатьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД) Экспорт
Фрагменты = СтрРазделитьЛкс(ПолноеИмяМД);
ТипМетаданных = Фрагменты[0];
ИмяОбъекта = Фрагменты[1];
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
ТипОбъекта = Тип(ТипМетаданных + "Объект." + ИмяОбъекта);
Иначе
КэшТиповВнешнихМетаданных = ирПортативный.мКэшТиповВнешнихМетаданных;
ВнешнийОбъект = КэшТиповВнешнихМетаданных[ПолноеИмяМД];
Если ВнешнийОбъект <> Неопределено Тогда
ТипОбъекта = ТипЗнч(ВнешнийОбъект);
КонецЕсли;
КонецЕсли;
Если ТипОбъекта <> Неопределено Тогда
Результат = Новый (ТипОбъекта);
Иначе
Менеджер = ирПортативный.ПолучитьМенеджерТипаМетаданныхЛкс(ТипМетаданных);
ПолноеИмяФайла = ирПортативный.ПолучитьПолноеИмяФайлаПортативногоОбъектаМетаданныхЛкс(ИмяОбъекта, ТипМетаданных);
Попытка
Результат = Менеджер.Создать(ПолноеИмяФайла, Ложь);
//// Антибаг платформы 8.3 https://partners.v8.1c.ru/forum/t/1442085/m/1442085
//Если ИмяОбъекта = "ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой" Тогда
// Пустышка = Результат.ПолучитьФорму();
//КонецЕсли;
Исключение
// Это очень помогает при ошибках функций режима отладки
ВызватьИсключение ОписаниеОшибки();
КонецПопытки;
Если Истина
И КэшТиповВнешнихМетаданных <> Неопределено
// Такой прием ко всем нельзя применять, т.к. при получении формы у разных экземпляров будет возвращаться всегда форма первого экземпляра, если она открыта
И (Ложь
Или ИмяОбъекта = "ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой"
Или ИмяОбъекта = "ирПлатформа")
Тогда
КэшТиповВнешнихМетаданных[ПолноеИмяМД] = Результат;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьПолноеИмяМДТипаЛкс(Тип) Экспорт
ОбъектМетаданных = Метаданные.НайтиПоТипу(Тип);
Если ОбъектМетаданных <> Неопределено Тогда
Результат = ОбъектМетаданных.ПолноеИмя();
Если ЛиТипСсылкиТочкиМаршрутаЛкс(Тип) Тогда
Результат = Результат + "." + ПеревестиСтроку("Точки");
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОптимальныйПотоковыйПисательЛкс() Экспорт
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803006 Тогда
ПотоковыйПисатель = МойЗаписьJSON();
Иначе
ПотоковыйПисатель = Новый ЗаписьXML;
КонецЕсли;
Возврат ПотоковыйПисатель;
КонецФункции
Функция МойЗаписьJSON() Экспорт
Возврат Новый ("ЗаписьJSON");
КонецФункции
Функция ОптимальныйПотоковыйЧитательЛкс() Экспорт
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803006 Тогда
ПотоковыйЧитатель = МойЧтениеJSON();
Иначе
ПотоковыйЧитатель = Новый ЧтениеXML;
КонецЕсли;
Возврат ПотоковыйЧитатель;
КонецФункции
Функция МойЧтениеJSON() Экспорт
Возврат Новый ("ЧтениеJSON");
КонецФункции
Функция ЛиТекстJSONЛкс(Знач ТелоЗапросаСтрока) Экспорт
ТелоЗапросаСтрокаЧистое = СокрЛП(ТелоЗапросаСтрока);
ЛиТекстJSON = Истина
И Лев(ТелоЗапросаСтрокаЧистое, 1) = "{"
И Прав(ТелоЗапросаСтрокаЧистое, 1) = "}";
Возврат ЛиТекстJSON;
КонецФункции
Функция ДеревоЗначенийИзМассиваСтруктурЛкс(МассивСтруктур, Дерево = Неопределено) Экспорт
Если Дерево = Неопределено Тогда
Дерево = Новый ДеревоЗначений;
Дерево.Колонки.Добавить("Свойство");
Дерево.Колонки.Добавить("Значение");
КонецЕсли;
Если ТипЗнч(МассивСтруктур) = Тип("Структура") Тогда
ЭлементСтруктурыВДеревоЗначений(Дерево, МассивСтруктур);
ИначеЕсли ТипЗнч(МассивСтруктур) = Тип("Массив") Тогда
МассивВДеревоЗначений(Дерево, МассивСтруктур, "");
КонецЕсли;
Возврат Дерево;
КонецФункции
Процедура ЭлементСтруктурыВДеревоЗначений(Дерево, Структура)
#Если Сервер И Не Сервер Тогда
Дерево = Новый ДеревоЗначений;
#КонецЕсли
Для Каждого ЭлСтруктуры Из Структура Цикл
СтрокаДерева = Дерево.Строки.Добавить();
СтрокаДерева.Свойство = ЭлСтруктуры.Ключ;
Если ТипЗнч(ЭлСтруктуры.Значение) = Тип("Структура") Тогда
ЭлементСтруктурыВДеревоЗначений(СтрокаДерева, ЭлСтруктуры.Значение);
ИначеЕсли ТипЗнч(ЭлСтруктуры.Значение) = Тип("Массив") Тогда
СтрокаДерева.Значение = "[Массив-" + 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Алгоритма);
АлгоритмОбъект = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИмитаторАлгоритмОбъект");
#Если Сервер И Не Сервер Тогда
АлгоритмОбъект = Обработки.ирИмитаторАлгоритмОбъект.Создать();
#КонецЕсли
АлгоритмОбъект.ТекстАлгоритма = СтруктураАлгоритма.ТекстАлгоритма;
ЗагрузитьВТаблицуЗначенийЛкс(СтруктураАлгоритма.ВнутренниеПараметры, АлгоритмОбъект.Параметры, Новый Структура("Вход", Истина));
Возврат АлгоритмОбъект;
КонецФункции
// мВнешниеНаборыДанных - Структура, Неопределено - не очищается
Функция ДополнитьСтруктуруВнешнихНаборовДанныхПустышкамиЛкс(СхемаКомпоновкиДанных, ВнешниеНаборыДанных = Неопределено) Экспорт
Если ВнешниеНаборыДанных = Неопределено Тогда
ВнешниеНаборыДанных = Новый Структура();
КонецЕсли;
// Создадим пустышки внешних наборов данных, если они не переданы
ОбъектТаблица = 0;
Для Каждого НаборДанных Из СхемаКомпоновкиДанных.НаборыДанных Цикл
Если ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Тогда
Если НаборДанных.ИмяОбъекта = "" Тогда
Продолжить;
КонецЕсли;
Если Не ВнешниеНаборыДанных.Свойство(НаборДанных.ИмяОбъекта, ОбъектТаблица) Тогда
ОбъектТаблица = Новый ТаблицаЗначений;
КонецЕсли;
Попытка
КолонкиОбъектаТаблицы = ОбъектТаблица.Колонки;
Исключение
// Тогда это табличная часть, но возможно и тут будет исключение
КолонкиОбъектаТаблицы = ОбъектТаблица.ВыгрузитьКолонки().Колонки;
КонецПопытки;
Если КолонкиОбъектаТаблицы.Количество() > 0 Тогда
Продолжить;
КонецЕсли;
Для Каждого Поле Из НаборДанных.Поля Цикл
Если ТипЗнч(Поле) = Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда
Если КолонкиОбъектаТаблицы.Найти(Поле.Поле) = Неопределено Тогда
КолонкиОбъектаТаблицы.Добавить(Поле.Поле, Поле.ТипЗначения);
КонецЕсли;
КонецЕсли;
КонецЦикла;
ВнешниеНаборыДанных.Вставить(НаборДанных.ИмяОбъекта, ОбъектТаблица);
ИначеЕсли ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеСхемыКомпоновкиДанных") Тогда
ДополнитьСтруктуруВнешнихНаборовДанныхПустышкамиЛкс(Новый Структура("НаборыДанных", НаборДанных.Элементы), ВнешниеНаборыДанных);
КонецЕсли;
КонецЦикла;
Возврат ВнешниеНаборыДанных;
КонецФункции
Процедура ПроверитьСхемуКомпоновкиЛкс(Знач ПроверочнаяСхема, Знач НастройкаКомпоновки, Знач ПроверятьДоступностьПолей = Истина, Знач ВнешниеФункцииРазрешены = Истина, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
ирСервер.ПроверитьСхемуКомпоновкиЛкс(СохранитьОбъектВВидеСтрокиXMLЛкс(ПроверочнаяСхема), СохранитьОбъектВВидеСтрокиXMLЛкс(НастройкаКомпоновки), ПроверятьДоступностьПолей, ВнешниеФункцииРазрешены);
Иначе
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
// От(ПроверочнаяСхема, НастройкаКомпоновки);
ВнешниеНаборыДанных = ДополнитьСтруктуруВнешнихНаборовДанныхПустышкамиЛкс(ПроверочнаяСхема);
МакетКомпоновки = КомпоновщикМакета.Выполнить(ПроверочнаяСхема, НастройкаКомпоновки,,,, ПроверятьДоступностьПолей); // Здесь будет возникать ошибка
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных,, ВнешниеФункцииРазрешены);
КонецЕсли;
КонецПроцедуры
// Осуществляет вывод результата компоновки в коллекцию значений. По умолчанию в качестве коллекции используется новая таблица значений.
// Параметры:
// СхемаКомпоновки - СхемаКомпоновкиДанных
// НастройкаКомпоновки - НастройкиКомпоновкиДанных
// КоллекцияЗначений - ДеревоЗначений, Массив, СписокЗначений, ТаблицаЗначений - Если не указана, создается ТаблицаЗначений
// ВнешниеНаборыДанных - Структура
// ТолькоСоздатьКолонки - Булево
// СхемаКолонок - Структура - Если Неопределено, то не возвращается
// МаксимальноеЧислоСтрокРезультата - Число(15,2) - Для предотвращения получения слишком большого результата. Если порог превышен, то результат = Неопределено.
// ОтключитьОбщиеИтоги - Булево
// РежимОтладки - Булево
//
Функция СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(Знач СхемаКомпоновки, Знач НастройкаКомпоновки, КоллекцияЗначений = Неопределено, Знач ВнешниеНаборыДанных = Неопределено,
Знач ТолькоСоздатьКолонки = Ложь, СхемаКолонок = Неопределено, Знач МаксимальноеЧислоСтрокРезультата = 0, Знач ОтключитьОбщиеИтоги = Истина, Знач РежимОтладки = Ложь,
Знач ПроверятьДоступностьПолей = Ложь, Знач СузитьТипы = Ложь, ЗаменаТочкиВИменахКолонок = "", ВыбратьВсеДоступныеПоля = Ложь) Экспорт
МакетКомпоновки = СобратьМакетКомпоновкиЛкс(СхемаКомпоновки, НастройкаКомпоновки, ВнешниеНаборыДанных, ОтключитьОбщиеИтоги, РежимОтладки, ПроверятьДоступностьПолей, ВыбратьВсеДоступныеПоля);
Если РежимОтладки = Истина Тогда
Возврат Неопределено;
КонецЕсли;
Результат = СкомпоноватьВКоллекциюЗначенийПоМакетуЛкс(МакетКомпоновки, КоллекцияЗначений, ВнешниеНаборыДанных, ТолькоСоздатьКолонки, СхемаКолонок, МаксимальноеЧислоСтрокРезультата,
СузитьТипы, ЗаменаТочкиВИменахКолонок);
Возврат Результат;
КонецФункции
// Собирает макет компоновки из схемы и настроек.
// Параметры:
// СхемаКомпоновки - СхемаКомпоновкиДанных
// НастройкаКомпоновки - НастройкиКомпоновкиДанных
// ВнешниеНаборыДанных - Структура
// ОтключитьОбщиеИтоги - ? -
// РежимОтладки - ? -
// ПроверятьДоступностьПолей - ? -
// ВыбратьВсеДоступныеПоля - ? -
// МакетКомпоновки - МакетКомпоновкиДанных -
// ТипВыхода - Строка - Служебный параметр для перехода после вызова метода
Функция СобратьМакетКомпоновкиЛкс(СхемаКомпоновки, НастройкаКомпоновки, ВнешниеНаборыДанных = Неопределено, ОтключитьОбщиеИтоги = Истина, РежимОтладки = Ложь,
ПроверятьДоступностьПолей = Истина, ВыбратьВсеДоступныеПоля = Ложь) Экспорт
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
//ЭлементСтруктуры = НастройкаКомпоновки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
//ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура);
КонецЕсли;
Если ВыбратьВсеДоступныеПоля Тогда
ВыбратьВсеДоступныеПоляКомпоновки(СхемаКомпоновки, НастройкаКомпоновки);
КонецЕсли;
Если ОтключитьОбщиеИтоги Тогда
НастройкаКомпоновки.ПараметрыВывода.УстановитьЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ВертикальноеРасположениеОбщихИтогов"),
РасположениеИтоговКомпоновкиДанных.Нет);
КонецЕсли;
Если РежимОтладки = Истина Тогда
ОтладитьЛкс(СхемаКомпоновки, Ложь, НастройкаКомпоновки, ВнешниеНаборыДанных);
//Возврат Неопределено;
КонецЕсли;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Попытка
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, НастройкаКомпоновки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"), ПроверятьДоступностьПолей);
Исключение
//ИнформацияОбОшибке = ИнформацияОбОшибке();
//Если глКэш.ЭтоВидимоеПриложение Тогда
// ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке);
//Иначе
// ВызватьИсключение ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
//КонецЕсли;
ВызватьИсключение;
КонецПопытки;
//ИсследоватьЛкс(МакетКомпоновки, Ложь);
//ОтладитьЛкс(МакетКомпоновки, Ложь);
//Возврат Неопределено;
Возврат МакетКомпоновки;
КонецФункции
// Осуществляет вывод результата компоновки в коллекцию значений. По умолчанию в качестве коллекции используется новая таблица значений.
// Параметры:
// МакетКомпоновки - МакетКомпоновкиДанных -
// КоллекцияЗначений - ДеревоЗначений, Массив, СписокЗначений, ТаблицаЗначений - Если не указана, создается ТаблицаЗначений
// ВнешниеНаборыДанных - Структура -
// ТолькоСоздатьКолонки - Булево -
// СхемаКолонок - Структура - Если Неопределено, то не возвращается
// МаксимальноеЧислоСтрокРезультата - Число(15,2) - Для предотвращения получения слишком большого результата. Если порог превышен, то результат = Неопределено.
// СузитьТипы - Булево -
// ЗаменаТочкиВИменахКолонок - Строка -
// КоллекцияРезультата - ? -
// ТипВыхода - Строка - Служебный параметр для перехода после вызова метода
Функция СкомпоноватьВКоллекциюЗначенийПоМакетуЛкс(МакетКомпоновки, КоллекцияЗначений = Неопределено, ВнешниеНаборыДанных = Неопределено, ТолькоСоздатьКолонки = Ложь, СхемаКолонок = Неопределено,
МаксимальноеЧислоСтрокРезультата = 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]);
КонецЦикла;
КонецЕсли;
Иначе
КоллекцияЗначений = КоллекцияРезультата;
Если ЗначениеЗаполнено(ЗаменаТочкиВИменахКолонок) Тогда
Для Каждого Колонка Из КоллекцияЗначений.Колонки Цикл
Колонка.Имя = СтрЗаменить(СхемаКолонок[Колонка.Имя], ".", ЗаменаТочкиВИменахКолонок);
КонецЦикла;
КонецЕсли;
Если СузитьТипы Тогда
КоллекцияЗначений = ТаблицаСМинимальнымиТипамиКолонокЛкс(КоллекцияЗначений);
КонецЕсли;
КонецЕсли;
Возврат КоллекцияЗначений;
КонецФункции
Процедура ДописатьРежимВыбораВЗаголовокФормыЛкс(ЭтаФорма) Экспорт
Если ЭтаФорма.РежимВыбора Тогда
ЭтаФорма.Заголовок = ЭтаФорма.Заголовок + " (выбор)";
КонецЕсли;
КонецПроцедуры
#КонецЕсли
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент И Клиент Тогда
Функция БазовыйФайлРедактораJSONЛкс() экспорт
Возврат ирКэш.Получить().БазовыйФайлРедактораJSON();
КонецФункции
Процедура НастроитьРедакторJSONЛкс(РедакторJSON) Экспорт
РедакторJSON.menu.style.backgroundColor = "#d0d0d0";
КонецПроцедуры
Процедура ПереключитьРежимДереваРедактораJSONЛкс(РедакторJSON, РежимДерева) Экспорт
Если РежимДерева Тогда
РедакторJSON.setMode("tree");
Иначе
РедакторJSON.setMode("code");
КонецЕсли;
НастроитьРедакторJSONЛкс(РедакторJSON);
КонецПроцедуры
Процедура ПоказатьНеуникальныеСтрокиТабличногоПоляЛкс(Знач ТабличноеПоле, Знач СтрокаКлюча = "") Экспорт
НеуникальныеКлючи = НеуникальныеКлючиТаблицыЛкс(ТабличноеПоле.Значение, СтрокаКлюча);
ТекстСообщения = "Найдено " + НеуникальныеКлючи.Количество() + " неуникальных ключей строк";
Если НеуникальныеКлючи.Количество() > 0 Тогда
ВыделитьСтрокиТабличногоПоляПоКлючуЛкс(ТабличноеПоле, НеуникальныеКлючи[0], СтрокаКлюча);
ТекстСообщения = ТекстСообщения + ". Выделены строки первого ключа";
//ЭтаФорма.ТекущийЭлемент = ТабличноеПоле;
КонецЕсли;
СообщитьЛкс(ТекстСообщения);
КонецПроцедуры
Процедура УстановитьТекстПоляСохраняяПозициюЛкс(ПолеТекстовогоДокумента, НовыйТекст) Экспорт
НачальнаяКолонка = 0; НачальнаяСтрока = 0; КонечнаяКолонка = 0; КонечнаяСтрока = 0;
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка);
ПолеТекстовогоДокумента.УстановитьТекст(НовыйТекст);
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка);
КонецПроцедуры
Функция ПреобразоватьЗначениеИзSDBLЛкс(ЗначениеSDBL, АдресЧужойСхемыБД = "") Экспорт
Фрагменты = СтрРазделитьЛкс(ЗначениеSDBL, ":");
Если Фрагменты.Количество() < 2 Тогда
Возврат Неопределено;
КонецЕсли;
СтрокаНомераТаблицы = Фрагменты[0];
ИдентификаторОбъекта = Фрагменты[1];
ПолноеИмяМД = ПолучитьМетаданныеПоНомеруСсылочнойТаблицыЛкс(СтрокаНомераТаблицы, АдресЧужойСхемыБД);
ОбъектМетаданныхНайден = Истина;
Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда
ПолноеИмяМД = "НеизвестныйСсылочныйТип" + СтрокаНомераТаблицы;
ОбъектМетаданныхНайден = Ложь;
КонецЕсли;
Результат = ПолноеИмяМД + "._" + ИдентификаторОбъекта;
Если ОбъектМетаданныхНайден И Не ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда
//СтруктураБД = ирКэш.СтруктураХраненияБДЛкс(Ложь);
// Этот способ не работал для перечислений
//УникальныйИдентификатор = Новый УникальныйИдентификатор(ПолучитьГУИДПрямойИзИнверсногоЛкс(Фрагменты[1]));
//Массив = Новый Массив();
//Если ЗначениеЗаполнено(УникальныйИдентификатор) Тогда
// Массив.Добавить(УникальныйИдентификатор);
//КонецЕсли;
//Значение = Новый (Тип(ПолучитьИмяТипаСсылкиТаблицыБДЛкс(ПолноеИмяМД)), Массив);
//
ПустаяСсылка = Новый (Тип(ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяМД)));
ПустаяСсылкаВнутр = ЗначениеВСтрокуВнутр(ПустаяСсылка);
ФрагментыПустойСсылки = СтрРазделитьЛкс(ПустаяСсылкаВнутр, ":");
СсылкаВнутр = ФрагментыПустойСсылки[0] + ":" + ИдентификаторОбъекта + "}";
Попытка
Результат = ЗначениеИзСтрокиВнутр(СсылкаВнутр);
Исключение
// Например, если Фрагменты[1] содержит неверное число символов
КонецПопытки;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьМетаданныеПоНомеруСсылочнойТаблицыЛкс(СтрокаНомерТаблицы, АдресЧужойСхемыБД = "") Экспорт
СтруктураБД = ирКэш.СтруктураХраненияБДЛкс(,, АдресЧужойСхемыБД);
#Если Сервер И Не Сервер Тогда
СтруктураБД = Новый ТаблицаЗначений;
#КонецЕсли
СловарьШаблоновМетаданных = ирКэш.ПолучитьСловарьШаблоновМетаданныхЛкс(, АдресЧужойСхемыБД);
Для Каждого СтрокаШаблона Из СловарьШаблоновМетаданных.НайтиСтроки(Новый Структура("КоличествоПараметров", 1)) Цикл
ИмяКандидат = СтрЗаменить(СтрокаШаблона.ПозиционныйШаблон, "1", СтрокаНомерТаблицы);
СтрокаСтруктуры = СтруктураБД.Найти(ИмяКандидат, "КраткоеИмяТаблицыХранения");
Если СтрокаСтруктуры <> Неопределено Тогда
Возврат СтрокаСтруктуры.Метаданные;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Процедура ОтладитьОтложенныйОбъектЛкс(Знач СсылкаИлиИмяФайла = Неопределено, УдалитьОбъектПослеУспешногоОткрытия = Ложь) Экспорт
СтруктураПараметров = Неопределено;
ирПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
Ссылка = Справочники.ирОбъектыДляОтладки.ПустаяСсылка();
ирПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если СсылкаИлиИмяФайла = Неопределено Тогда
ВычислительРегулярныхВыражений = ирПлатформа.RegExp;
ВычислительРегулярныхВыражений.Pattern = "Объект ""([^""]+)""|Файл ""([^""]+)""|Пользователь ""([^""]+)""";
СсылкаИлиИмяФайла = ПолучитьТекстИзБуфераОбменаОСЛкс();
Результат = ВычислительРегулярныхВыражений.Execute(СсылкаИлиИмяФайла);
ЕстьСправочник = Метаданные.Справочники.Найти("ирОбъектыДляОтладки") <> Неопределено;
//Если Не ВвестиСтроку(СсылкаИлиИмяФайла, "Введите результат сохранения объекта") Тогда
ФормаВвода = ирПлатформа.ПолучитьФорму("ОткрытьОбъектДляОтладки");
Если Результат.Count > 0 Тогда
ФормаВвода.Текст = СсылкаИлиИмяФайла;
КонецЕсли;
СсылкаИлиИмяФайла = ФормаВвода.ОткрытьМодально();
Если Не ЗначениеЗаполнено(СсылкаИлиИмяФайла) Тогда
Если ЕстьСправочник Тогда
СсылкаИлиИмяФайла = ВыбратьСсылкуЛкс(Метаданные.Справочники.ирОбъектыДляОтладки,, Ложь);
Иначе
ПутьДляФайловОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс();
Расширение = ПолучитьРасширениеФайловДляОтладкиЛкс();
лПолноеИмяФайла = ВыбратьФайлЛкс(, Расширение, "Файлы объектов для отладки",, ПутьДляФайловОбъектовДляОтладки);
Если лПолноеИмяФайла <> Неопределено Тогда
СсылкаИлиИмяФайла = "Файл """ + лПолноеИмяФайла + """";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(СсылкаИлиИмяФайла) Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда
Результат = ВычислительРегулярныхВыражений.Execute(СсылкаИлиИмяФайла);
Если Результат.Count = 0 Тогда
СообщитьЛкс("Введен некорректный результат сохранения объекта для отладки");
Возврат;
КонецЕсли;
Если Результат.Item(0).SubMatches(0) <> Неопределено Тогда
Если ЕстьСправочник Тогда
ВычислительРегулярныхВыражений.Pattern = "\b(" + ирПлатформа.шGUID + ")\b";
Результат = ВычислительРегулярныхВыражений.Execute(СсылкаИлиИмяФайла);
Если Результат.Count > 0 Тогда
СсылкаИлиИмяФайла = Результат.Item(0).Value;
Иначе
СсылкаИлиИмяФайла = Неопределено;
КонецЕсли;
Иначе
СсылкаИлиИмяФайла = Неопределено;
КонецЕсли;
Если СсылкаИлиИмяФайла = Неопределено Тогда
СообщитьЛкс("Введен некорректный результат сохранения объекта для отладки");
Возврат;
КонецЕсли;
СсылкаИлиИмяФайла = Справочники.ирОбъектыДляОтладки.ПолучитьСсылку(Новый УникальныйИдентификатор(СсылкаИлиИмяФайла));
Если Не ЗначениеЗаполнено(СсылкаИлиИмяФайла) Тогда
СообщитьЛкс("Объект для отладки не найден в справочнике");
Возврат;
КонецЕсли;
ИначеЕсли Результат.Item(0).SubMatches(1) <> Неопределено Тогда
СсылкаИлиИмяФайла = Результат.Item(0).SubMatches(1);
Если ЕстьСправочник Тогда
// Перекладываем из файла в новый элемент справочника
ФайлОбъектаДляОтладки = Новый Файл(СсылкаИлиИмяФайла);
ОбъектДляОтладки = ВосстановитьОбъектИзСтрокиXMLЛкс(ФайлОбъектаДляОтладки);
РезультатОтложения = ОтложитьУпакованныйОбъектДляОтладкиЛкс(ОбъектДляОтладки, СсылкаИлиИмяФайла);
СообщитьЛкс(РезультатОтложения);
УдалитьФайлы(ФайлОбъектаДляОтладки.ПолноеИмя);
КонецЕсли;
ИначеЕсли Результат.Item(0).SubMatches(2) <> Неопределено Тогда
ИмяПользователя = Результат.Item(0).SubMatches(2);
СтруктураПараметров = ХранилищеОбщихНастроек.Загрузить(ирКэш.ИмяПродукта(), ИмяНастройкиХраненияОбъектаОтложеннойОтладкиЛкс(),, ИмяПользователя);
Если СтруктураПараметров = Неопределено Тогда
СообщитьЛкс("Объект для отладки не найден в общих настройках пользователя """ + ИмяПользователя + """");
Возврат;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СтруктураПараметров = Неопределено Тогда
//Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда
// СтрокаРезультата = ПолучитьИзВременногоХранилища(СсылкаИлиИмяФайла);
// Если СтрокаРезультата = Неопределено Тогда
// СообщитьЛкс("Временное хранилище пусто. Вероятно отлаживаемый сеанс завершился.");
// Возврат;
// КонецЕсли;
ЧтениеXML = Новый ЧтениеXML;
Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда
ЧтениеXML.ОткрытьФайл(СсылкаИлиИмяФайла);
ИначеЕсли ЛиСсылкаНаОбъектБДЛкс(СсылкаИлиИмяФайла) Тогда
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
| ирОбъектыДляОтладки.XML
|ИЗ
| Справочник.ирОбъектыДляОтладки КАК ирОбъектыДляОтладки
|ГДЕ
| ирОбъектыДляОтладки.Ссылка = &Ссылка
|";
Запрос.УстановитьПараметр("Ссылка", СсылкаИлиИмяФайла);
ТаблицаРезультата = Запрос.Выполнить().Выгрузить();
Если ТаблицаРезультата.Количество() = 0 Тогда
СообщитьЛкс("Объект для отладки не найден в справочнике. Вероятно он был удален.");
Возврат;
КонецЕсли;
СтрокаРезультата = ТаблицаРезультата[0];
СтрокаРезультата = СтрокаРезультата.XML;
ЧтениеXML.УстановитьСтроку(СтрокаРезультата);
КонецЕсли;
Попытка
СтруктураПараметров = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Исключение
ОписаниеОшибки = ОписаниеОшибки();
СообщитьЛкс("Некорректный объект для отладки: " + ОписаниеОшибки, СтатусСообщения.Внимание);
Возврат;
КонецПопытки;
КонецЕсли;
ОтладитьОбъектПоСтруктуреЛкс(СтруктураПараметров);
Если УдалитьОбъектПослеУспешногоОткрытия Тогда
Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда
УдалитьФайлы(СсылкаИлиИмяФайла);
Иначе
УдалениеОбъекта = Новый УдалениеОбъекта(СсылкаИлиИмяФайла);
УдалениеОбъекта.ОбменДанными.Загрузка = Истина;
УдалениеОбъекта.Записать();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ОтладитьОбъектПоСтруктуреЛкс(Знач СтруктураПараметров) Экспорт
#Если Сервер И Не Сервер Тогда
СтруктураПараметров = Новый Структура;
#КонецЕсли
Объект = СтруктураПараметров.Объект;
Если СтруктураПараметров.Свойство("ИмяПользователя") Тогда
ИмяПользователя = СтруктураПараметров.ИмяПользователя;
Если ИмяПользователя <> ИмяПользователя() Тогда
СообщитьЛкс("Загружаемый снимок объекта для отладки был сделан под другим пользователем (" + ИмяПользователя + ")");
КонецЕсли;
КонецЕсли;
ТипОперации = СтруктураПараметров.ТипОперации;
Если ТипОперации = "Отладить" Тогда
Объект2 = СтруктураПараметров.НастройкаКомпоновки;
Если СтруктураПараметров.Свойство("ТипОбъекта") И СтруктураПараметров.ТипОбъекта = "HttpСоединение" Тогда
// Параметр ИспользоватьАутентификациюОС появился в 8.3.7
Если Объект.Защищенное Тогда
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL;
Иначе
ЗащищенноеСоединение = Неопределено;
КонецЕсли;
Объект = Вычислить("Новый HTTPСоединение(Объект.Сервер, Объект.Порт, Объект.Пользователь, Объект.Пароль,, Объект.Таймаут, ЗащищенноеСоединение, Объект.ИспользоватьАутентификациюОС)");
ЗаполнитьЗначенияСвойств(Объект, СтруктураПараметров.Объект);
Объект2 = Новый HTTPЗапрос;
ЗаполнитьЗначенияСвойств(Объект2, СтруктураПараметров.НастройкаКомпоновки);
Если СтруктураПараметров.НастройкаКомпоновки.ТелоДвоичныеДанные <> Неопределено Тогда
Объект2.УстановитьТелоИзДвоичныхДанных(СтруктураПараметров.НастройкаКомпоновки.ТелоДвоичныеДанные);
КонецЕсли;
ИначеЕсли ТипЗнч(Объект) = Тип("Структура") Тогда
СтруктураЗапроса = Объект;
Объект = Новый Запрос;
Если Истина
И СтруктураЗапроса.Свойство("ВременныеТаблицы")
И СтруктураЗапроса.ВременныеТаблицы <> Неопределено
Тогда
Объект.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Объект2 = "";
#Если Клиент Тогда
СостояниеЛкс("Подготовка временных таблиц");
#КонецЕсли
ТекстЗапросаПодготовки = "";
НеподдерживаемыеКолонки = "";
Для Каждого КлючИЗначение Из СтруктураЗапроса.ВременныеТаблицы Цикл
Если ТекстЗапросаПодготовки <> "" Тогда
ТекстЗапросаПодготовки = ТекстЗапросаПодготовки + ";";
Объект2 = Объект2 + ",";
КонецЕсли;
Объект2 = Объект2 + КлючИЗначение.Ключ;
ТаблицаЗначений = ТаблицаСМинимальнымиТипамиКолонокЛкс(КлючИЗначение.Значение, Истина);
#Если Сервер И Не Сервер Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
ТекстВыбораПолей = "";
СуффиксВыборПодколонки = "_ВыборПодколонки_7в989";
СуффиксПодколонкиБезТипов = "_Значение_7в989";
СуффиксПодколонкиЗначениеДляТипов = "_ЗначениеДляТипа_7в989";
ЕстьКолонкиСТипомТип = Ложь;
Для ИндексКолонки = 0 По ТаблицаЗначений.Колонки.Количество() - 1 Цикл
Колонка = ТаблицаЗначений.Колонки[ИндексКолонки]; // Состав коллекции расширяется, но нам нужно обойти только начальный состав
Если Ложь
Или Колонка.ТипЗначения.СодержитТип(Тип("МоментВремени"))
Или (ирКэш.НомерРежимаСовместимостиЛкс() < 803012 И Колонка.ТипЗначения.СодержитТип(Тип("УникальныйИдентификатор")))
//Или Колонка.ТипЗначения.СодержитТип(Тип("Тип"))
Тогда
Если НеподдерживаемыеКолонки <> "" Тогда
НеподдерживаемыеКолонки = НеподдерживаемыеКолонки + ", ";
КонецЕсли;
НеподдерживаемыеКолонки = НеподдерживаемыеКолонки + КлючИЗначение.Ключ + "." + Колонка.Имя;
ИначеЕсли Колонка.ТипЗначения.СодержитТип(Тип("Тип")) Тогда
ЕстьКолонкиСТипомТип = Истина;
ИмяКолонкиВыбораПодколонки = Колонка.Имя + СуффиксВыборПодколонки;
ИмяКолонкиЗначениеДляТипов = Колонка.Имя + СуффиксПодколонкиЗначениеДляТипов;
ИмяКолонкиБезТипов = Колонка.Имя + СуффиксПодколонкиБезТипов;
ТаблицаЗначений.Колонки.Добавить(ИмяКолонкиВыбораПодколонки, Новый ОписаниеТипов("Строка",,,, Новый КвалификаторыСтроки(10)));
ОписаниеТиповКолонкиБезТипов = Новый ОписаниеТипов(Колонка.ТипЗначения,, "Тип, Null");
Если ОписаниеТиповКолонкиБезТипов.Типы().Количество() > 0 Тогда
ТаблицаЗначений.Колонки.Добавить(ИмяКолонкиБезТипов, ОписаниеТиповКолонкиБезТипов);
ВыражениеПоляБезТипов = "Т." + ИмяКолонкиБезТипов;
Иначе
ВыражениеПоляБезТипов = "НЕОПРЕДЕЛЕНО";
КонецЕсли;
ТаблицаЗначений.Колонки.Добавить(ИмяКолонкиЗначениеДляТипов);
ТекстВыбораПолей = ТекстВыбораПолей +
"
| , ВЫБОР КОГДА Т." + ИмяКолонкиВыбораПодколонки + " = ""Тип""
| ТОГДА ТипЗначения(Т." + ИмяКолонкиЗначениеДляТипов + ")
| КОГДА Т." + ИмяКолонкиВыбораПодколонки + " = ""Null""
| ТОГДА NULL
| ИНАЧЕ " + ВыражениеПоляБезТипов + "
| КОНЕЦ КАК " + Колонка.Имя + "
|";
Для Каждого СтрокаТаблицы Из ТаблицаЗначений Цикл
ЗначениеКолонки = СтрокаТаблицы[Колонка.Имя];
Если ТипЗнч(ЗначениеКолонки) = Тип("Тип") Тогда
СтрокаТаблицы[ИмяКолонкиВыбораПодколонки] = "Тип";
Типы = Новый Массив;
Типы.Добавить(ЗначениеКолонки);
ОписаниеТипов = Новый ОписаниеТипов(Типы);
СтрокаТаблицы[ИмяКолонкиЗначениеДляТипов] = ОписаниеТипов.ПривестиЗначение();
ИначеЕсли ЗначениеКолонки = Null Тогда
// Моноколонку с типом NULL тоже невозможно поместить во временную таблицу из таблицы-параметра
СтрокаТаблицы[ИмяКолонкиВыбораПодколонки] = "Null";
Иначе
СтрокаТаблицы[ИмяКолонкиБезТипов] = ЗначениеКолонки;
КонецЕсли;
КонецЦикла;
ТаблицаЗначений.Колонки.Удалить(Колонка.Имя);
Иначе
ТекстВыбораПолей = ТекстВыбораПолей + ", Т." + Колонка.Имя + " КАК " + Колонка.Имя + "
|";
КонецЕсли;
КонецЦикла;
Если ЕстьКолонкиСТипомТип Тогда
ТаблицаЗначений = ТаблицаСМинимальнымиТипамиКолонокЛкс(ТаблицаЗначений, Истина);
ТекстЗапросаПодготовки = ТекстЗапросаПодготовки + "
|ВЫБРАТЬ Т.* ПОМЕСТИТЬ _Т ИЗ &" + КлючИЗначение.Ключ + " КАК Т;
|ВЫБРАТЬ " + Сред(ТекстВыбораПолей, 2) + " ПОМЕСТИТЬ " + КлючИЗначение.Ключ + " ИЗ _Т КАК Т;
|УНИЧТОЖИТЬ _Т";
Иначе
ТекстЗапросаПодготовки = ТекстЗапросаПодготовки + "
|ВЫБРАТЬ Т.* ПОМЕСТИТЬ " + КлючИЗначение.Ключ + " ИЗ &" + КлючИЗначение.Ключ + " КАК Т";
КонецЕсли;
Объект.Параметры.Вставить(КлючИЗначение.Ключ, ТаблицаЗначений);
КонецЦикла;
Если НеподдерживаемыеКолонки <> "" Тогда
// https://partners.v8.1c.ru/forum/t/1570237/m/1570237
ВызватьИсключение "Невозможно восстановить временные таблицы из-за недопустимых типов (МоментВремени, УникальныйИдентификатор, Тип) в колонках: " + НеподдерживаемыеКолонки;
КонецЕсли;
Если ЗначениеЗаполнено(ТекстЗапросаПодготовки) Тогда
Объект.Текст = ТекстЗапросаПодготовки;
Попытка
Объект.Выполнить();
Исключение
СообщитьЛкс("Ошибка восстановления временных таблиц: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЕсли;
Объект.Параметры.Очистить();
Объект.Текст = СтруктураЗапроса.Текст;
// Антибаг платформы 8.2.18. Некорректная сериализация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураЗапроса.Параметры, Объект.Параметры);
Для Каждого КлючИЗначение Из СтруктураЗапроса.Параметры Цикл
Объект.Параметры.Вставить(КлючИЗначение.Ключ, ЗначениеИзСтрокиВнутр(КлючИЗначение.Значение));
КонецЦикла;
КонецЕсли;
ОтладитьЛкс(Объект, , Объект2, СтруктураПараметров.ВнешниеНаборыДанных);
ИначеЕсли ТипОперации = "Исследовать" Тогда
Если СтруктураПараметров.Свойство("СериализацияФабрикой") И СтруктураПараметров.СериализацияФабрикой Тогда
Объект = ОбъектXDTOИзСтрокиXMLЛкс(Объект, Истина);
КонецЕсли;
ИсследоватьЛкс(Объект, , СтруктураПараметров.КакКоллекцию);
КонецЕсли;
КонецПроцедуры
Функция ОбъектXDTOИзСтрокиXMLЛкс(Объект, СТипами = Ложь) Экспорт
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(Объект);
Если СТипами Тогда
XMLТип = СериализаторXDTO.ПолучитьXMLТип(Чтение);
Если XMLТип <> Неопределено Тогда
ТипОбъекта = ФабрикаXDTO.Тип(XMLТип.URIПространстваИмен, XMLТип.ИмяТипа);
КонецЕсли;
КонецЕсли;
Результат = ФабрикаXDTO.ПрочитатьXML(Чтение, ТипОбъекта);
Возврат Результат;
КонецФункции
// ОформляемыеКолонки - имена колонок, разделенные запятыми
Процедура ОтобразитьПустыеЗначенияВЯчейкахТабличногоПоля(ОформлениеСтроки, Знач ОформляемыеКолонки = "") Экспорт
ирПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
ирПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ОформляемыеКолонки = Новый Структура(ОформляемыеКолонки);
НеФильтровтатьКолонки = (ОформляемыеКолонки.Количество() = 0);
Для Каждого Ячейка Из ОформлениеСтроки.Ячейки Цикл
Если Ложь
Или НеФильтровтатьКолонки
Или ОформляемыеКолонки.Свойство(Ячейка.Имя)
Тогда
ЗначениеЯчейки = Ячейка.Значение;
Если Не ЗначениеЗаполнено(ЗначениеЯчейки) Тогда
Ячейка.УстановитьТекст(ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ЗначениеЯчейки));
Ячейка.ЦветФона = WebЦвета.Роса;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ОтобразитьПустыеЗначенияВЯчейкахТабличногоПоля()
Процедура ПолеВвода_ОкончаниеВводаТекстаЛкс(Элемент, Текст, Значение, СтандартнаяОбработка, РасширенноеЗначение = Null, ЛиТипСтрокаСлужебный = Ложь) Экспорт
Менеджер = Неопределено;
ТекущеееЗначение = ДанныеЭлементаФормыЛкс(Элемент);
Если ТипЗнч(ТекущеееЗначение) = Тип("Строка") Тогда
Элемент.Значение = Текст; // Восстановим значение, т.к. при чтении из него в режиме пароля оно меняется на "*************"
Попытка
ТипЗначенияПоля = ПолучитьТипЗначенияЭлементаФормыЛкс(Элемент);
Исключение
Если ТипЗнч(Элемент) = Тип("ПолеВвода") Тогда
ВызватьИсключение;
Иначе
// Для поля формы игнорируем
Возврат;
КонецЕсли;
КонецПопытки;
Типы = ТипЗначенияПоля.Типы();
Если Типы.Количество() > 1 Тогда
ЗначениеСсылки = НавигационнаяСсылкаВЗначениеЛкс(ТекущеееЗначение);
Если Не ЗначениеЗаполнено(ЗначениеСсылки) Тогда
ПредставлениеЗначения = СтрокаМеждуМаркерамиЛкс(ТекущеееЗначение, "(", ")");
ЗначениеСсылки = ПреобразоватьЗначениеИзSDBLЛкс(ПредставлениеЗначения);
КонецЕсли;
Если Истина
И ЗначениеСсылки <> Неопределено
И ТипЗнч(ЗначениеСсылки) <> Тип("Строка")
И Элемент.ТипЗначения.СодержитТип(ТипЗнч(ЗначениеСсылки))
Тогда
Ответ = КодВозвратаДиалога.Да;
Если Не ЛиТипСтрокаСлужебный Тогда
Ответ = Вопрос("Хотите вставить строку как ссылку?", РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Нет);
КонецЕсли;
Если Ответ = КодВозвратаДиалога.Да Тогда
Значение = ЗначениеСсылки;
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(ЗначениеСсылки) Тогда
Фрагменты = СтрРазделитьЛкс(ТекущеееЗначение);
Если Фрагменты.Количество() > 1 Тогда
ИмяТипа = Фрагменты[0] + "." + Фрагменты[1];
Попытка
ОписаниеТипов = Новый ОписаниеТипов(ИмяТипа);
Исключение
ОписаниеТипов = Неопределено;
КонецПопытки;
Если ОписаниеТипов <> Неопределено Тогда
Значение = ОписаниеТипов.ПривестиЗначение();
Менеджер = ПолучитьМенеджерЛкс(Значение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И ЛиТипСтрокаСлужебный
И СтандартнаяОбработка
И ЗначениеЗаполнено(ТекущеееЗначение)
Тогда
Значение = "";
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЛиТипСсылкиБДЛкс(ТипЗнч(ТекущеееЗначение)) Тогда
Менеджер = ПолучитьМенеджерЛкс(ТекущеееЗначение);
КонецЕсли;
Если Менеджер <> Неопределено Тогда
Значение = ПреобразоватьПредставлениеВСсылкуЛкс(Менеджер, Текст);
Если Значение <> Неопределено Тогда
СтандартнаяОбработка = Ложь;
КонецЕсли;
Иначе
Если Ложь
Или (Истина
И РасширенноеЗначение <> Null
И ТипЗнч(РасширенноеЗначение) <> ТипЗнч(ТекущеееЗначение))
Или Элемент.ОграничениеТипа.ПривестиЗначение(ТекущеееЗначение) <> ТекущеееЗначение
Тогда
// Откат
СтандартнаяОбработка = Ложь;
Значение = Новый СписокЗначений;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция НавигационнаяСсылкаВЗначениеЛкс(Знач ТекущеееЗначение) Экспорт
//e1cib/data/Справочник.ирОбъектыДляОтладки?ref=aa3a0009dd50223411e1c2907cccb6b7
Маркер = "e1cib/data/";
ТекстСсылки = ПоследнийФрагментЛкс(ТекущеееЗначение, Маркер, Ложь);
Если ЗначениеЗаполнено(ТекстСсылки) Тогда
Разделитель = "?ref=";
Идентификатор = ПоследнийФрагментЛкс(ТекстСсылки, Разделитель);
Идентификатор = ПолучитьГУИДПрямойИзИнверсногоЛкс(Идентификатор);
ПолноеИмяМД = ПервыйФрагментЛкс(ТекстСсылки, Разделитель);
лМенеджер = Новый (СтрЗаменить(ПолноеИмяМД, ".", "Менеджер."));
ЗначениеСсылки = лМенеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(Идентификатор));
КонецЕсли;
Возврат ЗначениеСсылки;
КонецФункции
Функция ПреобразоватьПредставлениеВСсылкуЛкс(Знач МенеджерИлиОбъектМД, Знач Текст, КэшПоиска = Неопределено) Экспорт
Если ТипЗнч(МенеджерИлиОбъектМД) = Тип("ОбъектМетаданных") Тогда
Менеджер = ПолучитьМенеджерЛкс(МенеджерИлиОбъектМД);
Иначе
Менеджер = МенеджерИлиОбъектМД;
КонецЕсли;
Текст = СокрЛП(Текст);
УникальныйИдентификатор = ирКэш.Получить().ПолучитьУникальныйИдентификаторИзСтроки(Текст);
Если УникальныйИдентификатор <> Неопределено Тогда
Значение = Менеджер.ПолучитьСсылку(УникальныйИдентификатор);
Иначе
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(Менеджер));
RegExp = ирКэш.Получить().RegExp;
RegExp.Pattern = "([^ ]+)\ от\ (\d+\.\d+\.\d+\ \d+\:\d+\:\d+)$";
Результаты = RegExp.Execute(Текст);
Если Результаты.Count > 0 Тогда
Номер = Результаты.Item(0).Submatches(0);
Дата = Результаты.Item(0).Submatches(1);
Попытка
Дата = Дата(Дата);
Исключение
Дата = Неопределено;
КонецПопытки;
Если Дата <> Неопределено Тогда
Если КэшПоиска <> Неопределено Тогда
Значение = КэшПоиска[Текст];
КонецЕсли;
Если Значение = Неопределено Тогда
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
| _Т.Ссылка
|ИЗ
| " + ОбъектМД.ПолноеИмя() + " КАК _Т
|ГДЕ
| _Т.Номер = &Номер
| И _Т.Дата = &Дата
|";
Запрос.УстановитьПараметр("Номер", Номер);
Запрос.УстановитьПараметр("Дата", Дата);
Значение = Новый СписокЗначений;
Значение.ЗагрузитьЗначения(Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(0));
Если Значение.Количество() > 0 Тогда
Для Каждого ЭлементСписка Из Значение Цикл
ЭлементСписка.Представление = "" + ЭлементСписка.Значение + " (" + ЭлементСписка.Значение.УникальныйИдентификатор() + ")";
КонецЦикла;
КонецЕсли;
Если КэшПоиска <> Неопределено Тогда
КэшПоиска[Текст] = Значение;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Значение;
КонецФункции
// Параметры:
// РедактированиеРазрешено - Булево - для открытия ссылки надо установить Ложь
// ЭлементУправления - Неопределено - значение этого элемента управления открываем, при открытии значения из ячейки табличного поля должно быть Неопределено
// ЭлементУправленияРодитель - ТабличноеПоле - чью ячейку открываем
// Результат - Булево - Истина если значение было изменено
Функция ОткрытьЗначениеЛкс(РасширенноеЗначение, РедактированиеРазрешено = Истина, СтандартнаяОбработка = Истина, ЗаголовокФормы = "", РедактироватьМодально = Истина,
ПринудительноВОтдельнойФорме = Истина, ЭлементУправления = Неопределено, ЭлементУправленияРодитель = Неопределено) Экспорт
Результат = Ложь;
ТипРасширенногоЗначения = ТипЗнч(РасширенноеЗначение);
ХмлТип = XMLТипЗнч(РасширенноеЗначение);
Если Ложь
Или ТипРасширенногоЗначения = Тип("ТаблицаЗначений")
Или ТипРасширенногоЗначения = Тип("ДеревоЗначений")
Или ТипРасширенногоЗначения = Тип("МоментВремени")
Или ТипРасширенногоЗначения = Тип("ТабличныйДокумент")
Или ТипРасширенногоЗначения = Тип("Массив")
Или ТипРасширенногоЗначения = Тип("Граница")
Или ТипРасширенногоЗначения = Тип("УникальныйИдентификатор")
Или ТипРасширенногоЗначения = Тип("Тип")
Или ТипРасширенногоЗначения = Тип("ОписаниеТипов")
Или ТипРасширенногоЗначения = Тип("СписокЗначений")
Или ТипРасширенногоЗначения = Тип("ДвоичныеДанные")
Или ТипРасширенногоЗначения = Тип("ХранилищеЗначения")
Или ТипРасширенногоЗначения = Тип("Картинка")
Или (Истина
И ТипРасширенногоЗначения = Тип("Строка")
И (Ложь
Или ПринудительноВОтдельнойФорме
Или СтрДлина(РасширенноеЗначение) > 150
Или Не РедактированиеРазрешено))
Тогда
СтандартнаяОбработка = Ложь;
ЕстьРастягивающиесяВертикальноЭлементы = Истина;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если Ложь
Или ТипРасширенногоЗначения = Тип("ТаблицаЗначений")
Или ТипРасширенногоЗначения = Тип("ДеревоЗначений")
Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ТаблицаЗначений", , РасширенноеЗначение);
ФормаРедактирования.ТабличноеПоле = ЭлементУправления;
ИначеЕсли ТипРасширенногоЗначения = Тип("МоментВремени") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("МоментВремени", , РасширенноеЗначение);
ЕстьРастягивающиесяВертикальноЭлементы = Ложь;
ИначеЕсли ТипРасширенногоЗначения = Тип("ТабличныйДокумент") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ТабличныйДокумент", , РасширенноеЗначение);
Если ЭлементУправления <> Неопределено Тогда
ФормаРедактирования.ПолеТабличногоДокумента = ЭлементУправления;
Иначе
ФормаРедактирования.ПолеТабличногоДокумента = РасширенноеЗначение;
КонецЕсли;
ИначеЕсли ТипРасширенногоЗначения = Тип("Граница") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("Граница", , РасширенноеЗначение);
ЕстьРастягивающиесяВертикальноЭлементы = Ложь;
ИначеЕсли ТипРасширенногоЗначения = Тип("Массив") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("Массив", , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("УникальныйИдентификатор") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("УникальныйИдентификатор", , РасширенноеЗначение);
ЕстьРастягивающиесяВертикальноЭлементы = Ложь;
ИначеЕсли ТипРасширенногоЗначения = Тип("СписокЗначений") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("СписокЗначений", , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("Строка") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("Текст", , Новый УникальныйИдентификатор());
ИначеЕсли ТипРасширенногоЗначения = Тип("Тип") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ВыборРедактируемыхТипов", , ТипРасширенногоЗначения);
ФормаРедактирования.РежимВыбора = Истина;
ФормаРедактирования.МножественныйВыбор = Ложь;
ИначеЕсли ТипРасширенногоЗначения = Тип("ОписаниеТипов") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ВыборРедактируемыхТипов", , РасширенноеЗначение);
ФормаРедактирования.РежимВыбора = Истина;
ФормаРедактирования.МножественныйВыбор = Истина;
ИначеЕсли ТипРасширенногоЗначения = Тип("ХранилищеЗначения") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ХранилищеЗначения", , Новый УникальныйИдентификатор());
ЕстьРастягивающиесяВертикальноЭлементы = Ложь;
ИначеЕсли ТипРасширенногоЗначения = Тип("ДвоичныеДанные") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ДвоичныеДанные", , Новый УникальныйИдентификатор());
ИначеЕсли ТипРасширенногоЗначения = Тип("Картинка") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("Картинка", , Новый УникальныйИдентификатор());
КонецЕсли;
Если ЗначениеЗаполнено(ЗаголовокФормы) Тогда
ФормаРедактирования.Заголовок = ЗаголовокФормы;
КонецЕсли;
Если ФормаРедактирования.Открыта() Тогда
ФормаРедактирования.Активизировать();
Возврат Результат;
КонецЕсли;
ФормаРедактирования.ТолькоПросмотр = Не РедактированиеРазрешено;
Если РедактированиеРазрешено И РедактироватьМодально Тогда
ФормаРедактирования.НачальноеЗначениеВыбора = КопияОбъектаЛкс(РасширенноеЗначение, ); // Опасно
Иначе
ФормаРедактирования.НачальноеЗначениеВыбора = РасширенноеЗначение;
КонецЕсли;
Если Ложь
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Или Не ЕстьРастягивающиесяВертикальноЭлементы // https://www.hostedredmine.com/issues/901852
#КонецЕсли
Или РедактированиеРазрешено И РедактироватьМодально
Тогда
РезультатВыбора = ФормаРедактирования.ОткрытьМодально();
Если РезультатВыбора <> Неопределено Тогда
РасширенноеЗначение = РезультатВыбора;
Результат = Истина;
КонецЕсли;
Иначе
ФормаРедактирования.Открыть();
КонецЕсли;
ИначеЕсли Ложь
Или ТипРасширенногоЗначения = Тип("Число")
Или ТипРасширенногоЗначения = Тип("Строка")
Или ТипРасширенногоЗначения = Тип("Дата")
Или ТипРасширенногоЗначения = Тип("Булево")
Или ТипРасширенногоЗначения = Тип("Неопределено")
Или ТипРасширенногоЗначения = Тип("Null")
Или ТипРасширенногоЗначения = Тип("ПолеКомпоновкиДанных")
Или ТипРасширенногоЗначения = Тип("СтандартнаяДатаНачала")
Или ТипРасширенногоЗначения = Тип("СтандартныйПериод")
Или ТипРасширенногоЗначения = Тип("ВидДвиженияНакопления")
Или ТипРасширенногоЗначения = Тип("ВидДвиженияБухгалтерии")
Или ТипРасширенногоЗначения = Тип("ВидСчета")
Или (Истина
И ХмлТип <> Неопределено
И Найти(ХмлТип.ИмяТипа, "Ref.") > 0)
Тогда
Если ЛиТипСсылкиБДЛкс(ТипРасширенногоЗначения, Ложь) Тогда
Если ЗначениеЗаполнено(РасширенноеЗначение) Тогда
ОбъектСуществует = ЛиСуществуетОбъектПоСсылкеЛкс(РасширенноеЗначение);
Если Не ОбъектСуществует И Не ПринудительноВОтдельнойФорме Тогда
//ОткрытьСсылкуЯчейкиВРедактореОбъектаБДЛкс(ТабличноеПоле);
ОткрытьСсылкуВРедактореОбъектаБДЛкс(РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Ложь
Или Не СтандартнаяОбработка
Или Не РедактированиеРазрешено
Или ЭлементУправленияРодитель = Неопределено
Тогда
Если ЛиТипСсылкиБДЛкс(ТипРасширенногоЗначения, Ложь) Тогда
Если Истина
И ЗначениеЗаполнено(РасширенноеЗначение)
И ОбъектСуществует
Тогда
Если Не ЛиДоступноРедактированиеВФормеОбъектаЛкс(Метаданные.НайтиПоТипу(ТипРасширенногоЗначения)) Тогда
ОткрытьСсылкуВРедактореОбъектаБДЛкс(РасширенноеЗначение);
Иначе
ОткрытьЗначение(РасширенноеЗначение);
КонецЕсли;
КонецЕсли;
СтандартнаяОбработка = Ложь;
КонецЕсли;
Если СтандартнаяОбработка Тогда
ОткрытьЗначение(РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
Иначе
//Если Истина
// И ТипЗначения1 <> Неопределено
// И ТипЗначения1.ПривестиЗначение(РасширенноеЗначение) <> РасширенноеЗначение
//Тогда
ИсследоватьЛкс(РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
//КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОткрытьКонсольСерверов1СБезПараметровЛкс() Экспорт
ОткрытьКонсольСерверов1СЛкс();
КонецПроцедуры
Процедура ОткрытьКонсольСерверов1СЛкс(Знач СборкаПлатформы = Неопределено, ТаблицаСерверов = Неопределено) Экспорт
ОбработкаРегистрации = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирУправлениеCOMКлассами1С");
#Если Сервер И Не Сервер Тогда
ОбработкаРегистрации = Обработки.ирУправлениеCOMКлассами1С.Создать();
ТекущаяСтрокаТаблицыСерверов = Обработки.ирУправлениеСлужбамиСервера1С.Создать().СлужбыАгентовСерверов.Добавить();
#КонецЕсли
ОбработкаРегистрации.ЗаполнитьТипыCOMКлассов();
ирОбщий.ЗаполнитьДоступныеСборкиПлатформыЛкс(ОбработкаРегистрации.СборкиПлатформы,, ОбработкаРегистрации.ТипыComКлассов);
ТипКласса = "ServerAdminScope";
Если Не ЗначениеЗаполнено(СборкаПлатформы) Тогда
СборкаПлатформы = ОбработкаРегистрации.ТекущаяСборкаПлатформы;
КонецЕсли;
СтрокаСборкиПлатформы = ОбработкаРегистрации.СборкиПлатформы.НайтиСтроки(Новый Структура("СборкаПлатформы," + ТипКласса, СборкаПлатформы, Истина));
Если СтрокаСборкиПлатформы.Количество() = 0 Тогда
Возврат;
КонецЕсли;
СтрокаСборкиПлатформы = СтрокаСборкиПлатформы[0];
#Если Сервер И Не Сервер Тогда
СтрокаСборкиПлатформы = ОбработкаРегистрации.СборкиПлатформы[0];
#КонецЕсли
ПолноеИмяФайлаКонсоли = "";
КаталогПрограммныхФайлов = ирОбщий.КаталогПрограммныхФайловОСЛкс(СтрокаСборкиПлатформы.x64);
Если ирКэш.НомерИзданияПлатформыЛкс() = "81" Тогда
ПолноеИмяФайлаКонсоли = КаталогПрограммныхФайлов + "\1cv81\bin\1CV8 Servers.msc";
Файл = Новый Файл(ПолноеИмяФайлаКонсоли);
Если Не Файл.Существует() Тогда
ПолноеИмяФайлаКонсоли = "";
КонецЕсли;
ИначеЕсли ирКэш.НомерИзданияПлатформыЛкс() = "82" Тогда
ПолноеИмяФайлаКонсоли = КаталогПрограммныхФайлов + "\1cv82\common\";
Если СтрокаСборкиПлатформы.x64 Тогда
ПолноеИмяФайлаКонсоли = ПолноеИмяФайлаКонсоли + "1CV8 Servers (x86-64).msc";
Иначе
ПолноеИмяФайлаКонсоли = ПолноеИмяФайлаКонсоли + "1CV8 Servers.msc";
КонецЕсли;
Файл = Новый Файл(ПолноеИмяФайлаКонсоли);
Если Не Файл.Существует() Тогда
ПолноеИмяФайлаКонсоли = "";
КонецЕсли;
ИначеЕсли ирКэш.НомерИзданияПлатформыЛкс() = "83" Тогда
ПолноеИмяФайлаКонсоли = КаталогПрограммныхФайлов + "\1cv8\common\";
Если СтрокаСборкиПлатформы.x64 Тогда
ПолноеИмяФайлаКонсоли = ПолноеИмяФайлаКонсоли + "1CV8 Servers (x86-64).msc";
Иначе
ПолноеИмяФайлаКонсоли = ПолноеИмяФайлаКонсоли + "1CV8 Servers.msc";
КонецЕсли;
Файл = Новый Файл(ПолноеИмяФайлаКонсоли);
Если Не Файл.Существует() Тогда
ПолноеИмяФайлаКонсоли = "";
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(ПолноеИмяФайлаКонсоли) Тогда
Если ТаблицаСерверов <> Неопределено Тогда
ТаблицаСерверов = ПолучитьТаблицуСерверовИзСпискаПользователя(ТаблицаСерверов);
ПоместитьТаблицуСерверовВСписокПользователя(ТаблицаСерверов);
КонецЕсли;
//ОбработкаРегистрации = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирУправлениеCOMКлассами1С");
//#Если Сервер И Не Сервер Тогда
// ОбработкаРегистрации = Обработки.ирУправлениеCOMКлассами1С.Создать();
//#КонецЕсли
//ОбработкаРегистрации.ЗаполнитьТипыCOMКлассов();
//ОбработкаРегистрации.СборкиПлатформы.Загрузить(СборкиПлатформы.Выгрузить());
СтрокаТипаКласса = ОбработкаРегистрации.ТипыComКлассов.Найти(ТипКласса, "Имя");
ОбработкаРегистрации.ЗарегистрироватьCOMКлассСборкиПлатформы(СтрокаТипаКласса, СтрокаСборкиПлатформы.x64, СтрокаСборкиПлатформы.СборкаПлатформы);
ЗапуститьПриложение("""" + ПолноеИмяФайлаКонсоли + """");
Иначе
Если СтрокаСборкиПлатформы.x64 Тогда
ПредставлениеРазрядности = "64";
Иначе
ПредставлениеРазрядности = "32";
КонецЕсли;
Сообщить("Файл консоли серверов 1С " + ирКэш.НомерИзданияПлатформыЛкс() + " " + ПредставлениеРазрядности + "б не найден по пути """ + ПолноеИмяФайлаКонсоли + """");
КонецЕсли;
КонецПроцедуры
Функция ПолучитьПолноеИмяФайлаСпискаСерверов1С() Экспорт
КаталогФайловыхКэшей = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс();
ПолноеИмяФайлаСпискаСерверов = КаталогФайловыхКэшей + "\" + "appsrvrs.lst";
Возврат ПолноеИмяФайлаСпискаСерверов;
КонецФункции
Функция ПолучитьТаблицуСерверовИзСпискаПользователя(ТаблицаСерверов = Неопределено) Экспорт
ТаблицаСерверовИзФайла = Новый ТаблицаЗначений;
ТаблицаСерверовИзФайла.Колонки.Добавить("Протокол");
ТаблицаСерверовИзФайла.Колонки.Добавить("Компьютер");
ТаблицаСерверовИзФайла.Колонки.Добавить("НКомпьютер");
ТаблицаСерверовИзФайла.Колонки.Добавить("Порт");
ТаблицаСерверовИзФайла.Колонки.Добавить("Наименование");
//ТаблицаСерверовИзФайла.Колонки.Добавить("ИзданиеПлатформы");
ТаблицаСерверов.Колонки.Добавить("НКомпьютер");
Для Каждого СтрокаСервера Из ТаблицаСерверов Цикл
СтрокаСервера.НКомпьютер = НРег(СтрокаСервера.Компьютер);
КонецЦикла;
ПолноеИмяФайлаСпискаСерверов = ПолучитьПолноеИмяФайлаСпискаСерверов1С();
Файл = Новый Файл(ПолноеИмяФайлаСпискаСерверов);
Если Файл.Существует() Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ПолноеИмяФайлаСпискаСерверов);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
// {2,
// {"tcp","pcname",1540,""},
// {"tcp","pcname",1740,""}
// }
ДокументDOM = ирОбщий.ПолучитьДокументDOMИзСтрокиВнутрЛкс(ТекстФайла);
РазыменовательПИ = Новый РазыменовательПространствИменDOM(ДокументDOM);
ИмяЭлемента = "/elem/elem";
РезультатXPath = ДокументDOM.ВычислитьВыражениеXPath(ИмяЭлемента, ДокументDOM, РазыменовательПИ, ТипРезультатаDOMXPath.УпорядоченныйИтераторУзлов);
Пока 1 = 1 Цикл
Узел = РезультатXPath.ПолучитьСледующий();
Если Узел = Неопределено Тогда
Прервать;
КонецЕсли;
ДочерниеУзлы = Узел.ДочерниеУзлы;
// Здесь есть пробельный узел, который сместит индексы н начиная с 2, если отключить игнорирование пробельных символов при построении документа DOM
Порт = Вычислить(ДочерниеУзлы[2].ТекстовоеСодержимое);
Компьютер = ирОбщий.ПоследнийФрагментЛкс(Вычислить(ДочерниеУзлы[1].ТекстовоеСодержимое), "/"); // Имя компьютера может быть указано в виде "REMOTE/GOMER"
КлючПоиска = Новый Структура("НКомпьютер, Порт", НРег(Компьютер), Порт);
Если ТаблицаСерверовИзФайла.НайтиСтроки(КлючПоиска).Количество() > 0 Тогда
Продолжить;
КонецЕсли;
ОписаниеСервера = ТаблицаСерверовИзФайла.Добавить();
ЗаполнитьЗначенияСвойств(ОписаниеСервера, КлючПоиска);
ОписаниеСервера.Протокол = Вычислить(ДочерниеУзлы[0].ТекстовоеСодержимое);
ОписаниеСервера.Компьютер = Компьютер;
ОписаниеСервера.Наименование = Вычислить(ДочерниеУзлы[3].ТекстовоеСодержимое);
Если Не ЗначениеЗаполнено(ОписаниеСервера.Наименование) Тогда
ОписаниеСервера.Наименование = ОписаниеСервера.Компьютер + ":" + XMLСтрока(ОписаниеСервера.Порт);
КонецЕсли;
СтрокиСервера = ТаблицаСерверов.НайтиСтроки(Новый Структура("НКомпьютер, Порт", ОписаниеСервера.НКомпьютер, ОписаниеСервера.Порт));
КонецЦикла;
КонецЕсли;
Если ТаблицаСерверов <> Неопределено Тогда
Для Каждого СтрокаСервера Из ТаблицаСерверов Цикл
СтрокаСервераИзФайла = ТаблицаСерверовИзФайла.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаСервераИзФайла, СтрокаСервера);
СтрокаСервераИзФайла.Протокол = "tcp";
КонецЦикла;
КонецЕсли;
Возврат ТаблицаСерверовИзФайла;
КонецФункции
Процедура ПоместитьТаблицуСерверовВСписокПользователя(ТаблицаСерверов) Экспорт
#Если _ Тогда
ТаблицаСерверов = Новый ТаблицаЗначений;
ТаблицаСерверов.Колонки.Добавить("Протокол");
ТаблицаСерверов.Колонки.Добавить("Компьютер");
ТаблицаСерверов.Колонки.Добавить("Порт");
ТаблицаСерверов.Колонки.Добавить("Наименование");
#КонецЕсли
// {2,
// {"tcp","pyramid",1540,""},
// {"tcp","pyramid",1740,""}
// }
Текст = "";
Для Каждого СтрокаСервера Из ТаблицаСерверов Цикл
Если Текст <> "" Тогда
Текст = Текст + "," + Символы.ПС;
КонецЕсли;
Текст = Текст + "{"
+ """" + СтрокаСервера.Протокол + ""","
+ """" + СтрокаСервера.Компьютер + ""","
+ XMLСтрока(СтрокаСервера.Порт) + ","
+ """" + СтрокаСервера.Наименование + """"
+ "}";
КонецЦикла;
Текст = "{" + XMLСтрока(ТаблицаСерверов.Количество()) + "," + Символы.ПС + Текст + "}";
ПолноеИмяФайлаСпискаСерверов = ПолучитьПолноеИмяФайлаСпискаСерверов1С();
Файл = Новый Файл(ПолноеИмяФайлаСпискаСерверов);
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(Текст);
ТекстовыйДокумент.Записать(ПолноеИмяФайлаСпискаСерверов);
УстановитьТекущийПутьВДеревеКонсолиСерверов(ТаблицаСерверов);
КонецПроцедуры
Процедура УстановитьТекущийПутьВДеревеКонсолиСерверов(ТаблицаСерверов) Экспорт
МассивПути = ПолучитьМассивПутиКСсылкеВКонсолиСерверов();
ПолноеИмяФайлаНастроекКонсолиСерверов = ирОбщий.КаталогПеремещаемыхДанныхПриложенийЛкс() + "\Microsoft\MMC\1CV8 Servers";
Файл = Новый Файл(ПолноеИмяФайлаНастроекКонсолиСерверов);
Если Не Файл.Существует() Тогда
Возврат;
КонецЕсли;
ДокументDOM = ирОбщий.ПрочитатьФайлВДокументDOMЛкс(ПолноеИмяФайлаНастроекКонсолиСерверов);
РазыменовательПИ = Новый РазыменовательПространствИменDOM(ДокументDOM);
ИмяЭлемента = "/MMC_ConsoleFile/Views/View/BookMark[2]";
РезультатXPath = ДокументDOM.ВычислитьВыражениеXPath(ИмяЭлемента, ДокументDOM, РазыменовательПИ);
ЭлементДом = РезультатXPath.ПолучитьСледующий();
КорневыеЭлементы = ЭлементДом.ПолучитьЭлементыПоИмени("DynamicPath");
Если КорневыеЭлементы.Количество() > 0 Тогда
КорневойЭлемент = КорневыеЭлементы[0];
Иначе
КорневойЭлемент = ДокументDOM.СоздатьЭлемент("DynamicPath");
ЭлементДом.ДобавитьДочерний(КорневойЭлемент);
КонецЕсли;
Пока КорневойЭлемент.ПервыйДочерний <> Неопределено Цикл
КорневойЭлемент.УдалитьДочерний(КорневойЭлемент.ПервыйДочерний);
КонецЦикла;
Для Каждого ЭлементПути Из МассивПути Цикл
ЭлементСегмент = ДокументDOM.СоздатьЭлемент("Segment");
ЭлементСегмент.УстановитьАтрибут("String", ЭлементПути);
КорневойЭлемент.ДобавитьДочерний(ЭлементСегмент);
КонецЦикла;
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ПолноеИмяФайлаНастроекКонсолиСерверов);
ЗаписьДом = Новый ЗаписьDOM;
ЗаписьДом.Записать(ДокументDOM, ЗаписьXML);
КонецПроцедуры
Функция ПолучитьМассивПутиКСсылкеВКонсолиСерверов(Знач ИмяСервера = "")
Если Не ЗначениеЗаполнено(ИмяСервера) Тогда
ИмяСервера = ирОбщий.ИмяКомпьютераКластераЛкс();
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяСервера) Тогда
ИмяСервера = ИмяКомпьютера();
КонецЕсли;
//
//
//
//
//
МассивПути = Новый Массив;
ЭлементПути = ИмяСервера;
Если ирОбщий.ЭтоИмяЛокальногоКомпьютераЛкс(ЭлементПути) Тогда
ЭлементПути = "(*)" + ЭлементПути;
КонецЕсли;
МассивПути.Добавить(ЭлементПути);
Возврат МассивПути;
КонецФункции
Функция ВыбратьСтрокуТаблицыЗначенийЛкс(Знач ТаблицаЗначений, Знач ТекущаяСтрока = Неопределено, Модально = Истина, Заголовок = "") Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ИмитаторТабличногоПоля = Новый Структура;
ИмитаторТабличногоПоля.Вставить("ТекущаяКолонка");
ИмитаторТабличногоПоля.Вставить("ТекущаяСтрока", ТекущаяСтрока);
ИмитаторТабличногоПоля.Вставить("Значение", ТаблицаЗначений);
ИмитаторТабличногоПоля.Вставить("ВыделенныеСтроки", Новый Массив);
ИмитаторТабличногоПоля.Вставить("Подвал", Ложь);
ФормаРедактирования = мПлатформа.ПолучитьФорму("ТаблицаЗначений", , ТаблицаЗначений);
ФормаРедактирования.ТабличноеПоле = ИмитаторТабличногоПоля;
ФормаРедактирования.НачальноеЗначениеВыбора = ТаблицаЗначений;
ФормаРедактирования.ТолькоПросмотр = Истина;
Если ЗначениеЗаполнено(Заголовок) Тогда
ФормаРедактирования.Заголовок = Заголовок;
КонецЕсли;
ФормаРедактирования.РежимВыбора = Истина;
Если Модально Тогда
Результат = ФормаРедактирования.ОткрытьМодально();
Иначе
ФормаРедактирования.Открыть();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ВыбратьЭлементСпискаЗначенийЛкс(Знач СписокЗначений, Знач ТекущийЭлемент = Неопределено, Модально = Истина, Заголовок = "") Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаРедактирования = мПлатформа.ПолучитьФорму("СписокЗначений", , СписокЗначений);
ФормаРедактирования.НачальноеЗначениеВыбора = СписокЗначений;
ФормаРедактирования.НачальныйЭлементСписка = ТекущийЭлемент;
ФормаРедактирования.ТолькоПросмотр = Истина;
Если ЗначениеЗаполнено(Заголовок) Тогда
ФормаРедактирования.Заголовок = Заголовок;
КонецЕсли;
ФормаРедактирования.РежимВыбора = Истина;
Если Модально Тогда
Результат = ФормаРедактирования.ОткрытьМодально();
Иначе
ФормаРедактирования.Открыть();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиСуществуетОбъектПоСсылкеЛкс(Знач РасширенноеЗначение) Экспорт
Запрос = Новый Запрос("ВЫБРАТЬ 1 ИЗ " + ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РасширенноеЗначение)) + " ГДЕ Ссылка = &Ссылка");
Запрос.УстановитьПараметр("Ссылка", РасширенноеЗначение);
ОбъектСуществует = Не Запрос.Выполнить().Пустой();
Возврат ОбъектСуществует;
КонецФункции
Функция ОткрытьРедакторИзПоляТабличногоДокументаЛкс(ПолеТабличногоДокумента) Экспорт
Копия = Новый ТабличныйДокумент;
Копия.Вывести(ПолеТабличногоДокумента);
ЗаполнитьЗначенияСвойств(Копия, ПолеТабличногоДокумента);
Результат = ирОбщий.ОткрытьЗначениеЛкс(Копия,,,, Ложь);
Возврат Результат;
КонецФункции
Функция ОткрытьРедакторСтрокиТаблицыЛкс(ЭтаФорма, ТабличноеПоле, ИмяТаблицыБДТабличногоПоля = Неопределено, СвязиИПараметрыВыбора = Истина) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Форма = мПлатформа.ПолучитьФорму("СтрокаТаблицы", ЭтаФорма, ТабличноеПоле);
Форма.ИмяТаблицыБД = ИмяТаблицыБДТабличногоПоля;
Форма.СвязиИПараметрыВыбора = СвязиИПараметрыВыбора;
Форма.Открыть();
Возврат Форма;
КонецФункции
Процедура ОткрытьФайлВПроводникеЛкс(Знач ИмяФайла) Экспорт
ЗапуститьПриложение("explorer /select, """ + ИмяФайла + """");
КонецПроцедуры
// Результат - Булево - Истина если значение было изменено
Функция ЯчейкаТабличногоПоляРасширенногоЗначения_ВыборЛкс(ЭтаФорма, ТабличноеПоле, СтандартнаяОбработка = Ложь, РасширенноеЗначение = Null,
РедактированиеРазрешено = Истина, ПринудительноВОтдельнойФорме = Ложь, Данные = "") Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
Колонка = ТабличноеПоле.ТекущаяКолонка;
ЭлементУправления = Колонка.ЭлементУправления;
Иначе
Колонка = ТабличноеПоле.ТекущийЭлемент;
ЭлементУправления = Колонка;
КонецЕсли;
Если Не ЗначениеЗаполнено(Данные) Тогда
Данные = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
КонецЕсли;
Если РасширенноеЗначение = Null Тогда
Если Не ЗначениеЗаполнено(Данные) Тогда
Возврат Ложь;
КонецЕсли;
РасширенноеЗначение = ТабличноеПоле.ТекущиеДанные[Данные];
КонецЕсли;
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") И ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда
ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(ТабличноеПоле.ТекущаяСтрока);
Ячейка = ОформлениеСтроки.Ячейки[Колонка.Имя];
РедактированиеРазрешено = РедактированиеРазрешено И Не Ячейка.ТолькоПросмотр;
КонецЕсли;
РедактированиеРазрешено = Истина
И РедактированиеРазрешено
И Не ТабличноеПоле.ТолькоПросмотр
И Не Колонка.ТолькоПросмотр
И (Ложь
Или ЭлементУправления = Неопределено
Или ТипЗнч(ЭлементУправления) = Тип("Флажок")
Или Не ЭлементУправления.ТолькоПросмотр);
Если РедактированиеРазрешено Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзЗначения(РасширенноеЗначение);
Попытка
СвойствоГлобальногоКонтекста = Вычислить(СтруктураТипа.ИмяОбщегоТипа);
Исключение
СвойствоГлобальногоКонтекста = Неопределено;
КонецПопытки;
Если СвойствоГлобальногоКонтекста <> Неопределено Тогда
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
СписокВыбора = Новый СписокЗначений;
#Если Сервер И Не Сервер Тогда
СписокВыбора = Новый СписокЗначений;
#КонецЕсли
НачальныйВыбор = Неопределено;
СтрокиЗначений = мПлатформа.ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста", "Перечисление" + СтруктураТипа.ИмяОбщегоТипа));
Для Каждого СтрокаЗначения Из СтрокиЗначений Цикл
ЗначениеПеречисления = Вычислить(СтруктураТипа.ИмяОбщегоТипа + "." + СтрокаЗначения.Слово);
ЭлементСписка = СписокВыбора.Добавить(ЗначениеПеречисления);
Если РасширенноеЗначение = ЗначениеПеречисления Тогда
НачальныйВыбор = ЭлементСписка;
КонецЕсли;
КонецЦикла;
РезультатВыбора = ЭтаФорма.ВыбратьИзСписка(СписокВыбора, ЭлементУправления, НачальныйВыбор);
Результат = РезультатВыбора <> Неопределено;
Если Результат Тогда
РасширенноеЗначение = РезультатВыбора.Значение;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Результат = Неопределено Тогда
Результат = ОткрытьЗначениеЛкс(РасширенноеЗначение, РедактированиеРазрешено, СтандартнаяОбработка,,, ПринудительноВОтдельнойФорме,, ТабличноеПоле);
КонецЕсли;
Если Результат Тогда
НовоеЗначение = РасширенноеЗначение; // Сохраняем значение, т.к. оно может испортиться следующей строкой
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначение); // Почему то запрещенные для поля ввода значения здесь превращаются в строку (например МоментВремени, УникальныйИдентификатор)
РасширенноеЗначение = НовоеЗначение;
КонецЕсли;
Возврат Результат;
КонецФункции
// Результат - Булево - Истина если значение было изменено
Функция ПолеВводаРасширенногоЗначения_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка, РасширенноеЗначение = Null) Экспорт
Если РасширенноеЗначение = Null Тогда
РасширенноеЗначение = Элемент.Значение;
КонецЕсли;
ЗначениеИзменено = Ложь;
Если РасширенноеЗначение = Неопределено Тогда
СтандартнаяОбработка = Ложь;
ОграничениеТипа = Элемент.ОграничениеТипа;
НовыйТипИлиЗначение = ирОбщий.ВыбратьРедактируемыйТипЛкс(ОграничениеТипа);
Если НовыйТипИлиЗначение <> Неопределено Тогда
Если ТипЗнч(НовыйТипИлиЗначение) = Тип("Тип") Тогда
МассивТипов = ирОбщий.БыстрыйМассивЛкс(НовыйТипИлиЗначение);
НовоеОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
НовоеЗначение = НовоеОписаниеТипов.ПривестиЗначение(Неопределено);
Иначе
НовоеЗначение = НовыйТипИлиЗначение;
КонецЕсли;
РасширенноеЗначение = НовоеЗначение;
Элемент.Значение = РасширенноеЗначение; //
ЗначениеИзменено = Истина;
КонецЕсли;
Иначе
Если Истина
И ТипЗнч(Элемент.Значение) = Тип("СписокЗначений")
И ТипЗнч(РасширенноеЗначение) = Тип("СписокЗначений")
Тогда
РасширенноеЗначение.ТипЗначения = Элемент.ТипЗначенияСписка;
КонецЕсли;
Если Не ЛиСсылкаНаОбъектБДЛкс(РасширенноеЗначение, Ложь) Тогда
ЗначениеИзменено = ирОбщий.ОткрытьЗначениеЛкс(РасширенноеЗначение, Истина, СтандартнаяОбработка);
Если ЗначениеИзменено Тогда
Элемент.Значение = РасширенноеЗначение;
КонецЕсли;
КонецЕсли;
Если Не СтандартнаяОбработка Тогда
Элемент.Значение = РасширенноеЗначение;
КонецЕсли;
Если СтандартнаяОбработка Тогда
Если ЛиСсылкаНаОбъектБДЛкс(РасширенноеЗначение, Ложь) Тогда
ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РасширенноеЗначение)),,, Элемент, Истина,, РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ЗначениеИзменено;
КонецФункции
// Результат - Булево - Истина если значение было изменено
Функция ПолеВводаКолонкиРасширенногоЗначения_НачалоВыбораЛкс(ЭтаФорма, ТабличноеПоле, СтандартнаяОбработка, РасширенноеЗначение = Null, ИспользоватьОграничениеТипа = Ложь,
СтруктураОтбора = Неопределено, Данные = "") Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
Колонка = ТабличноеПоле.ТекущаяКолонка;
ЭлементУправления = Колонка.ЭлементУправления;
Иначе
Колонка = ТабличноеПоле.ТекущийЭлемент;
ЭлементУправления = Колонка;
КонецЕсли;
Если Не ЗначениеЗаполнено(Данные) Тогда
Данные = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
РазрешитьВыборТипа = Истина;
Иначе
РазрешитьВыборТипа = Ложь;
КонецЕсли;
Если РасширенноеЗначение = Null Тогда
РасширенноеЗначение = ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле)[Данные];
КонецЕсли;
ЗначениеИзменено = Ложь;
Если РасширенноеЗначение = Неопределено Или РасширенноеЗначение = Null Тогда
Если Не РазрешитьВыборТипа Тогда
Возврат ЗначениеИзменено;
КонецЕсли;
СтандартнаяОбработка = Ложь;
ОграничениеТипа = Неопределено;
Если ИспользоватьОграничениеТипа Тогда
ОграничениеТипа = ЭлементУправления.ОграничениеТипа;
Если Истина
И ОграничениеТипа.Типы().Количество() = 0
И ТипЗнч(ЭлементУправления) = Тип("ПолеФормы")
И ЗначениеЗаполнено(ЭлементУправления.СвязьПоТипу.ПутьКДанным)
Тогда
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ЭлементУправления);
Попытка
ОграничениеТипа = Вычислить("ЭтаФорма." + ЭлементУправления.СвязьПоТипу.ПутьКДанным);
Исключение
ВызватьИсключение "Ошибка вычисления влияющего типа поля: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Если ОграничениеТипа.Типы().Количество() = 0 Тогда
ОграничениеТипа = ПолучитьТипЗначенияЭлементаФормыЛкс(ЭлементУправления);
КонецЕсли;
КонецЕсли;
НовыйТипИлиЗначение = ВыбратьРедактируемыйТипЛкс(ОграничениеТипа);
Если НовыйТипИлиЗначение <> Неопределено Тогда
Если ТипЗнч(НовыйТипИлиЗначение) = Тип("Тип") Тогда
МассивТипов = БыстрыйМассивЛкс(НовыйТипИлиЗначение);
НовоеОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
НовоеЗначение = НовоеОписаниеТипов.ПривестиЗначение(Неопределено);
Иначе
НовоеЗначение = НовыйТипИлиЗначение;
КонецЕсли;
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначение); // Почему то запрещенные для поля ввода значения здесь превращаются в строку (например МоментВремени)
РасширенноеЗначение = НовоеЗначение;
ЗначениеИзменено = Истина;
//// http://www.hostedredmine.com/issues/884276
//Если ЛиСсылкаНаОбъектБДЛкс(РасширенноеЗначение, Ложь) Тогда
// ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РасширенноеЗначение)), СтруктураОтбора,, ЭлементУправления, Истина,, РасширенноеЗначение);
//КонецЕсли;
КонецЕсли;
КонецЕсли;
Если РасширенноеЗначение <> Неопределено Тогда
Если Не ЛиСсылкаНаОбъектБДЛкс(РасширенноеЗначение, Ложь) Тогда
ЗначениеИзменено = ЯчейкаТабличногоПоляРасширенногоЗначения_ВыборЛкс(ЭтаФорма, ТабличноеПоле, СтандартнаяОбработка, РасширенноеЗначение, Истина, Истина, Данные) Или ЗначениеИзменено;
КонецЕсли;
//Если ЗначениеИзменено Тогда
Если Не СтандартнаяОбработка И ЗначениеЗаполнено(Данные) Тогда
ТабличноеПоле.ТекущиеДанные[Данные] = РасширенноеЗначение;//
КонецЕсли;
Если СтандартнаяОбработка Тогда
Если ЛиСсылкаНаОбъектБДЛкс(РасширенноеЗначение, Ложь) Тогда
ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РасширенноеЗначение)), СтруктураОтбора,, ЭлементУправления, Истина,, РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ЗначениеИзменено;
КонецФункции
// Параметры:
// ЭтаФорма - Форма -
// ТабличноеПоле - ТабличноеПоле -
// ИмяКолонкиИмениРеквизита - Примитивный -
// ПолноеИмяТаблицы - Строка -
// СвязиИПараметрыВыбора - Булево -
// СтандартнаяОбработка - Булево -
Функция ПолеВводаКолонкиЗначенияРеквизита_НачалоВыбораЛкс(ЭтаФорма, ТабличноеПоле, ПолноеИмяТаблицы, ИмяКолонкиИмениРеквизита = "Имя", ИмяКолонкиЗначения = "Значение",
СвязиИПараметрыВыбора = Истина, СтандартнаяОбработка = Истина, Ссылка = Неопределено) Экспорт
Если СвязиИПараметрыВыбора Тогда
ПоляТаблицыБД = ирКэш.ПоляТаблицыБДЛкс(ПолноеИмяТаблицы);
ТекущиеДанные = ТабличноеПоле.ТекущаяСтрока;
СтрокаПоля = ПоляТаблицыБД.Найти(ТекущиеДанные[ИмяКолонкиИмениРеквизита], "Имя");
Если СтрокаПоля <> Неопределено Тогда
МетаРеквизит = СтрокаПоля.Метаданные;
СтруктураРеквизитов = Новый Структура;
Для Каждого СтрокаРеквизита Из ТабличноеПоле.Значение Цикл
ИмяРеквизита = СтрокаРеквизита[ИмяКолонкиИмениРеквизита];
ЗначениеРеквизита = СтрокаРеквизита[ИмяКолонкиЗначения];
Если ИмяРеквизита = "ИдентификаторСсылкиЛкс" Тогда
ИмяРеквизита = "Ссылка";
ЗначениеРеквизита = Ссылка;
КонецЕсли;
СтруктураРеквизитов.Вставить(ИмяРеквизита, ЗначениеРеквизита);
КонецЦикла;
Если ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицыБДЛкс(ПолноеИмяТаблицы)) Тогда
ОсновныеДанные = Неопределено;
СтруктураТЧ = Новый Структура(ирОбщий.ПоследнийФрагментЛкс(ПолноеИмяТаблицы), СтруктураРеквизитов);
Иначе
ОсновныеДанные = СтруктураРеквизитов;
СтруктураТЧ = Неопределено;
КонецЕсли;
СтруктураОтбора = ирОбщий.ПолучитьСтруктуруОтбораПоСвязямИПараметрамВыбораЛкс(ОсновныеДанные, МетаРеквизит, СтруктураТЧ);
ИначеЕсли ЗначениеЗаполнено(ТекущиеДанные.ДопРеквизит) Тогда
ДопРеквизит = ТекущиеДанные.ДопРеквизит;
#Если Сервер И Не Сервер Тогда
ДопРеквизит = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ПустаяСсылка();
#КонецЕсли
СтруктураОтбора = Новый Структура("Владелец", ДопРеквизит);
ПриведенноеЗначение = ДопРеквизит.ТипЗначения.ПривестиЗначение(ТекущиеДанные[ИмяКолонкиЗначения]);
Если ПриведенноеЗначение <> ТекущиеДанные[ИмяКолонкиЗначения] Тогда
СтандартнаяОбработка = Ложь;
ирОбщий.ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, ТабличноеПоле.Колонки[ИмяКолонкиЗначения], ПриведенноеЗначение);
Возврат Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
УспехВыбора = ПолеВводаКолонкиРасширенногоЗначения_НачалоВыбораЛкс(ЭтаФорма, ТабличноеПоле, СтандартнаяОбработка, , Истина, СтруктураОтбора);
Возврат УспехВыбора;
КонецФункции
// Нужно вызывать после установки признака ТолькоПросмотр ячеек.
// ИменаКолонокСПиктограммамиТипов - Массив, Строка
Процедура ТабличноеПолеПриВыводеСтрокиЛкс(Знач ЭтаФорма, Знач Элемент, Знач ОформлениеСтроки, Знач ДанныеСтроки, Знач КнопкаРежимаОтображения = Неопределено, Знач ИменаКолонокСПиктограммамиТипов = "",
РасширенныеКолонки = Неопределено, РасширенноеПредставлениеХранилищЗначений = Ложь, Знач РасширенныеДанныеСтроки = Неопределено, Знач КолонкиДляРежимаОтображения = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Элемент = Новый ТабличноеПоле;
#КонецЕсли
Если ДанныеСтроки = Неопределено Тогда
Возврат;
КонецЕсли;
КолонкиТаблицы = Элемент.Колонки;
Если КнопкаРежимаОтображения <> Неопределено Тогда
ВариантОтображенияИдентификаторов = КнопкаРежимаОтображения.Текст;
КонецЕсли;
Ячейки = ОформлениеСтроки.Ячейки;
Если РасширенныеДанныеСтроки = Неопределено Тогда
РасширенныеДанныеСтроки = ДанныеСтроки;
КонецЕсли;
Если КолонкиДляРежимаОтображения <> Неопределено Тогда
КолонкиДляРежимаОтображения = Новый Структура(КолонкиДляРежимаОтображения);
КонецЕсли;
СостоянияКнопки = ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс();
ЛиОтбражатьПустые = Ложь
Или ВариантОтображенияИдентификаторов = СостоянияКнопки[1]
Или ВариантОтображенияИдентификаторов = СостоянияКнопки[2];
ОтображатьИдентификаторы = Ложь
Или ВариантОтображенияИдентификаторов = СостоянияКнопки[2];
ирПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
ирПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если ТипЗнч(ИменаКолонокСПиктограммамиТипов) = Тип("Строка") Тогда
ИменаКолонокСПиктограммамиТипов = СтрРазделитьЛкс(ИменаКолонокСПиктограммамиТипов, ",", Истина);
КонецЕсли;
Для Каждого Колонка Из КолонкиТаблицы Цикл
Если Не Колонка.Видимость Тогда
Продолжить;
КонецЕсли;
Ячейка = Ячейки[Колонка.Имя];
КартинкаЯчейки = Неопределено;
КолонкаРасширенныхДанных = Неопределено;
Если РасширенныеКолонки <> Неопределено Тогда
РасширенныеКолонки.Свойство(Колонка.Имя, КолонкаРасширенныхДанных);
КонецЕсли;
ПрименятьРежимОтображения = Ложь
Или КолонкиДляРежимаОтображения = Неопределено
Или КолонкиДляРежимаОтображения.Свойство(Колонка.Имя);
КолонкаОтображаетДанныеФлажка = Ложь;
Если КолонкаРасширенныхДанных <> Неопределено Тогда
ЗначениеЯчейки = РасширенныеДанныеСтроки[КолонкаРасширенныхДанных];
Иначе
Если Истина
И Не ЗначениеЗаполнено(Колонка.Данные)
И ЗначениеЗаполнено(Колонка.ДанныеФлажка)
Тогда
ЗначениеЯчейки = Ячейка.ЗначениеФлажка;
КолонкаОтображаетДанныеФлажка = Истина;
Иначе
ЗначениеЯчейки = Ячейка.Значение;
КонецЕсли;
КонецЕсли;
Если Истина
И Не КолонкаОтображаетДанныеФлажка
И ТипЗнч(ЗначениеЯчейки) = Тип("Булево")
И ТипЗнч(Колонка.ЭлементУправления) <> Тип("ПолеВыбора") // Колонка "Вид" таблицы "Параметры" в консоли запросов
Тогда
Если Истина
И Не ЛиОтбражатьПустые
И Не ОтображатьИдентификаторы
И ИменаКолонокСПиктограммамиТипов.Найти(Колонка.Имя) = Неопределено
Тогда
Ячейка.УстановитьТекст("");
Иначе
Ячейка.УстановитьТекст("" + ЗначениеЯчейки);
КонецЕсли;
Если Не Ячейка.ТолькоПросмотр И Колонка.ЭлементУправления <> Неопределено Тогда
Ячейка.УстановитьФлажок(ЗначениеЯчейки);
ИначеЕсли ЗначениеЯчейки = Истина И Ячейка.Текст = "" Тогда
КартинкаЯчейки = ирКэш.КартинкаПоИмениЛкс("ирФлажокТолькоПросмотр");
КонецЕсли;
КонецЕсли;
ПредставлениеЗначения = "";
Если Истина
И Не КолонкаОтображаетДанныеФлажка
И ТипЗнч(ЗначениеЯчейки) <> Тип("Строка")
И ЗначениеЯчейки <> Неопределено
И (Ложь
Или РасширенноеПредставлениеХранилищЗначений
Или ТипЗнч(ЗначениеЯчейки) = Тип("ОписаниеТипов")
Или XMLТипЗнч(ЗначениеЯчейки) = Неопределено)
Тогда
ПредставлениеЗначения = РасширенноеПредставлениеЗначенияЛкс(ЗначениеЯчейки, Колонка,, РасширенноеПредставлениеХранилищЗначений, Ложь);
КонецЕсли;
Если ЛиОтбражатьПустые И ПрименятьРежимОтображения Тогда
Если ТипЗнч(ЗначениеЯчейки) = Тип("Строка") Тогда
Если Не ЗначениеЗаполнено(ЗначениеЯчейки) Тогда
ПредставлениеЗначения = ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ЗначениеЯчейки);
Ячейка.ЦветФона = ЦветФонаЯчеекПустыхЗначенийЛкс();
ИначеЕсли ОтображатьИдентификаторы Тогда
ПредставлениеЗначения = """" + ЗначениеЯчейки + """";
КонецЕсли;
ИначеЕсли Не ЭтоКоллекцияЛкс(ЗначениеЯчейки) Тогда
Попытка
ЗначениеНепустое = ЗначениеЗаполнено(ЗначениеЯчейки) И ЗначениеЯчейки <> Ложь;
Исключение
ЗначениеНепустое = Истина;
КонецПопытки;
Если Не ЗначениеНепустое Тогда
ПредставлениеЗначения = ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ЗначениеЯчейки);
Ячейка.ЦветФона = ЦветФонаЯчеекПустыхЗначенийЛкс();
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ПредставлениеЗначения <> "" Тогда
Если Ложь
Или КолонкаОтображаетДанныеФлажка
Или Формат(ЗначениеЯчейки, Колонка.Формат) = Ячейка.Текст // Здесь могут быть обращения к БД
Тогда
Ячейка.УстановитьТекст(ПредставлениеЗначения);
КонецЕсли;
КонецЕсли;
Если ОтображатьИдентификаторы И ПрименятьРежимОтображения Тогда
ИдентификаторСсылки = СтроковыйИдентификаторСсылкиЛкс(ЗначениеЯчейки, Истина);
Если ИдентификаторСсылки <> Неопределено Тогда
Ячейка.УстановитьТекст(ИдентификаторСсылки);
КонецЕсли;
КонецЕсли;
Если КартинкаЯчейки = Неопределено И ИменаКолонокСПиктограммамиТипов.Найти(Колонка.Имя) <> Неопределено Тогда
Если ТипЗнч(ЗначениеЯчейки) <> Тип("ПолеКомпоновкиДанных") Тогда
ТипЗначения = ТипЗнч(ЗначениеЯчейки);
Если Не (Истина
И ТипЗначения = Тип("Булево")
И Ячейка.ОтображатьФлажок)
Тогда
КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения);
Если КартинкаТипа <> Неопределено Тогда
КартинкаЯчейки = КартинкаТипа;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если КартинкаЯчейки <> Неопределено Тогда
Ячейка.УстановитьКартинку(КартинкаЯчейки);
КонецЕсли;
КонецЦикла;
ИмяКолонкиНомерСтроки = ирКэш.ИмяКолонкиНомерСтрокиЛкс();
Если Ячейки.Найти(ИмяКолонкиНомерСтроки) <> Неопределено Тогда
Если ТипЗнч(ДанныеСтроки) = Тип("СтрокаДереваЗначений") Тогда
ИндексСтроки = ПолучитьРодителяСтрокиДереваЛкс(ДанныеСтроки, ДанныеСтроки.Владелец()).Строки.Индекс(ДанныеСтроки);
Иначе
ИндексСтроки = ДанныеСтроки.Владелец().Индекс(ДанныеСтроки);
КонецЕсли;
Ячейки[ИмяКолонкиНомерСтроки].УстановитьТекст(XMLСтрока(ИндексСтроки + 1));
Ячейки[ИмяКолонкиНомерСтроки].ЦветТекста = Новый Цвет(128, 128, 128);
КонецЕсли;
Если ТипЗнч(ДанныеСтроки) = Тип("ТекущиеДанныеСписка") Тогда
ЭтоВыводТекущейСтроки = Ложь;
Если Элемент.ТекущиеДанные <> Неопределено Тогда
ЭтоВыводТекущейСтроки = Истина;
ИмяТаблицыБД = ИмяТаблицыБДДинамическогоСпискаЛкс(Элемент);
КлючСтроки = СтруктураКлючаТаблицыБДЛкс(ИмяТаблицыБД);
#Если Сервер И Не Сервер Тогда
КлючСтроки = Новый Структура;
#КонецЕсли
Для Каждого КлючИЗначение Из КлючСтроки Цикл
Если ДанныеСтроки[КлючИЗначение.Ключ] <> Элемент.ТекущиеДанные[КлючИЗначение.Ключ] Тогда
ЭтоВыводТекущейСтроки = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ИначеЕсли ТипЗнч(ДанныеСтроки) = Тип("ТекущиеДанныеСтруктурыНастроекКомпоновкиДанных") Тогда
ЭтоВыводТекущейСтроки = Элемент.ТекущаяСтрока = ДанныеСтроки.Строка;
Иначе
ЭтоВыводТекущейСтроки = Элемент.ТекущаяСтрока = ДанныеСтроки;
КонецЕсли;
ЭтоВыводВыделеннойСтроки = Элемент.ВыделенныеСтроки.Содержит(ДанныеСтроки);
Если ЭтоВыводТекущейСтроки Или ЭтоВыводВыделеннойСтроки Тогда
СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
#Если Сервер И Не Сервер Тогда
СлужебныеДанныеФормы = Новый Структура;
#КонецЕсли
Если СлужебныеДанныеФормы.Свойство("ВременноОформленныеСтроки") Тогда
ВременноОформленныеСтроки = СлужебныеДанныеФормыЛкс(ЭтаФорма).ВременноОформленныеСтроки;
#Если Сервер И Не Сервер Тогда
ВременноОформленныеСтроки = Новый Структура;
#КонецЕсли
Если ВременноОформленныеСтроки.Свойство(Элемент.Имя) Тогда
Если ЭтоВыводТекущейСтроки Тогда
СмещениеЦвета = -20;
Иначе
СмещениеЦвета = -15;
КонецЕсли;
ТекущийЦветФона = ОформлениеСтроки.ЦветФона;
Если ТекущийЦветФона.Вид = ВидЦвета.АвтоЦвет Тогда
ТекущийЦветФона = Элемент.ЦветФонаПоля;
КонецЕсли;
ОформлениеСтроки.ЦветФона = СмещенныйЦветЛкс(ТекущийЦветФона, СмещениеЦвета,, СмещениеЦвета);
Для Каждого Ячейка Из ОформлениеСтроки.Ячейки Цикл
ТекущийЦветФона = Ячейка.ЦветФона;
Если ТекущийЦветФона.Вид = ВидЦвета.АвтоЦвет Тогда
Продолжить;
КонецЕсли;
Ячейка.ЦветФона = СмещенныйЦветЛкс(ТекущийЦветФона, СмещениеЦвета,, СмещениеЦвета);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Основным элементом страницы считается одноименный с ней элемент формы.
//
Функция Форма_ОбновлениеОтображенияЛкс(ЭтаФорма) Экспорт
Если ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма") Тогда
ЭлементыФормы = ЭтаФорма.Элементы;
Иначе
ЭлементыФормы = ЭтаФорма.ЭлементыФормы;
//Если ЭтаФорма.ВводДоступен() Тогда
// СлужебныеДанныеФормы = ирОбщий.СлужебныеДанныеФормыЛкс(ЭтаФорма);
// Если СлужебныеДанныеФормы.Свойство("ОбновитьПриАктивации") Тогда
// СлужебныеДанныеФормы.Удалить("ОбновитьПриАктивации");
// //ЭтаФорма.Обновить();
// КонецЕсли;
//КонецЕсли;
КонецЕсли;
Для Каждого ЭлементФормы Из ЭлементыФормы Цикл
Если Истина
#Если Клиент Тогда
И ТипЗнч(ЭлементФормы) <> Тип("Панель")
#КонецЕсли
И Не (Истина
И ТипЗнч(ЭлементФормы) = Тип("ГруппаФормы")
И ЭлементФормы.Вид = ВидГруппыФормы.Страницы)
Тогда
Продолжить;
КонецЕсли;
ОбновитьЗаголовкиСтраницПанелиЛкс(ЭтаФорма, ЭлементыФормы, ЭлементФормы);
КонецЦикла;
Возврат Истина;
КонецФункции
// Не используется
Процедура ТабличноеПолеПриПолученииДанныхЛкс(ЭтаФорма, Знач Элемент, Знач ОформленияСтрок) Экспорт
СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
Если СлужебныеДанныеФормы.Свойство("ОбработчикиПриВыводеСтроки") Тогда
ОбработчикиПриВыводеСтроки = СлужебныеДанныеФормы.ОбработчикиПриВыводеСтроки;
ОбработчикПриВыводеСтроки = ОбработчикиПриВыводеСтроки[Элемент.Имя];
КонецЕсли;
Если Истина
И ОбработчикПриВыводеСтроки <> Неопределено
И Не МетодРеализованЛкс(ЭтаФорма, ОбработчикПриВыводеСтроки) // Сообщение о его отсутствии выдаем в общем обработчике Форма_ПриОткрытии
Тогда
ОбработчикПриВыводеСтроки = Неопределено;
КонецЕсли;
Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
Если ДанныеСтроки = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ОбработчикПриВыводеСтроки = Неопределено Тогда
ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки);
Иначе
Выполнить("ЭтаФорма." + ОбработчикПриВыводеСтроки + "(Элемент, ОформлениеСтроки, ДанныеСтроки);");
КонецЕсли;
КонецЦикла;
//Сообщить("" + ТекущаяДата() + " обновлено табличное поле """ + Элемент.Имя + """");
КонецПроцедуры
Функция СмещенныйЦветЛкс(Знач ТекущийЦветФона, СмещениеКрасный = -20, СмещениеЗеленый = 0, СмещениеСиний = -20) Экспорт
Если ТекущийЦветФона.Вид = ВидЦвета.АвтоЦвет Тогда
ТекущийЦветФона = ЦветаСтиля.ЦветФонаПоля;
КонецЕсли;
АбсолютныйЦвет = ирКэш.АбсолютныйЦветЛкс(ЗначениеВСтрокуВнутр(ТекущийЦветФона));
#Если Сервер И Не Сервер Тогда
АбсолютныйЦвет = Новый Цвет;
#КонецЕсли
СмещенныйЦвет = Новый Цвет(Макс(0, АбсолютныйЦвет.Красный + СмещениеКрасный), Макс(0, АбсолютныйЦвет.Зеленый + СмещениеЗеленый), Макс(АбсолютныйЦвет.Синий + СмещениеСиний));
Возврат СмещенныйЦвет;
КонецФункции
Процедура ТабличноеПолеПриАктивизацииСтрокиЛкс(ЭтаФорма, Элемент) Экспорт
Если Элемент = Неопределено Тогда
Возврат;
КонецЕсли;
СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
#Если Сервер И Не Сервер Тогда
СлужебныеДанныеФормы = Новый Структура;
Элемент = Новый ТабличноеПоле;
#КонецЕсли
Если Не СлужебныеДанныеФормы.Свойство("ВременноОформленныеСтроки") Тогда
СлужебныеДанныеФормы.Вставить("ВременноОформленныеСтроки", Новый Структура);
КонецЕсли;
ВременноОформленныеСтроки = СлужебныеДанныеФормы.ВременноОформленныеСтроки;
#Если Сервер И Не Сервер Тогда
ВременноОформленныеСтроки = Новый Структура;
#КонецЕсли
Если ВременноОформленныеСтроки.Свойство(Элемент.Имя) Тогда
МассивСтрок = ВременноОформленныеСтроки[Элемент.Имя];
Если МассивСтрок <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
МассивСтрок = Новый Массив;
#КонецЕсли
Если МассивСтрок.Количество() > 1 Тогда
Элемент.ОбновитьСтроки();
Иначе
Элемент.ОбновитьСтроки(МассивСтрок);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Элемент.ТекущаяСтрока <> Неопределено Тогда
Элемент.РежимВыделенияСтроки = РежимВыделенияСтрокиТабличногоПоля.Ячейка;
ВременноОформленныеСтроки.Вставить(Элемент.Имя, Неопределено);
Элемент.ОбновитьСтроки(Элемент.ТекущаяСтрока);
КонецЕсли;
МассивСтрок = Новый Массив;
МассивСтрок.Добавить(Элемент.ТекущаяСтрока);
Если Элемент.ВыделенныеСтроки.Количество() > 1 Тогда
МассивСтрок.Добавить(Элемент.ТекущаяСтрока);
КонецЕсли;
ВременноОформленныеСтроки.Вставить(Элемент.Имя, МассивСтрок);
ИндексКолонки = 0;
Пока Элемент.ТекущаяКолонка = Неопределено И Элемент.Колонки.Количество() > ИндексКолонки Цикл
// Антибаг платформы 8.3.17 https://partners.v8.1c.ru/forum/t/1919341/m/1919341 http://www.hostedredmine.com/issues/877079
КолонкаТП = Элемент.Колонки[ИндексКолонки];
Если КолонкаТП.Доступность И КолонкаТП.Видимость Тогда
Элемент.ТекущаяКолонка = КолонкаТП;
КонецЕсли;
ИндексКолонки = ИндексКолонки + 1;
КонецЦикла;
ТабличноеПолеВключитьСтаруюЦветовуюСхемуЛкс(Элемент);
ТабличноеПолеОбновитьТекстыПодваловЛкс(Элемент);
КонецПроцедуры
Процедура ТабличноеПолеВключитьСтаруюЦветовуюСхемуЛкс(Знач Элемент)
// Переключаем цветовую схему на старый вариант (без градиентов и с подсветкой текущей колонки) https://partners.v8.1c.ru/forum/t/898034/m/898082
Если Элемент.Колонки.Количество() > 0 И Элемент.Колонки[0].ЦветФонаШапки <> ЦветаСтиля.ЦветФонаКнопки Тогда
Элемент.Колонки[0].ЦветФонаШапки = ЦветаСтиля.ЦветФонаКнопки;
КонецЕсли;
КонецПроцедуры
Процедура ИнтерактивноЗаписатьВКолонкуФлажкаЛкс(Знач Элемент, Знач Колонка, Знач НовоеЗначение = Неопределено, ВосстанавитьТекущуюКолонку = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
Элемент = Новый ТабличноеПоле;
Колонка = Элемент.Колонки.Добавить();
#КонецЕсли
Если НовоеЗначение = Неопределено Тогда
НовоеЗначение = Не Элемент.ТекущаяСтрока[Колонка.Данные];
КонецЕсли;
ирОбщий.ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(Элемент, Колонка, НовоеЗначение,, ВосстанавитьТекущуюКолонку,,, Истина);
КонецПроцедуры
Процедура ТабличноеПоле_ИнтерактивноУстановитьПометкуТекущейСтрокиЛкс(ТабличноеПоле, КолонкаПометки, НоваяПометка = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
Если ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
Если КолонкаПометки = Неопределено Тогда
КолонкаПометки = КолонкаПометкиТабличногоПоляЛкс(ТабличноеПоле);
КонецЕсли;
Если КолонкаПометки = Неопределено Тогда
Возврат;
КонецЕсли;
ИнтерактивноЗаписатьВКолонкуФлажкаЛкс(ТабличноеПоле, КолонкаПометки, НоваяПометка);
Возврат;
КонецПроцедуры
Функция КолонкаПометкиТабличногоПоляЛкс(Знач ТабличноеПоле)
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
КолонкаТекущая = ТабличноеПоле.ТекущаяКолонка;
Если Истина
//И ТабличноеПоле.ТекущаяКолонка <> Неопределено
//И ТабличноеПоле.Значение.Количество() > 0
//И ТипЗнч(ТабличноеПоле.Значение[0][ТабличноеПоле.ТекущаяКолонка.Данные]) = Тип("Булево")
И КолонкаТекущая.ЭлементУправления <> Неопределено
И ТипЗнч(КолонкаТекущая.ЭлементУправления.Значение) = Тип("Булево")
Тогда
Колонка = ТабличноеПоле.ТекущаяКолонка;
КонецЕсли;
Если Колонка = Неопределено Тогда
Колонка = ТабличноеПоле.Колонки.Найти("Пометка");
КонецЕсли;
Если Колонка = Неопределено Тогда
Колонка = ТабличноеПоле.Колонки.Найти("Использование");
КонецЕсли;
Если Колонка = Неопределено Тогда
КолонкаПервая = ТабличноеПоле.Колонки[0];
Если КолонкаПервая.Имя = "НомерСтроки" И ТабличноеПоле.Колонки.Количество() > 1 Тогда
КолонкаПервая = ТабличноеПоле.Колонки[1];
КонецЕсли;
Если Истина
И КолонкаПервая.ЭлементУправления <> Неопределено
И ТипЗнч(КолонкаПервая.ЭлементУправления.Значение) = Тип("Булево")
Тогда
Колонка = КолонкаПервая;
КонецЕсли;
КонецЕсли;
Возврат Колонка;
КонецФункции
Процедура УстановитьФокусВводаФормеЛкс(ФормаВладелец) Экспорт
// Для обхода ошибок платформы. Форма при закрытии может вернуть фокус ввода главному окну вместо отображаемому на переднем плане дочернему окну.
ФормаВладелец.Открыть();
мПлатформа = ирКэш.Получить();
ФормаПустышка = мПлатформа.ПолучитьФорму("Пустышка");
ФормаПустышка.Открыть();
ФормаПустышка.Закрыть();
КонецПроцедуры
Процедура ТабличноеПолеОтбораКомпоновкиПеретаскиваниеЛкс(ЭтаФорма, Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка) Экспорт
Если Истина
И ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Массив")
И ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Перемещение
Тогда
ТипЭлемента = ТипЗнч(ПараметрыПеретаскивания.Значение[0]);
Если Ложь
Или ТипЭлемента = Тип("ДоступноеПолеКомпоновкиДанных")
Или ТипЭлемента = Тип("ДоступноеПолеОтбораКомпоновкиДанных")
Тогда
Если Истина
И Строка <> Неопределено
И Колонка <> Неопределено
И Найти(Колонка.Данные, "ПравоеЗначение") = 1
Тогда
СтандартнаяОбработка = Ложь;
Строка.ПравоеЗначение = ПараметрыПеретаскивания.Значение[0].Поле;
//ИначеЕсли Найти(Колонка.Данные, "ЛевоеЗначение") = 1 Тогда // Удобнее штатным способом добавлять новый элемент сразу в нужную позицию
// СтандартнаяОбработка = Ложь;
// Строка.ЛевоеЗначение = ПараметрыПеретаскивания.Значение[0].Поле;
Иначе
//Если ТипЗнч(Строка) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
// Родитель = ПолучитьРодителяСтрокиДереваЛкс(Строка, Элемент.Значение);
//ИначеЕсли ТипЗнч(Строка) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
// Родитель = Строка;
//Иначе
// Родитель = Элемент.Значение;
//КонецЕсли;
//Для Каждого ДоступноеПоле Из ПараметрыПеретаскивания.Значение Цикл
// #Если Сервер И Не Сервер Тогда
// ДоступноеПоле = Новый НастройкиКомпоновкиДанных;
// ДоступноеПоле = ДоступноеПоле.Выбор.ДоступныеПоляВыбора.НайтиПоле();
// #КонецЕсли
// НовыйЭлемент = Родитель.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
// НовыйЭлемент.Использование = Истина;
// НовыйЭлемент.ЛевоеЗначение = ДоступноеПоле.Поле;
// Элемент.ТекущаяСтрока = НовыйЭлемент;
//КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПолныйИдентификаторСсылкиЛкс(Знач ЗначениеЯчейки) Экспорт
ИдентификаторСсылки = СтроковыйИдентификаторСсылкиЛкс(ЗначениеЯчейки);
Возврат ИдентификаторСсылки;
КонецФункции
Функция СтроковыйИдентификаторЗначенияЛкс(Значение) Экспорт
ИдентификаторЗначения = СтроковыйИдентификаторСсылкиЛкс(Значение);
Если ИдентификаторЗначения = Неопределено Тогда
ИдентификаторЗначения = Формат(Значение, "ЧН=; ДП=; БЛ=");
КонецЕсли;
Возврат ИдентификаторЗначения;
КонецФункции
Функция РазмерЗначенияЛкс(Значение) Экспорт
Результат = СтрДлина(ЗначениеВСтрокуВнутр(Новый ХранилищеЗначения(Значение)));
Возврат Результат;
КонецФункции
Процедура ТабличноеПолеВставитьКолонкуНомерСтрокиЛкс(Знач ТабличноеПоле) Экспорт
ИмяКолонкиНомерСтроки = ирКэш.ИмяКолонкиНомерСтрокиЛкс();
Если ТабличноеПоле.Колонки.Найти(ИмяКолонкиНомерСтроки) = Неопределено Тогда
КолонкаТП = ТабличноеПоле.Колонки.Вставить(0);
КолонкаТП.Имя = ИмяКолонкиНомерСтроки;
КолонкаТП.ТекстШапки = "№";
КолонкаТП.ПодсказкаВШапке = "Номер элемента в пределах родителя (служебная)";
КолонкаТП.ТолькоПросмотр = Истина;
КолонкаТП.Ширина = 4;
КонецЕсли;
КонецПроцедуры // ОбновитьТаблицуКолонок()
Процедура _РасширенныйВыборПравогоЗначенияОтбораКомпоновкиЛкс(ТабличноеПолеОтбора) Экспорт
ТекущаяСтрока = ТабличноеПолеОтбора.ТекущаяСтрока;
Если Ложь
Или ТекущаяСтрока = Неопределено
Или ТипЗнч(ТекущаяСтрока) = Тип("ОтборКомпоновкиДанных")
Или ТипЗнч(ТекущаяСтрока) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
Тогда
Возврат;
КонецЕсли;
ЗначениеОтбора = ТекущаяСтрока.ПравоеЗначение;
КолонкаТП = ТабличноеПолеОтбора.Колонки.ПравоеЗначениеДляКраткогоОтображенияЭлемента;
ТабличноеПолеОтбора.ТекущаяКолонка = КолонкаТП;
Если ТипЗнч(ЗначениеОтбора) <> Тип("СписокЗначений") Тогда
Если ЛиСсылкаНаОбъектБДЛкс(ЗначениеОтбора, Ложь) Тогда
ТабличноеПолеОтбора.ИзменитьСтроку();
ирОбщий.ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеОтбора)),,, КолонкаТП.ЭлементУправления, Истина,, ЗначениеОтбора);
КонецЕсли;
Иначе
Результат = ирОбщий.ОткрытьЗначениеЛкс(ЗначениеОтбора, Истина);
Если Результат Тогда
ТекущаяСтрока.ПравоеЗначение = ЗначениеОтбора;
ТекущаяСтрока.Использование = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПоказатьДоступноеПолеЭлементаНастроекКомпоновкиЛкс(ЭтаФорма, Знач ТабличноеПолеДоступныхПолей, Знач ТабличноеПолеНастроек) Экспорт
ТекущаяСтрока = ТабличноеПолеНастроек.ТекущаяСтрока;
Если ТипЗнч(ТекущаяСтрока) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
ИскомоеПоле = ТекущаяСтрока.ЛевоеЗначение;
Если ТабличноеПолеНастроек.ТекущаяКолонка = ТабличноеПолеНастроек.Колонки.ПравоеЗначениеДляКраткогоОтображенияЭлемента Тогда
ИскомоеПоле = ТекущаяСтрока.ПравоеЗначение;
КонецЕсли;
ИначеЕсли Ложь
Или ТипЗнч(ТекущаяСтрока) = Тип("ЭлементПорядкаКомпоновкиДанных")
Или ТипЗнч(ТекущаяСтрока) = Тип("ВыбранноеПолеКомпоновкиДанных")
Или ТипЗнч(ТекущаяСтрока) = Тип("ПолеГруппировкиКомпоновкиДанных")
Тогда
ИскомоеПоле = ТекущаяСтрока.Поле;
Иначе
Возврат Неопределено;
КонецЕсли;
ДоступноеПоле = ТабличноеПолеДоступныхПолей.Значение.НайтиПоле(Новый ПолеКомпоновкиДанных(ИскомоеПоле));
Если ДоступноеПоле <> Неопределено Тогда
ТабличноеПолеДоступныхПолей.ТекущаяСтрока = ДоступноеПоле;
ЭтаФорма.ТекущийЭлемент = ТабличноеПолеДоступныхПолей;
КонецЕсли;
Возврат ДоступноеПоле;
КонецФункции
Процедура КнопкаОтображатьПустыеИИдентификаторыНажатиеЛкс(Кнопка) Экспорт
МассивСостояний = ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс();
Если ТипЗнч(Кнопка) = Тип("КнопкаКоманднойПанели") Тогда
ТекстКнопки = Кнопка.Текст;
Иначе
ТекстКнопки = Кнопка.Заголовок;
КонецЕсли;
Если ТекстКнопки = МассивСостояний[2] Тогда
Кнопка.Пометка = Ложь;
НовыйТекстКнопки = МассивСостояний[0];
Кнопка.Картинка = ирКэш.КартинкаПоИмениЛкс("ирПусто");
ИначеЕсли ТекстКнопки = МассивСостояний[1] Тогда
Кнопка.Пометка = Истина;
НовыйТекстКнопки = МассивСостояний[2];
Кнопка.Картинка = ирКэш.КартинкаПоИмениЛкс("ирИдентификатор");
Иначе//Если ТекстКнопки = МассивСостояний[0] Тогда
Кнопка.Пометка = Истина;
НовыйТекстКнопки = МассивСостояний[1];
Кнопка.Картинка = ирКэш.КартинкаПоИмениЛкс("ирПусто");
КонецЕсли;
Если ТипЗнч(Кнопка) = Тип("КнопкаКоманднойПанели") Тогда
Кнопка.Текст = НовыйТекстКнопки;
Иначе
Кнопка.Заголовок = НовыйТекстКнопки;
КонецЕсли;
КонецПроцедуры
Процедура ПрименитьИзмененияИЗакрытьФормуЛкс(ЭтаФорма, ЗначениеВыбора = Неопределено) Экспорт
ЭтаФорма.Модифицированность = Ложь;
Если Ложь
Или ЭтаФорма.ВладелецФормы <> Неопределено
Или Не ЭтаФорма.Открыта()
Тогда
ЭтаФорма.ОповеститьОВыборе(ЗначениеВыбора);
КонецЕсли;
Если ЭтаФорма.Открыта() Тогда
ЭтаФорма.Закрыть(ЗначениеВыбора);
КонецЕсли;
//Если ЭтаФорма.Открыта() Тогда
// ЭтаФорма.Закрыть(ЗначениеВыбора);
//Иначе//Если ЭтаФорма.МодальныйРежим Тогда
// ЭтаФорма.ОповеститьОВыборе(ЗначениеВыбора);
//КонецЕсли;
КонецПроцедуры // ПрименитьИзмененияИЗакрытьФорму()
//
// Параметры:
// ЯзыкПрограммы - Число - 0 - встроенный язык, 1 - язык запросов, 2 - язык выражений СКД
Функция НайтиВозможныеСтрокиОписанияСловаВСинтаксПомощникеЛкс(Знач Слово, ЯзыкПрограммы = 0, ПоискСУчетомТипаСлова = Истина) Экспорт
мПлатформа = ирКэш.Получить();
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
МассивВозможныхТиповСлова = Новый Массив;
МассивВозможныхТиповСлова.Добавить("Конструктор");
Слово = НРег(Слово);
Если Ложь
Или Не ПоискСУчетомТипаСлова
Или Прав(Слово, 1) = "("
Тогда
Если Прав(Слово, 1) = "(" Тогда
Слово = СтрокаБезКонцаЛкс(Слово, 1);
КонецЕсли;
МассивВозможныхТиповСлова.Добавить("Метод");
КонецЕсли;
Если Ложь
Или Не ПоискСУчетомТипаСлова
Или Прав(Слово, 1) <> "("
Тогда
МассивВозможныхТиповСлова.Добавить("Свойство");
МассивВозможныхТиповСлова.Добавить("Конструкция");
МассивВозможныхТиповСлова.Добавить("Событие");
МассивВозможныхТиповСлова.Добавить("Таблица");
КонецЕсли;
ТаблицаСтруктурВозможныхТиповКонтекста = мПлатформа.НоваяТаблицаСтруктурТипа();
Для Каждого ВозможныйТипСлова Из МассивВозможныхТиповСлова Цикл
Если ВозможныйТипСлова = "Конструктор" Тогда
КлючПоиска = Новый Структура("ТипКонтекста, ТипСлова, ЯзыкПрограммы, ТипЯзыка", Слово, ВозможныйТипСлова, ЯзыкПрограммы, "");
Иначе
КлючПоиска = Новый Структура("НСлово, ТипСлова, ЯзыкПрограммы, ТипЯзыка", Слово, ВозможныйТипСлова, ЯзыкПрограммы, "");
КонецЕсли;
НайденныеСтроки = мПлатформа.ТаблицаКонтекстов.НайтиСтроки(КлючПоиска);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока));
КонецЦикла;
НайденныеСтроки = мПлатформа.ТаблицаШаблоновКонтекстов.НайтиСтроки(КлючПоиска);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока));
КонецЦикла;
КонецЦикла;
КлючПоиска = Новый Структура("НСлово, ЯзыкПрограммы", Слово, ЯзыкПрограммы);
НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока));
КонецЦикла;
Возврат ТаблицаСтруктурВозможныхТиповКонтекста;
КонецФункции // НайтиВозможныеСтрокиОписанияСлова()
// Открывает форму синтакс-помощника и загружает в нее нужную страницу, подсвечивая заданную строку.
//
// Параметры:
// ВнутреннийПутьКОписанию – Строка – внутренний путь к странице синтакс-помощника;
// СтрокаДляПодсветки – Строка – которую нужно подсветить в тексте страницы.
//
// Возвращаемое значение:
// Форма.
//
Функция ОткрытьСтраницуСинтаксПомощникаЛкс(ВнутреннийПутьКОписанию, СтрокаДляПодсветки = "", ВладелецФормы = Неопределено, КлючУникальности = Неопределено) Экспорт
Если ВнутреннийПутьКОписанию = "" Тогда
Возврат Неопределено;
КонецЕсли;
ФормаСправка = ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма", , , КлючУникальности);
ФормаСправка.ВладелецФормы = ВладелецФормы;
ФормаСправка.ОткрытьАдрес(ВнутреннийПутьКОписанию, СтрокаДляПодсветки);
ФормаСправка.ВладелецФормы = Неопределено;
Возврат ФормаСправка;
КонецФункции
// Параметры:
// ЭтаФорма - Форма - для возвращения фокуса ввода
Функция ОткрытьОписаниеТипаЛкс(Тип, ЭтаФорма = Неопределено) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзКонкретногоТипа(Тип);
СтрокаОбщегоТипа = мПлатформа.ТаблицаОбщихТипов.Найти(СтруктураТипа.ИмяОбщегоТипа);
Если СтрокаОбщегоТипа = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Результат = ирОбщий.ОткрытьСтраницуСинтаксПомощникаЛкс(СтрокаОбщегоТипа.ПутьКОписанию, , ЭтаФорма);
Возврат Результат;
КонецФункции
// Обходит строки табличного поля и имитирует редактирование и выбор пользователем заданного значения.
//
// Параметры:
// ТабличноеПоле - ТабличноеПоле;
// ЗначениеОбработки - Произвольные - значение, которое будем записывать в ячейки;
// *ФормаИнициатор - Форма, *Неопределено - форма, от имени которой будет записывать;
// *ТипИсточника – Строка, *Неопределено – "ТаблицаЗначений", "ТабличнаяЧасть";
// *Колонка – КолонкаТабличногоПоля, *Неопределено – колонка в которой обходим ячейки, по умолчанию текущая;
// *ТолькоВыделенныеСтроки - Булево, *Истина - обходить только выделенные строки.
//
Процедура УстановитьЗначениеВКолонкеТабличногоПоляТЧИлиТЗЛкс(ТабличноеПоле, ЗначениеОбработки, Знач ТипИсточника = Неопределено,
Знач Колонка = Неопределено, Знач ТолькоВыделенныеСтроки = Истина, Знач ИнтерактивнаяУстановка = Истина, Знач НаСервере = Ложь, СтруктураОтбора = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
ПроверятьОформлениеСтроки = ИнтерактивнаяУстановка;
ЗначениеТабличногоПоля = ирОбщий.ДанныеЭлементаФормыЛкс(ТабличноеПоле);
Если ТипИсточника = "" Тогда
ТипИсточника = ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле);
КонецЕсли;
ЕстьОтборСтрок = Ложь
Или ТипИсточника = "ТабличнаяЧасть"
Или ТипИсточника = "НаборЗаписей";
Если ТолькоВыделенныеСтроки Тогда
Если Истина
И ТабличноеПоле.ВыделенныеСтроки.Количество() = 1
И ТипИсточника <> "ДеревоЗначений"
Тогда
ТекстОтбора = "";
Если ЕстьОтборСтрок Тогда
ТекстОтбора = " удовлетворяющие отбору";
КонецЕсли;
Ответ = Вопрос("Выделена только одна строка. Хотите обработать все" + ТекстОтбора + " строки?",
РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Да Тогда
ТолькоВыделенныеСтроки = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтараяТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
СтараяТекущаяКолонка = ТекущаяКолонкаТаблицыФормыЛкс(ТабличноеПоле);
СтарыеВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТабличноеПоле);
Если Колонка = Неопределено Тогда
Колонка = СтараяТекущаяКолонка;
Иначе
УстановитьТекущуюКолонкуТаблицыФормыЛкс(ТабличноеПоле, Колонка);
КонецЕсли;
КлючиСтрокДляОбработки = Новый Массив;
КДанныетрокДляОбработки = Новый Массив;
Если ТолькоВыделенныеСтроки Тогда
Для Каждого ВыделеннаяСтрока Из ТабличноеПоле.ВыделенныеСтроки Цикл
КлючиСтрокДляОбработки.Добавить(ВыделеннаяСтрока);
КонецЦикла;
Иначе
Если ЕстьОтборСтрок Или СтруктураОтбора <> Неопределено Тогда
КлючеваяКолонка = "НомерСтроки";
Построитель = ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ТабличноеПоле, СтруктураОтбора);
#Если Сервер И Не Сервер Тогда
Построитель = Новый ПостроительЗапроса;
#КонецЕсли
Построитель.ВыбранныеПоля.Очистить();
Построитель.ВыбранныеПоля.Добавить(КлючеваяКолонка);
ТаблицаРезультата = Построитель.Результат.Выгрузить();
Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл
КлючиСтрокДляОбработки.Добавить(СтрокаРезультата[КлючеваяКолонка] - 1);
КонецЦикла;
ИначеЕсли ТипИсточника = "ТаблицаЗначений" Тогда
Для Каждого СтрокаТаблицы Из ЗначениеТабличногоПоля Цикл
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
КлючСтроки = СтрокаТаблицы.ПолучитьИдентификатор();
Иначе
КлючСтроки = СтрокаТаблицы;
КонецЕсли;
КлючиСтрокДляОбработки.Добавить(КлючСтроки);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
ЭлементУправления = Колонка.ЭлементУправления;
ДействиеПриИзменении = "" + ЭлементУправления.ПолучитьДействие("ПриИзменении");
ИнтерактивнаяУстановка = ИнтерактивнаяУстановка И ЗначениеЗаполнено(ДействиеПриИзменении);
Иначе
ЭлементУправления = Колонка;
КонецЕсли;
ИспользоватьИндикатор = ПроверятьОформлениеСтроки Или ИнтерактивнаяУстановка;
Индикатор = ПолучитьИндикаторПроцессаЛкс(КлючиСтрокДляОбработки.Количество(), "Групповая установка значения");
ПоследняяОбработаннаяСтрока = Неопределено;
Для Каждого КлючСтроки Из КлючиСтрокДляОбработки Цикл
ОбработкаПрерыванияПользователя();
Если ИспользоватьИндикатор Тогда
ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
ДанныеСтроки = ТабличноеПоле.ДанныеСтроки(КлючСтроки);
ТекущаяСтрока = КлючСтроки;
Иначе
Если ТипЗнч(КлючСтроки) = Тип("Число") Тогда
ТекущаяСтрока = ЗначениеТабличногоПоля[КлючСтроки];
Иначе
ТекущаяСтрока = КлючСтроки;
КонецЕсли;
ДанныеСтроки = ТекущаяСтрока;
Если ПроверятьОформлениеСтроки Тогда
ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(ДанныеСтроки);
Если ОформлениеСтроки.Ячейки[Колонка.Имя].ТолькоПросмотр Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ЗначениеОбработки) = Тип("Структура") Тогда
ЗаполнитьЗначенияСвойств(ЗначениеОбработки.Параметры, ДанныеСтроки);
НовоеЗначение = ВычислитьВыражение(ЗначениеОбработки.Формула, ЗначениеОбработки.Параметры, НаСервере);
Иначе
НовоеЗначение = ЗначениеОбработки;
КонецЕсли;
Если ИнтерактивнаяУстановка Тогда
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
ДействиеПриАктивизацииСтроки = ТабличноеПоле.ПолучитьДействие("ПриАктивизацииСтроки");
ТабличноеПоле.УстановитьДействие("ПриАктивизацииСтроки", Неопределено);
ТабличноеПоле.ТекущаяСтрока = ТекущаяСтрока;
ТабличноеПоле.УстановитьДействие("ПриАктивизацииСтроки", ДействиеПриАктивизацииСтроки);
Иначе
ТабличноеПоле.ТекущаяСтрока = КлючСтроки;
КонецЕсли;
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначение,, Ложь,,, Истина);
Иначе
ТекущаяСтрока[Колонка.Имя] = НовоеЗначение;
КонецЕсли;
ПоследняяОбработаннаяСтрока = ТекущаяСтрока;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс(Индикатор);
Если Истина
И ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле")
И Не ИнтерактивнаяУстановка
И ПоследняяОбработаннаяСтрока <> Неопределено
Тогда
// Переустановим значение ради срабатывания события ПриИзменении без его фактического изменения, чтобы сработали механизмы подсчета количества помеченных
ТабличноеПоле.ТекущаяСтрока = ПоследняяОбработаннаяСтрока;
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, ПоследняяОбработаннаяСтрока[ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле, Колонка)],,,,, Истина);
КонецЕсли;
ТабличноеПоле.ВыделенныеСтроки.Очистить();
Если СтараяТекущаяСтрока <> Неопределено Тогда
ТабличноеПоле.ТекущаяСтрока = СтараяТекущаяСтрока;
КонецЕсли;
Если СтараяТекущаяКолонка <> Неопределено Тогда
УстановитьТекущуюКолонкуТаблицыФормыЛкс(ТабличноеПоле, СтараяТекущаяКолонка);
КонецЕсли;
Для Каждого СтрокаЦикл Из СтарыеВыделенныеСтроки Цикл
ТабличноеПоле.ВыделенныеСтроки.Добавить(СтрокаЦикл);
КонецЦикла;
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
ТабличноеПоле.ОбновитьСтроки(); // Антибаг платформы. Без этого иногда некоторые строки были недорисованы
КонецЕсли;
КонецПроцедуры
// Результат:
// Неопределено, ТаблицаЗначений, ДеревоЗначений
Функция ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(Знач ИсточникДействий, Знач МассивСтрок = Неопределено, СУчетомОтбора = Ложь, ПреобразоватьДеревоВТаблицу = Истина) Экспорт
ПолноеИмяТаблицыБД = "";
ДанныеТабличногоПоля = Неопределено;
ТипИсточника = ОбщийТипДанныхТабличногоПоляЛкс(ИсточникДействий,,, ПолноеИмяТаблицыБД, ДанныеТабличногоПоля);
Если ТипИсточника = "Список" И ЗначениеЗаполнено(ПолноеИмяТаблицыБД) Тогда
Возврат Неопределено;
КонецЕсли;
Если Ложь
#Если Клиент Тогда
Или ТипЗнч(ИсточникДействий) = Тип("ТабличноеПоле")
#КонецЕсли
Тогда
#Если Сервер И Не Сервер Тогда
ИсточникДействий = Новый ТабличноеПоле;
#КонецЕсли
ВыгрузкаРезультата = ирОбщий.ДанныеЭлементаФормыЛкс(ИсточникДействий);
Если ТипЗнч(ВыгрузкаРезультата) = Тип("ТаблицаЗначений") Тогда
ВыгрузкаРезультата = ВыгрузкаРезультата.Скопировать(МассивСтрок);
ИначеЕсли ТипЗнч(ВыгрузкаРезультата) = Тип("ДеревоЗначений") Тогда
Если ПреобразоватьДеревоВТаблицу Тогда
Если МассивСтрок = Неопределено Тогда
ВыгрузкаРезультата = ирОбщий.ВсеСтрокиДереваЗначенийЛкс(ВыгрузкаРезультата, Истина);
Иначе
ВыгрузкаРезультата = СкопироватьКолонкиКоллекцииЛкс(ВыгрузкаРезультата, Новый ТаблицаЗначений);
Для Каждого СтрокаДерева Из МассивСтрок Цикл
ЗаполнитьЗначенияСвойств(ВыгрузкаРезультата.Добавить(), СтрокаДерева);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
Если МассивСтрок <> Неопределено Или Не СУчетомОтбора Тогда
ВыгрузкаРезультата = ВыгрузкаРезультата.Выгрузить(МассивСтрок);
Иначе
Построитель = ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ИсточникДействий);
#Если Сервер И Не Сервер Тогда
Построитель = Новый ПостроительЗапроса;
#КонецЕсли
ВыгрузкаРезультата = Построитель.Результат.Выгрузить();
КонецЕсли;
КонецЕсли;
Счетчик = 0;
Для Каждого КолонкаТП Из ИсточникДействий.Колонки Цикл
ПутьКДанным = ПутьКДаннымКолонкиТабличногоПоляЛкс(ИсточникДействий, КолонкаТП);
Если ЗначениеЗаполнено(ПутьКДанным) Тогда
КолонкаТЗ = ВыгрузкаРезультата.Колонки[ПутьКДанным];
ВыгрузкаРезультата.Колонки.Сдвинуть(КолонкаТЗ, Счетчик - ВыгрузкаРезультата.Колонки.Индекс(КолонкаТЗ));
Счетчик = Счетчик + 1;
КонецЕсли;
КонецЦикла;
Иначе // ТипЗнч(ИсточникДействий) = Тип("ТаблицаФормы")
ТаблицаФормы = ИсточникДействий;
ДанныеЭлемента = ДанныеЭлементаФормыЛкс(ТаблицаФормы);
Если ТипЗнч(ДанныеЭлемента) = Тип("ДинамическийСписок") Тогда
ДанныеЭлемента = Неопределено;
КонецЕсли;
Если МассивСтрок = Неопределено И ТипЗнч(ДанныеЭлемента) = Тип("ДанныеФормыДерево") Тогда
Результат = ДанныеФормыВЗначение(ДанныеЭлемента, Тип("ДеревоЗначений")); // Для табличных частей не работает
Иначе
Если ДанныеЭлемента = Неопределено Тогда
Если МассивСтрок = Неопределено Тогда
МассивСтрок = ВыделенныеСтрокиТабличногоПоляЛкс(ТаблицаФормы);
ирОбщий.СообщитьЛкс("Эта таблица позволяет выводить только выделенные строки");
КонецЕсли;
Иначе
//ТипЗначенияТаблицы = ирОбщий.ПолучитьТипЗначенияЭлементаФормыЛкс(ТаблицаФормы, Ложь);
//Если ТипЗначенияТаблицы <> Неопределено Тогда
// ТипЗначенияТаблицы = ТипЗначенияТаблицы.Типы()[0];
// ИмяОбщегоТипа = ОбщийТипДанныхТабличногоПоляЛкс(ТаблицаФормы, Истина);
// ОбъектМДТаблицы = Метаданные.НайтиПоТипу(ТипЗначенияТаблицы);
// Если ОбъектМДТаблицы <> Неопределено Тогда
// ВыгрузкаРезультата = Новый ТаблицаЗначений;
// Если ИмяОбщегоТипа = "ТабличнаяЧасть" Тогда
// // Через поля таблицы БД нельзя, т.к. у ТЧ может не быть проекции в БД
// Для Каждого МетаРеквизит Из ОбъектМДТаблицы.Реквизиты Цикл
// Результат.Колонки.Добавить(МетаРеквизит.Имя, МетаРеквизит.Тип, МетаРеквизит.Представление());
// КонецЦикла;
// Иначе
// ПоляТаблицыБД = ирОбщий.ПоляТаблицыМДЛкс(ОбъектМДТаблицы);
// Для Каждого ПолеБД Из ПоляТаблицыБД Цикл
// Результат.Колонки.Добавить(ПолеБД.Имя, ПолеБД.ТипЗначения, ПолеБД.Заголовок);
// КонецЦикла;
// КонецЕсли;
// КонецЕсли;
//КонецЕсли;
Если МассивСтрок = Неопределено Тогда
МассивСтрок = ДанныеЭлемента;
КонецЕсли;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
МассивСтрок = Новый Массив;
#КонецЕсли
Результат = Новый ТаблицаЗначений;
Если МассивСтрок.Количество() > 0 Тогда
КолонкиДобавлены = Ложь;
КолонкаСРеквизитом = "";
Для Каждого ИдентификаторСтроки Из МассивСтрок Цикл
Если ТипЗнч(ИдентификаторСтроки) = Тип("Число") Тогда
ДанныеСтроки = ТаблицаФормы.ДанныеСтроки(ИдентификаторСтроки);
Иначе
ДанныеСтроки = ИдентификаторСтроки;
КонецЕсли;
Если Не КолонкиДобавлены Тогда
Если ТипЗнч(ИдентификаторСтроки) = Тип("Число") Тогда
Результат.Колонки.Добавить("_КлючИсточника");
КонецЕсли;
ДобавитьКолонкиГруппыФормыВТаблицуЗначений(ТаблицаФормы.ПодчиненныеЭлементы, Результат, ДанныеСтроки);
ТекущееПоле = ТаблицаФормы.ТекущийЭлемент;
Если ТекущееПоле <> Неопределено Тогда
ПутьКДаннымПоля = НайтиПутьКДаннымПоляТаблицыФормыЛкс(ДанныеСтроки, ТекущееПоле.Имя);
ИмяРеквизитаКоллекции = ПутьКДаннымПоля;
Если Найти(ПутьКДаннымПоля, ".") > 0 Тогда
КолонкаСРеквизитом = ПутьКДаннымПоля;
ИмяРеквизитаКоллекции = СтрЗаменить(КолонкаСРеквизитом, ".", "_");
КонецЕсли;
Если Результат.Колонки.Найти(ИмяРеквизитаКоллекции) = Неопределено Тогда
Результат.Колонки.Добавить(ИмяРеквизитаКоллекции);
КонецЕсли;
КонецЕсли;
КолонкиДобавлены = Истина;
КонецЕсли;
НоваяСтрока = Результат.Добавить();
Если ТипЗнч(ИдентификаторСтроки) = Тип("Число") Тогда
НоваяСтрока._КлючИсточника = ИдентификаторСтроки;
КонецЕсли;
ЗаполнитьЗначенияСвойств(НоваяСтрока, ДанныеСтроки);
КонецЦикла;
Если ЗначениеЗаполнено(КолонкаСРеквизитом) Тогда
ЗначенияКолонкиСРеквизитом = ПрочитатьРеквизитПоМассивуСсылокЛкс(Результат.ВыгрузитьКолонку(ПервыйФрагментЛкс(КолонкаСРеквизитом)), ПоследнийФрагментЛкс(КолонкаСРеквизитом));
Результат.ЗагрузитьКолонку(ЗначенияКолонкиСРеквизитом, СтрЗаменить(КолонкаСРеквизитом, ".", "_"));
КонецЕсли;
Результат = ТаблицаСМинимальнымиТипамиКолонокЛкс(Результат);
ИначеЕсли ДанныеЭлемента <> Неопределено Тогда
ДобавитьКолонкиГруппыФормыВТаблицуЗначений(ТаблицаФормы.ПодчиненныеЭлементы, Результат, ДанныеЭлемента);
КонецЕсли;
//Если ВыделенныеСтрокиВосстановить <> Неопределено Тогда
// ТаблицаФормы.ВыделенныеСтроки.Очистить();
// Для Каждого ВыделеннаяСтрока Из ВыделенныеСтрокиВосстановить Цикл
// ТаблицаФормы.ВыделенныеСтроки.Добавить(ВыделеннаяСтрока);
// КонецЦикла;
//КонецЕсли;
КонецЕсли;
ВыгрузкаРезультата = Результат;
Если ПреобразоватьДеревоВТаблицу И ТипЗнч(ВыгрузкаРезультата) = Тип("ДеревоЗначений") Тогда
ВыгрузкаРезультата = ирОбщий.ВсеСтрокиДереваЗначенийЛкс(ВыгрузкаРезультата, Истина);
КонецЕсли;
КонецЕсли;
Возврат ВыгрузкаРезультата;
КонецФункции
Процедура ПоследниеВыбранныеНажатиеЛкс(Знач ЭтаФорма, ТабличноеПоле, Знач КлючевоеПоле = "Ссылка", Знач Кнопка) Экспорт
КлючЗначения = КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма, ТабличноеПоле);
ПоследниеВыбранные = ВосстановитьЗначениеЛкс(КлючЗначения);
Если ТипЗнч(ПоследниеВыбранные) <> Тип("СписокЗначений") Тогда
Возврат;
КонецЕсли;
ИндексЭлементаСписка = Число(Сред(Кнопка.Имя, СтрДлина(НачалоИмениКнопкиПодменюПоследнихВыбранных()) + 1));
Если ПоследниеВыбранные.Количество() <= ИндексЭлементаСписка Тогда
Возврат;
КонецЕсли;
КлючСтроки = ПоследниеВыбранные[ИндексЭлементаСписка].Значение;
СтрокаНайдена = ирОбщий.УстановитьТекущуюСтрокуСКонтролемУспешностиЛкс(ЭтаФорма, ТабличноеПоле, КлючевоеПоле, КлючСтроки,, Истина);
Если СтрокаНайдена И ЭтаФорма.РежимВыбора Тогда
Ответ = Вопрос("Выбрать установленную строку?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
//ЭтаФорма.ОповеститьОВыборе(КлючСтроки);
//Если Этаформа.ВводДоступен() Тогда
ОтправитьНажатияКлавишЛкс("{ENTER}");
//КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// https://docs.microsoft.com/ru-ru/office/vba/language/reference/user-interface-help/sendkeys-statement
// Параметры:
// СтрокаКлавиш - Строка - SHIFT +, CTRL ^, ALT %
//
Процедура ОтправитьНажатияКлавишЛкс(СтрокаКлавиш, ОжидатьЗавершения = Ложь) Экспорт
ирПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
ирПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ирПлатформа.WshShell.SendKeys(СтрокаКлавиш, ОжидатьЗавершения); // При этом почему то NumLock перенажимается
КонецПроцедуры
Процедура ПоследниеВыбранныеДобавитьЛкс(ЭтаФорма, Знач ВыбранноеЗначение, Знач ПредставлениеЗначения = "", Знач ТабличноеПоле = Неопределено) Экспорт
ЗапоминатьПоследниеВыбранные = КоличествоЗапоминаемыхПоследнихВыбранныхЛкс();
Если Истина
И ЗапоминатьПоследниеВыбранные <> Неопределено
И ЗапоминатьПоследниеВыбранные > 0
Тогда
КлючЗначения = КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма, ТабличноеПоле);
ПоследниеВыбранные = ВосстановитьЗначениеЛкс(КлючЗначения);
Если ТипЗнч(ПоследниеВыбранные) <> Тип("СписокЗначений") Тогда
ПоследниеВыбранные = Новый СписокЗначений;
КонецЕсли;
Если ТипЗнч(ВыбранноеЗначение) = Тип("Массив") Тогда
Если ВыбранноеЗначение.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ВыбранноеЗначение = ВыбранноеЗначение[0];
КонецЕсли;
Индекс = ПоследниеВыбранные.НайтиПоЗначению(ВыбранноеЗначение);
Если Индекс <> Неопределено Тогда
ПоследниеВыбранные.Удалить(Индекс);
КонецЕсли;
КлючСтроки = ВыбранноеЗначение;
Если Не ЗначениеЗаполнено(ПредставлениеЗначения) Тогда
ПредставлениеЗначения = ПредставлениеКлючаСтрокиБДЛкс(ВыбранноеЗначение);
КонецЕсли;
ПоследниеВыбранные.Вставить(0, КлючСтроки, ПредставлениеЗначения);
ирОбщий.СохранитьЗначениеЛкс(КлючЗначения, ПоследниеВыбранные);
КонецЕсли;
КонецПроцедуры
Процедура НайденныеСтандартноСсылкиПриВыводеСтрокиЛкс(Знач ОформлениеСтроки) Экспорт
ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
Ячейки = ОформлениеСтроки.Ячейки;
Если ирОбщий.ЛиКорневойТипРегистраСведенийЛкс(ирОбщий.ПервыйФрагментЛкс(ДанныеСтроки.Метаданные)) Тогда
Попытка
КлючЗаписи = ЗначениеИзСтрокиВнутр(Ячейки.Данные.Текст);
Исключение
// Некоторые большие ключи регистров в сериализованном виде не умещаются в 1024 символа
КлючЗаписи = "<Ключ записи регистра обрезан и не может быть восстановлен>";
КонецПопытки;
Ячейки.Данные.Текст = ирОбщий.ПредставлениеКлючаСтрокиБДЛкс(КлючЗаписи, Ложь);
КонецЕсли;
КонецПроцедуры
Процедура ОформитьФонТекущейСтрокиЛкс(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
Если Элемент.ТекущаяСтрока = ДанныеСтроки Тогда
ОформлениеСтроки.ЦветФона = WebЦвета.СветлоНебесноГолубой;
КонецЕсли;
КонецПроцедуры
Функция ПроверитьЗапуститьОтладчик(Знач ВремяОжиданияЗапуска = 5) Экспорт
ИдентификаторПроцессаОтладчика = Неопределено;
Платформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
Платформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ПортОтладки = Платформа.ПортДляПодключенияОтладчика(ИдентификаторПроцессаОтладчика);
Если ИдентификаторПроцессаОтладчика = Неопределено Тогда
//Если Не УФ(сПроверитьДоступностьКонфигуратора) Тогда
// СообщитьЛкс("Конфигуратор уже открыт, но отладка не подключена. Выполните подключение отладчика вручную");
// Перейти ~Конец;
//КонецЕсли;
// Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1003164#1003164
Если ирКэш.НомерВерсииПлатформыЛкс() = 802015 Тогда
СообщитьЛкс("Из-за ошибки платформы 8.2.15 запуск и подключение отладчика необходимо выполнять вручную");
Возврат Неопределено;
КонецЕсли;
Если ПортОтладки = Неопределено Тогда
СообщитьЛкс("Если используется TCP отладка, включите разрешение отладки в главном меню ""Сервис/Параметры/Системные"" и повторите операцию снова");
Возврат Неопределено;
КонецЕсли;
ПараметрыЗапуска = "CONFIG /DEBUG /DEBUGTARGET""tcp://127.0.0.1:" + ПортОтладки + """";
ЗапуститьСистему(ПараметрыЗапуска);
ПаузаЛкс(ВремяОжиданияЗапуска);
Если ИдентификаторПроцессаОтладчика = Неопределено Тогда
ИдентификаторПроцессаОтладчика = 0;
КонецЕсли;
Пока Истина Цикл
Платформа.ПортДляПодключенияОтладчика(ИдентификаторПроцессаОтладчика);
Если ИдентификаторПроцессаОтладчика = Неопределено Тогда
Ответ = Вопрос("Отладчик еще не подключился. Повторить снова?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Прервать;
КонецЦикла;
Иначе
Платформа.АктивизироватьОкноПроцесса1С8(Число(ИдентификаторПроцессаОтладчика));
КонецЕсли;
Если ИдентификаторПроцессаОтладчика <> Неопределено Тогда
Результат = Число(ИдентификаторПроцессаОтладчика);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОткрытьСсылкуЯчейкиВРедактореОбъектаБДЛкс(ТабличноеПоле, ИмяКолонки = "") Экспорт
Если ТабличноеПоле.ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ТекущаяКолонка = ТекущаяКолонкаТаблицыФормыЛкс(ТабличноеПоле);
Если ТекущаяКолонка = Неопределено Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
ИмяКолонки = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТекущаяКолонка, Истина);
Иначе
ИмяКолонки = ТекущаяКолонка.Данные;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Возврат;
КонецЕсли;
ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные[ИмяКолонки];
XMLТип = XMLТипЗнч(ЗначениеЯчейки);
Если XMLТип = Неопределено Тогда
Возврат;
КонецЕсли;
Если Найти(XMLТип.ИмяТипа, "Ref.") = 0 Тогда
Возврат;
КонецЕсли;
//Если Ложь
// Или Найти(XMLТип.ИмяТипа, "EnumRef.") > 0
// Или Найти(XMLТип.ИмяТипа, "BusinessProcessRoutePointRef.") > 0
//Тогда
// ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеЯчейки)),, Истина,,,, ЗначениеЯчейки);
//Иначе
ОткрытьСсылкуВРедактореОбъектаБДЛкс(ЗначениеЯчейки);
//КонецЕсли;
КонецПроцедуры
// Параметры
// КлючИлиОбъект - СтруктураОбъектаБД, Ссылка, ОбъектБД
Функция ОткрытьСсылкуВРедактореОбъектаБДЛкс(КлючОбъекта, ИскомоеЗначение = Неопределено, ИмяТабличнойЧасти = "", ИмяПоля = "", КлючСтроки = Неопределено) Экспорт
ФормаРедактора = ПолучитьФормуСсылки(КлючОбъекта, ИскомоеЗначение);
ФормаРедактора.Открыть();
Если ЗначениеЗаполнено(ИмяПоля) Тогда
Если ЗначениеЗаполнено(ИмяТабличнойЧасти) Тогда
ИмяДочернейТаблицыБД = КлючОбъекта.Метаданные().ПолноеИмя();
ИмяДочернейТаблицыБД = ИмяДочернейТаблицыБД + "." + ИмяТабличнойЧасти;
КонецЕсли;
ФормаРедактора.ПоказатьЯчейкуДанныхОбъекта(ИмяДочернейТаблицыБД, ИмяПоля, КлючСтроки);
КонецЕсли;
Возврат ФормаРедактора;
КонецФункции
Функция ОткрытьОбъектВРедактореОбъектаБДЛкс(ОбъектБД, ИскомоеЗначение = Неопределено, КлючУникальности = Неопределено) Экспорт
Если КлючУникальности = Неопределено Тогда
КлючУникальности = Новый УникальныйИдентификатор;
КонецЕсли;
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ПараметрКлючИлиОбъект", ОбъектБД);
ПараметрыФормы.Вставить("ПараметрПрочитатьОбъект", Ложь);
ПараметрыФормы.Вставить("ПараметрИскомоеЗначение", ИскомоеЗначение);
Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", ПараметрыФормы,, КлючУникальности);
#Если Сервер И Не Сервер Тогда
Форма = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
ЗаполнитьЗначенияСвойств(Форма.фОбъект, ПараметрыФормы, "ПараметрКлючИлиОбъект, ПараметрПрочитатьОбъект, ПараметрИскомоеЗначение");
Форма.Открыть();
Возврат Форма;
КонецФункции
// Параметры
// КлючИлиОбъект - СтруктураОбъектаБД, Ссылка, ОбъектБД
Функция ПолучитьФормуСсылки(КлючОбъекта, ИскомоеЗначение = Неопределено)
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ПараметрКлючИлиОбъект", КлючОбъекта);
ПараметрыФормы.Вставить("ПараметрПрочитатьОбъект", Истина);
ПараметрыФормы.Вставить("ПараметрИскомоеЗначение", ИскомоеЗначение);
Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", ПараметрыФормы,, КлючОбъекта);
#Если Сервер И Не Сервер Тогда
Форма = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
ЗаполнитьЗначенияСвойств(Форма, ПараметрыФормы);
Возврат Форма;
КонецФункции
Процедура НайтиИПоказатьСсылкиНаОбъектБД(СсылкаНаКоторуюИщемСсылки) Экспорт
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ПараметрКлючИлиОбъект", СсылкаНаКоторуюИщемСсылки);
Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", ПараметрыФормы);
#Если Сервер И Не Сервер Тогда
Форма = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
ЗаполнитьЗначенияСвойств(Форма, ПараметрыФормы);
Форма.Открыть();
Форма.НайтиИПоказатьСсылкиВФорме();
КонецПроцедуры // НайтиСсылки()
// ВариантПросмотра - Строка - "Компактный", "ЯзыкЗапросов", "ВстроенныйЯзык", ...
Функция ПолучитьФормуТекстаЛкс(Текст, Знач Заголовок = "", ВариантПросмотра = "Компактный", ТолькоПросмотр = Ложь, Знач КлючУникальности = Неопределено, ВладелецФормы = Неопределено, ВыделитьВсе = Ложь) Экспорт
Если КлючУникальности = Неопределено Тогда
КлючУникальности = Новый УникальныйИдентификатор();
КонецЕсли;
ФормаПросмотра = ирКэш.Получить().ПолучитьФорму("Текст", ВладелецФормы, КлючУникальности);
ФормаПросмотра.НачальноеЗначениеВыбора = Текст;
ФормаПросмотра.РекомендуемыйВариант = ВариантПросмотра;
ФормаПросмотра.ТолькоПросмотр = ТолькоПросмотр;
ФормаПросмотра.ПараметрВыделитьВсе = ВыделитьВсе;
Если Не ЗначениеЗаполнено(Заголовок) Тогда
//Заголовок = ФормаПросмотра.Заголовок;
Заголовок = "Текст"; // Чтобы при повторном открытии не оставался старый текст
КонецЕсли;
ФормаПросмотра.Заголовок = Заголовок;
Возврат ФормаПросмотра;
КонецФункции
Функция ОткрытьТекстЛкс(Текст, Знач Заголовок = "", ВариантПросмотра = "Компактный", ТолькоПросмотр = Ложь, Знач КлючУникальности = Неопределено, ВладелецФормы = Неопределено, ВыделитьВсе = Ложь) Экспорт
ФормаПросмотра = ПолучитьФормуТекстаЛкс(Текст, Заголовок, ВариантПросмотра, ТолькоПросмотр, КлючУникальности, ВладелецФормы, ВыделитьВсе);
ФормаПросмотра.Открыть();
Возврат ФормаПросмотра;
КонецФункции
Процедура ОткрытьПросмотрДереваJSONЛкс(Знач СтрокаJSON, Знач Заголовок = "", Знач КлючУникальности = Неопределено, ВладелецФормы = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(СтрокаJSON) Тогда
Возврат;
КонецЕсли;
Если КлючУникальности = Неопределено Тогда
КлючУникальности = Новый УникальныйИдентификатор();
КонецЕсли;
ФормаПросмотра = ирКэш.Получить().ПолучитьФорму("ДеревоJSON", ВладелецФормы, КлючУникальности);
ФормаПросмотра.ПараметрJSON = СтрокаJSON;
ФормаПросмотра.Открыть();
Если ЗначениеЗаполнено(Заголовок) Тогда
ирОбщий.ОбновитьТекстПослеМаркераВСтрокеЛкс(ФормаПросмотра.Заголовок,, Заголовок, " - ");
КонецЕсли;
КонецПроцедуры
Функция ФормаПросмотраHTMLЛкс(Текст) Экспорт
Форма = ирКэш.Получить().ПолучитьФорму("HTML");
Форма.ЭлементыФормы.ПолеHtmlДокумента.УстановитьТекст(Текст);
Возврат Форма;
КонецФункции
Процедура ПолеВводаТекста_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка) Экспорт
Если ТипЗнч(Элемент.Значение) = Тип("Строка") Тогда
СтандартнаяОбработка = Ложь;
ФормаРедактора = ирКэш.Получить().ПолучитьФорму("Текст", Элемент, Новый УникальныйИдентификатор);
ФормаРедактора.РежимВыбора = Истина;
ФормаРедактора.НачальноеЗначениеВыбора = Элемент.Значение;
ФормаРедактора.Открыть();
КонецЕсли;
КонецПроцедуры
// Для управляемой формы возвращает путь относительно родителя
Функция ПутьКДаннымКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, Колонка = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
Если Колонка = Неопределено Тогда
Колонка = ТекущаяКолонкаТаблицыФормыЛкс(ТабличноеПоле);
КонецЕсли;
Если ТипЗнч(Колонка) = Тип("ПолеФормы") Тогда
ПутьКДанным = ПутьКДаннымЭлементаУправляемойФормыЛкс(Колонка, Истина);
Если Не ЗначениеЗаполнено(ПутьКДанным) Тогда
ПутьКДанным = Колонка.Имя;
Если Найти(ПутьКДанным, ТабличноеПоле.Имя) = 1 Тогда
ДанныеТаблицы = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
ПутьКДанным = Сред(ПутьКДанным, СтрДлина(ТабличноеПоле.Имя) + 1);
КонецЕсли;
СтрокаИлиКоллекция = Неопределено;
Если ТабличноеПоле.ТекущиеДанные = Неопределено Тогда
Если ЛиДанныеФормыСВозможностьюПоискаЛкс(ДанныеТаблицы) Тогда
СтрокаИлиКоллекция = ДанныеТаблицы;
КонецЕсли;
Иначе
СтрокаИлиКоллекция = ТабличноеПоле.ТекущиеДанные;
КонецЕсли;
Если СтрокаИлиКоллекция <> Неопределено Тогда
ПутьКДанным = НайтиПутьКДаннымПоляТаблицыФормыЛкс(СтрокаИлиКоллекция, ПутьКДанным);
КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗнч(Колонка) = Тип("ГруппаФормы") Тогда
ПутьКДанным = "";
ИначеЕсли Колонка <> Неопределено Тогда
// Обычная форма
ПутьКДанным = Колонка.Данные;
Если Не ЗначениеЗаполнено(ПутьКДанным) Тогда
ПутьКДанным = Колонка.ДанныеФлажка;
Если Не ЗначениеЗаполнено(ПутьКДанным) Тогда
Если Ложь
Или ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений")
Или ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений")
Тогда
ПутьКДанным = Колонка.ДанныеКартинки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ТабличноеПоле.Значение) = Тип("НастройкиКомпоновкиДанных") Тогда
// Здесь ПутьКДанным = "СтруктураОтчета" - виртуальное имя
ПутьКДанным = "";
ИначеЕсли Ложь
Или ПутьКДанным = "ПравоеЗначениеДляКраткогоОтображенияЭлемента"
Тогда
ПутьКДанным = "ПравоеЗначение";
ИначеЕсли Ложь
Или ПутьКДанным = "ВидыСравненияДляКраткогоОтображенияЭлемента"
Тогда
ПутьКДанным = "ВидСравнения";
ИначеЕсли Ложь
Или ПутьКДанным = "ЛевоеЗначениеДляКраткогоОтображенияЭлемента"
Тогда
ПутьКДанным = "ЛевоеЗначение";
КонецЕсли;
КонецЕсли;
Возврат ПутьКДанным;
КонецФункции
Функция НайтиПутьКДаннымПоляТаблицыФормыЛкс(Знач СтрокаИлиКоллекция, Знач ИмяПоля, выхЗначениеПоля = Неопределено) Экспорт
Если ТипЗнч(СтрокаИлиКоллекция) = Тип("ТаблицаФормы") Тогда
СтрокаИлиКоллекция = ДанныеЭлементаФормыЛкс(СтрокаИлиКоллекция);
КонецЕсли;
ДлинаСтроки = СтрДлина(ИмяПоля);
ПутьКДанным = "";
РежимКоллекции = ЛиДанныеФормыСВозможностьюПоискаЛкс(СтрокаИлиКоллекция);
Пока ДлинаСтроки > 0 Цикл
ПроверяемоеИмя = Прав(ИмяПоля, ДлинаСтроки);
ДлинаСтроки = ДлинаСтроки - 1;
Если РежимКоллекции Тогда
Попытка
СтрокаИлиКоллекция.НайтиСтроки(Новый Структура(ПроверяемоеИмя));
ПутьКДанным = ПроверяемоеИмя;
Прервать;
Исключение
Продолжить;
КонецПопытки;
Иначе
Попытка
выхЗначениеПоля = СтрокаИлиКоллекция[ПроверяемоеИмя];
ПутьКДанным = ПроверяемоеИмя;
Прервать;
Исключение
Продолжить;
КонецПопытки;
КонецЕсли;
КонецЦикла;
Если Не ЗначениеЗаполнено(ПутьКДанным) Тогда
ДлинаИмениДочернегоРеквизита = 0;
Пока Не ЗначениеЗаполнено(ПутьКДанным) И ДлинаИмениДочернегоРеквизита < СтрДлина(ИмяПоля) Цикл
ДлинаИмениДочернегоРеквизита = ДлинаИмениДочернегоРеквизита + 1;
Если "_" <> Сред(ИмяПоля, СтрДлина(ИмяПоля) - ДлинаИмениДочернегоРеквизита + 1, 1) Тогда
Продолжить;
КонецЕсли;
ИмяРеквизита = Лев(ИмяПоля, СтрДлина(ИмяПоля) - ДлинаИмениДочернегоРеквизита);
ИмяДочернегоРеквизита = Прав(ИмяПоля, ДлинаИмениДочернегоРеквизита - 1);
ПутьКДанным = НайтиПутьКДаннымПоляТаблицыФормыЛкс(СтрокаИлиКоллекция, ИмяРеквизита, выхЗначениеПоля);
Если Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский Тогда
ИмяДочернегоРеквизита = ПеревестиВРусский(ИмяДочернегоРеквизита); // http://www.hostedredmine.com/issues/880938
КонецЕсли;
Если ЗначениеЗаполнено(ПутьКДанным) И выхЗначениеПоля <> Неопределено Тогда
ПоляТаблицыБД = ирКэш.ПоляТаблицыБДЛкс(выхЗначениеПоля.Метаданные().ПолноеИмя());
Если ПоляТаблицыБД.Найти(ИмяДочернегоРеквизита, "Имя") = Неопределено Тогда
ПутьКДанным = Неопределено;
Иначе
ПутьКДанным = ПутьКДанным + "." + ИмяДочернегоРеквизита;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ПутьКДанным;
КонецФункции
Процедура ТабличноеПолеОтборБезЗначенияВТекущейКолонке_КнопкаЛкс(Знач ТабличноеПоле) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
Если ТабличноеПоле.ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
ДанныеТабличногоПоля = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДанныеТабличногоПоля, "Пользовательские");
Попытка
Отбор = НастройкиСписка.Отбор;
Исключение
Отбор = ТабличноеПоле.ОтборСтрок;
КонецПопытки;
ТабличноеПолеОтборБезЗначенияВТекущейКолонкеЛкс(ТабличноеПоле, Отбор);
КонецПроцедуры
// Параметры:
// ТабличноеПоле - ТабличноеПоле -
// Отбор - ОтборКомпоновкиДанных -
// ТипВыхода - Строка - Служебный параметр для перехода после вызова метода
Функция ТабличноеПолеОтборБезЗначенияВТекущейКолонкеЛкс(Знач ТабличноеПоле, Знач Отбор, Знач СообщитьОДобавлении = Ложь, ТабличноеПолеОтбора = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
ТабличноеПолеОтбора = Новый ТабличноеПоле;
#КонецЕсли
Если ТабличноеПоле.ТекущаяСтрока = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
ДанныеКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
Возврат Ложь;
КонецЕсли;
Если ТипЗнч(Отбор) = Тип("Отбор") Тогда
#Если Сервер И Не Сервер Тогда
Отбор = Новый ПостроительЗапроса;
Отбор = Отбор.Отбор;
#КонецЕсли
ЭлементОтбора = Отбор.Найти(ДанныеКолонки);
Если ЭлементОтбора = Неопределено Тогда
// Например "Предопределенный"
Возврат Ложь;
КонецЕсли;
ДоступноеПоле = ЭлементОтбора;
ТекущееЗначениеОтбора = ЭлементОтбора.Значение;
ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные[ДанныеКолонки];
Иначе
#Если Сервер И Не Сервер Тогда
Отбор = Новый НастройкиКомпоновкиДанных;
Отбор = Отбор.Отбор;
#КонецЕсли
ДоступноеПоле = ирОбщий.НайтиДоступноеПолеКомпоновкиПоИмениКолонкиЛкс(Отбор.ДоступныеПоляОтбора, ДанныеКолонки);
#Если Сервер И Не Сервер Тогда
ДоступноеПоле = НастройкиСписка.ДоступныеПоляВыбора.НайтиПоле();
#КонецЕсли
ЭлементОтбора = ирОбщий.НайтиДобавитьЭлементОтбораКомпоновкиЛкс(Отбор, ДоступноеПоле.Поле,,,,, Ложь);
ТекущееЗначениеОтбора = ЭлементОтбора.ПравоеЗначение;
ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные["" + ДоступноеПоле.Поле];
КонецЕсли;
Если ЭлементОтбора.Использование Тогда
Если Ложь
Или ЭлементОтбора.ВидСравнения = ВидСравнения.НеРавно
Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно
Тогда
Если Ложь
Или ТипЗнч(ЗначениеЯчейки) <> Тип("Булево")
Или ДоступноеПоле.ТипЗначения.Типы().Количество() > 1
Тогда
СписокЗначений = Новый СписокЗначений;
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
НовыйВидСравения = ВидСравнения.НеВСписке;
Иначе
НовыйВидСравения = ВидСравненияКомпоновкиДанных.НеВСписке;
КонецЕсли;
СписокЗначений.Добавить(ТекущееЗначениеОтбора);
СписокЗначений.Добавить(ЗначениеЯчейки);
ЭлементОтбора.ВидСравнения = НовыйВидСравения;
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
ЭлементОтбора.Значение = СписокЗначений;
Иначе
ЭлементОтбора.ПравоеЗначение = СписокЗначений;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или ЭлементОтбора.ВидСравнения = ВидСравнения.НеВСписке
Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеВСписке
Тогда
СписокЗначений = ТекущееЗначениеОтбора;
Если СписокЗначений.НайтиПоЗначению(ЗначениеЯчейки) = Неопределено Тогда
СписокЗначений.Добавить(ЗначениеЯчейки);
КонецЕсли;
// Для обновления отбора
ЭлементОтбора.Использование = Ложь;
ЭлементОтбора.Использование = Истина;
ИначеЕсли Ложь
Или ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке
Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке
Тогда
СписокЗначений = ТекущееЗначениеОтбора;
СписокЗначений.Удалить(СписокЗначений.НайтиПоЗначению(ЗначениеЯчейки));
// Для обновления отбора
ЭлементОтбора.Использование = Ложь;
ЭлементОтбора.Использование = Истина;
Иначе
ЭлементОтбора.Использование = Ложь;
КонецЕсли;
КонецЕсли;
Если Не ЭлементОтбора.Использование Тогда
ЭлементОтбора.Использование = Истина;
Если Истина
И ДоступноеПоле.ТипЗначения.СодержитТип(Тип("Строка"))
И ДоступноеПоле.ТипЗначения.КвалификаторыСтроки.Длина = 0
Тогда
Если Не ЗначениеЗаполнено(ЗначениеЯчейки) Тогда
// Особенность платформы
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
ЭлементОтбора.ВидСравнения = ВидСравнения.Содержит;
Иначе
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит;
КонецЕсли;
Иначе
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
ЭлементОтбора.ВидСравнения = ВидСравнения.НеСодержит;
Иначе
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеСодержит;
КонецЕсли;
КонецЕсли;
Иначе
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
ЭлементОтбора.ВидСравнения = ВидСравнения.НеРавно;
Иначе
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
// Привести значение нужно например для NULL в динамическом списке регистра бухгалтерии
ЭлементОтбора.Значение = ЭлементОтбора.ТипЗначения.ПривестиЗначение(ЗначениеЯчейки);
Иначе
ЭлементОтбора.ПравоеЗначение = ЗначениеЯчейки;
КонецЕсли;
КонецЕсли;
Если СообщитьОДобавлении Тогда
СообщитьЛкс("В отбор установлен элемент """ + ПредставлениеЭлементаОтбораЛкс(ЭлементОтбора) + """");
КонецЕсли;
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
ПроверитьВключитьЭлементНастроекКомпоновкиВПользовательскиеНастройки(ЭлементОтбора);
КонецЕсли;
Если ТабличноеПолеОтбора <> Неопределено Тогда
ТабличноеПолеОтбора.ТекущаяСтрока = ЭлементОтбора;
КонецЕсли;
Возврат Истина;
КонецФункции
Функция ТабличноеПолеОтборПоЗначениюВТекущейКолонкеЛкс(Знач ТабличноеПоле, Знач Отбор, Знач СообщитьОДобавлении = Ложь, ТабличноеПолеОтбора = Неопределено) Экспорт
Если ТабличноеПоле.ТекущаяСтрока = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
ДанныеКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
Возврат Ложь;
КонецЕсли;
Если ТипЗнч(Отбор) = Тип("Отбор") Тогда
#Если Сервер И Не Сервер Тогда
Отбор = Новый ПостроительЗапроса;
Отбор = Отбор.Отбор;
#КонецЕсли
ЭлементОтбора = Отбор.Найти(ДанныеКолонки);
Если ЭлементОтбора = Неопределено Тогда
// Например "Предопределенный"
Возврат Ложь;
КонецЕсли;
ДоступноеПоле = ЭлементОтбора;
ТекущееЗначениеОтбора = ЭлементОтбора.Значение;
ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные[ДанныеКолонки];
Иначе
#Если Сервер И Не Сервер Тогда
Отбор = Новый НастройкиКомпоновкиДанных;
Отбор = Отбор.Отбор;
#КонецЕсли
ДоступноеПоле = ирОбщий.НайтиДоступноеПолеКомпоновкиПоИмениКолонкиЛкс(Отбор.ДоступныеПоляОтбора, ДанныеКолонки);
#Если Сервер И Не Сервер Тогда
ДоступноеПоле = НастройкиСписка.ДоступныеПоляВыбора.НайтиПоле();
#КонецЕсли
ЭлементОтбора = ирОбщий.НайтиДобавитьЭлементОтбораКомпоновкиЛкс(Отбор, ДоступноеПоле.Поле,,,,, Ложь);
ТекущееЗначениеОтбора = ЭлементОтбора.ПравоеЗначение;
ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные["" + ДоступноеПоле.Поле];
КонецЕсли;
Если Истина
И Не СообщитьОДобавлении
И ЭлементОтбора.Использование
И (Ложь
Или ЭлементОтбора.ВидСравнения = ВидСравнения.Равно
Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно)
Тогда
ЭлементОтбора.Использование = Ложь;
Иначе
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
НовыйВидСравения = ВидСравнения.Равно;
Иначе
НовыйВидСравения = ВидСравненияКомпоновкиДанных.Равно;
КонецЕсли;
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.ВидСравнения = НовыйВидСравения;
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
// Привести значение нужно например для NULL в динамическом списке регистра бухгалтерии
ЭлементОтбора.Значение = ЭлементОтбора.ТипЗначения.ПривестиЗначение(ЗначениеЯчейки);
Иначе
ЭлементОтбора.ПравоеЗначение = ЗначениеЯчейки;
КонецЕсли;
КонецЕсли;
Если СообщитьОДобавлении Тогда
СообщитьЛкс("В отбор установлен элемент """ + ПредставлениеЭлементаОтбораЛкс(ЭлементОтбора) + """");
КонецЕсли;
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
ПроверитьВключитьЭлементНастроекКомпоновкиВПользовательскиеНастройки(ЭлементОтбора);
КонецЕсли;
Если ТабличноеПолеОтбора <> Неопределено Тогда
ТабличноеПолеОтбора.ТекущаяСтрока = ЭлементОтбора;
КонецЕсли;
Возврат Истина;
КонецФункции
Функция ЗагрузитьЗначениеИзФайлаИнтерактивноЛкс(Знач Расширение = "", Знач ОписаниеФормата = "", Знач Сжатие = Истина) Экспорт
Если Не ЗначениеЗаполнено(Расширение) И Сжатие Тогда
Расширение = "zip";
КонецЕсли;
ПолноеИмяФайла = ВыбратьФайлЛкс(, Расширение, ОписаниеФормата);
Если ПолноеИмяФайла = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Результат = ЗагрузитьЗначениеИзФайлаЛкс(ПолноеИмяФайла, Сжатие);
Возврат Результат;
КонецФункции
Функция СохранитьЗначениеВФайлИнтерактивноЛкс(Знач Значение, Знач Расширение = "", Знач ОписаниеФормата = "", Знач Сжатие = Истина, Знач УровеньСжатия = Неопределено, Знач Заголовок = "") Экспорт
Если Не ЗначениеЗаполнено(Расширение) И Сжатие Тогда
Расширение = "zip";
КонецЕсли;
ПолноеИмяФайла = ВыбратьФайлЛкс(Ложь, Расширение, ОписаниеФормата,,,, Заголовок);
Если ПолноеИмяФайла = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Результат = СохранитьЗначениеВФайлЛкс(Значение, ПолноеИмяФайла, Сжатие, УровеньСжатия);
Возврат Результат;
КонецФункции
Функция ВыбратьРедактируемыйТипЛкс(ОграничениеТипа = Неопределено, ТолькоПросмотр = Ложь, НачальноеЗначениеВыбора = Неопределено, ВладелецФормы = Неопределено, ЗакрыватьПриВыборе = Истина) Экспорт
Если ОграничениеТипа = Неопределено Тогда
ОграничениеТипа = Новый ОписаниеТипов;
КонецЕсли;
ФормаРедактора = ирКэш.Получить().ПолучитьФорму("ВыборРедактируемыхТипов", ВладелецФормы);
ФормаРедактора.ОграничениеТипа = ОграничениеТипа;
ФормаРедактора.ЗакрыватьПриВыборе = ЗакрыватьПриВыборе;
ФормаРедактора.НачальноеЗначениеВыбора = НачальноеЗначениеВыбора;
ФормаРедактора.РежимВыбора = Истина;
ФормаРедактора.МножественныйВыбор = Ложь;
ФормаРедактора.ТолькоПросмотр = ТолькоПросмотр;
РезультатВыбора = ФормаРедактора.ОткрытьМодально();
Возврат РезультатВыбора;
КонецФункции
Функция РедактироватьОписаниеРедактируемыхТиповЛкс(ОграничениеТипаИлиПолеВвода, ТолькоПросмотр = Ложь) Экспорт
Если ТипЗнч(ОграничениеТипаИлиПолеВвода) = Тип("ОписаниеТипов") Тогда
ВладелецФормы = Неопределено;
ОграничениеТипа = ОграничениеТипаИлиПолеВвода;
Иначе
ВладелецФормы = ОграничениеТипаИлиПолеВвода;
ОграничениеТипа = ОграничениеТипаИлиПолеВвода.Значение;
КонецЕсли;
ФормаРедактора = ирКэш.Получить().ПолучитьФорму("ВыборРедактируемыхТипов", ВладелецФормы);
//ФормаРедактора.ОграничениеТипа = ОграничениеТипа;
ФормаРедактора.НачальноеЗначениеВыбора = ОграничениеТипа;
ФормаРедактора.РежимВыбора = Истина;
ФормаРедактора.МножественныйВыбор = Истина;
ФормаРедактора.ТолькоПросмотр = ТолькоПросмотр;
РезультатВыбора = ФормаРедактора.ОткрытьМодально();
Возврат РезультатВыбора;
КонецФункции
// ПолноеИмяНачальногоТипаВыбора - Строка - полное имя метаданного
Функция ОткрытьПодборСВыборомТипаЛкс(ВладелецФормы, ОписаниеТипов = Неопределено, Знач НачальноеЗначениеВыбора = Неопределено, ИспользоватьДинамическийСписокИР = Истина,
ПриПустомОписанииТиповРазрешатьВсе = Ложь) Экспорт
ЕстьТипТип = Ложь;
Если ТипЗнч(ОписаниеТипов) = Тип("Строка") Тогда
ДоступныеОбъекты = СтрРазделитьЛкс(ОписаниеТипов, ",", Истина);
ИначеЕсли ОписаниеТипов <> Неопределено Тогда
ДоступныеОбъекты = Новый Массив();
ЕстьТипТип = Ложь;
Для Каждого Тип Из ОписаниеТипов.Типы() Цикл
Если Тип = Тип("Тип") Тогда
ЕстьТипТип = Истина;
Иначе
ПолноеИмяМД = ПолучитьПолноеИмяМДТипаЛкс(Тип);
Если ЗначениеЗаполнено(ПолноеИмяМД) Тогда
ДоступныеОбъекты.Добавить(ПолноеИмяМД);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ДоступныеОбъекты.Количество() = 0 И ПриПустомОписанииТиповРазрешатьВсе Тогда
ДоступныеОбъекты = Неопределено;
КонецЕсли;
КонецЕсли;
Если Истина
И ДоступныеОбъекты = Неопределено
И (Ложь
Или ЕстьТипТип
Или (Истина
И ОписаниеТипов = Неопределено
И ТипЗнч(НачальноеЗначениеВыбора) = Тип("Тип")))
Тогда
Возврат ВыбратьРедактируемыйТипЛкс(,, НачальноеЗначениеВыбора, ВладелецФормы, Ложь);
КонецЕсли;
Если НачальноеЗначениеВыбора <> Неопределено Тогда
ТипНачальногоЗначенияВыбора = ТипОбъектаБДЛкс(НачальноеЗначениеВыбора);
ПолноеИмяНачальногоТипаВыбора = ПолучитьПолноеИмяМДТипаЛкс(ТипНачальногоЗначенияВыбора);
КонецЕсли;
Если Ложь
Или ДоступныеОбъекты = Неопределено
Или ДоступныеОбъекты.Количество() = 0
Или ДоступныеОбъекты.Количество() > 1
Тогда
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", ВладелецФормы);
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ДоступныеОбъекты", ДоступныеОбъекты);
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", ПолноеИмяНачальногоТипаВыбора);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
Результат = Форма.ОткрытьМодально();
Если Результат = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ПолноеИмяМД = Результат.ПолноеИмяОбъекта;
Иначе
ПолноеИмяМД = ДоступныеОбъекты[0];
КонецЕсли;
Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда
Возврат Неопределено;
КонецЕсли;
Если ПолноеИмяНачальногоТипаВыбора <> ПолноеИмяМД Тогда
НачальноеЗначениеВыбора = Неопределено;
КонецЕсли;
ТекущаяСтрока = Неопределено;
Отбор = Неопределено;
Если НачальноеЗначениеВыбора <> Неопределено Тогда
ИмяXMLТипа = СериализаторXDTO.XMLТип(ТипНачальногоЗначенияВыбора).ИмяТипа;
Если Ложь
Или Найти(ИмяXMLТипа, "Ref.") > 0
Или Найти(ИмяXMLТипа, "RecordKey.") > 0
Тогда
ТекущаяСтрока = НачальноеЗначениеВыбора;
Иначе
Отбор = НачальноеЗначениеВыбора.Методы.Отбор;
КонецЕсли;
КонецЕсли;
ФормаВыбора = ОткрытьФормуСпискаЛкс(ПолноеИмяМД, Отбор, ИспользоватьДинамическийСписокИР, ВладелецФормы, Истина, Истина, ТекущаяСтрока);
Возврат ФормаВыбора;
КонецФункции
Функция ПолучитьФормуВыбораОбъектаМетаданныхЛкс(Знач ВладелецФормы, Знач КлючУникальности, Знач НачальноеЗначениеВыбора, МножественныйВыбор = Ложь, ОтображатьСсылочныеОбъекты = Ложь,
ОтображатьВыборочныеТаблицы = Ложь, ОтображатьРегистры = Ложь, ОтображатьПоследовательности = Ложь, ОтображатьКонстанты = Ложь, ОтображатьТабличныеЧасти = Ложь,
ОтображатьТаблицыИзменений = Ложь, ОтображатьВнешниеИсточникиДанных = Ложь, ЗапретитьВыбиратьСсылочныеОбъекты = Ложь, ТолькоИспользованиеПолнотекстовогоПоиска = Ложь,
ОтображатьПеречисления = Ложь, Знач Фильтр = "", ОтображатьОбработки = Ложь, ОтображатьОтчеты = Ложь, ОтображатьПерерасчеты = Ложь) Экспорт
лСтруктураПараметров = ПараметрыВыбораОбъектаМетаданныхЛкс(ОтображатьСсылочныеОбъекты, ОтображатьВыборочныеТаблицы, ОтображатьРегистры, ОтображатьПоследовательности,
ОтображатьКонстанты, ОтображатьТабличныеЧасти, ОтображатьТаблицыИзменений, ОтображатьВнешниеИсточникиДанных, ЗапретитьВыбиратьСсылочныеОбъекты, ТолькоИспользованиеПолнотекстовогоПоиска,
ОтображатьПеречисления, ОтображатьОбработки, ОтображатьОтчеты, ОтображатьПерерасчеты, МножественныйВыбор);
Форма = ПолучитьФормуВыбораОбъектаМетаданныхСтруктуройЛкс(ВладелецФормы, КлючУникальности, НачальноеЗначениеВыбора, лСтруктураПараметров, Фильтр);
Возврат Форма;
КонецФункции
Функция ПолучитьФормуВыбораОбъектаМетаданныхСтруктуройЛкс(Знач ВладелецФормы, Знач КлючУникальности, Знач НачальноеЗначениеВыбора, Знач лСтруктураПараметров, Знач Фильтр = "") Экспорт
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", ВладелецФормы, КлючУникальности);
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора);
лСтруктураПараметров.Вставить("Фильтр", Фильтр);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
Возврат Форма;
КонецФункции
Функция ПараметрыВыбораОбъектаМетаданныхЛкс(ОтображатьСсылочныеОбъекты = Ложь, ОтображатьВыборочныеТаблицы = Ложь, ОтображатьРегистры = Ложь, ОтображатьПоследовательности = Ложь,
ОтображатьКонстанты = Ложь, ОтображатьТабличныеЧасти = Ложь, ОтображатьТаблицыИзменений = Ложь, ОтображатьВнешниеИсточникиДанных = Ложь, ЗапретитьВыбиратьСсылочныеОбъекты = Ложь,
ТолькоИспользованиеПолнотекстовогоПоиска = Ложь, ОтображатьПеречисления = Ложь, ОтображатьОбработки = Ложь, ОтображатьОтчеты = Ложь, ОтображатьПерерасчеты = Ложь, МножественныйВыбор = Ложь) Экспорт
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ОтображатьКонстанты", ОтображатьКонстанты);
лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", ОтображатьВыборочныеТаблицы);
лСтруктураПараметров.Вставить("ОтображатьТаблицыИзменений", ОтображатьТаблицыИзменений);
лСтруктураПараметров.Вставить("ОтображатьТабличныеЧасти", ОтображатьТабличныеЧасти);
лСтруктураПараметров.Вставить("ОтображатьРегистры", ОтображатьРегистры);
лСтруктураПараметров.Вставить("ОтображатьПерерасчеты", ОтображатьПерерасчеты);
лСтруктураПараметров.Вставить("ОтображатьПоследовательности", ОтображатьПоследовательности);
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", ОтображатьСсылочныеОбъекты);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", ОтображатьВнешниеИсточникиДанных);
лСтруктураПараметров.Вставить("ОтображатьПеречисления", ОтображатьПеречисления);
лСтруктураПараметров.Вставить("ОтображатьОбработки", ОтображатьОбработки);
лСтруктураПараметров.Вставить("ОтображатьОтчеты", ОтображатьОтчеты);
лСтруктураПараметров.Вставить("ТолькоИспользованиеПолнотекстовогоПоиска", ТолькоИспользованиеПолнотекстовогоПоиска);
лСтруктураПараметров.Вставить("ЗапретитьВыбиратьСсылочныеОбъекты", ЗапретитьВыбиратьСсылочныеОбъекты);
лСтруктураПараметров.Вставить("МножественныйВыбор", МножественныйВыбор);
Возврат лСтруктураПараметров;
КонецФункции
Процедура ОбъектМетаданныхНачалоВыбораЛкс(Знач Элемент, Знач ПараметрыВыбораОбъектаМетаданных, СтандартнаяОбработка) Экспорт
СтандартнаяОбработка = Ложь;
ФормаВыбора = ПолучитьФормуВыбораОбъектаМетаданныхСтруктуройЛкс(,, ДанныеЭлементаФормыЛкс(Элемент), ПараметрыВыбораОбъектаМетаданных);
РезультатВыбора = ФормаВыбора.ОткрытьМодально();
Если РезультатВыбора <> Неопределено Тогда
ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, РезультатВыбора.ПолноеИмяОбъекта);
КонецЕсли;
КонецПроцедуры
Процедура ОбъектМетаданныхОкончаниеВводаТекстаЛкс(Знач Элемент, Знач ПараметрыВыбораОбъектаМетаданных, Текст, Значение, СтандартнаяОбработка) Экспорт
Если ЗначениеЗаполнено(Текст) Тогда
СтандартнаяОбработка = Ложь;
Значение = Новый СписокЗначений;
Если ирОбщий.ЛиТаблицаБДСуществуетЛкс(Текст) Тогда
Значение.Добавить(Текст);
Иначе
ФормаВыбора = ирОбщий.ПолучитьФормуВыбораОбъектаМетаданныхСтруктуройЛкс(Элемент,, ДанныеЭлементаФормыЛкс(Элемент), ПараметрыВыбораОбъектаМетаданных, Текст);
РезультатВыбора = ФормаВыбора.ОткрытьМодально();
Если РезультатВыбора <> Неопределено Тогда
Значение.Добавить(РезультатВыбора.ПолноеИмяОбъекта);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьФормуВыбораТаблицыСтруктурыБДЛкс(ЛиИменаБД, ИмяТаблицыХранения = "") Экспорт
Форма = ирОбщий.ПолучитьФормуЛкс("Обработка.ирСтруктураХраненияБД.Форма",,, Истина);
Форма.РежимВыбора = Истина;
Форма.ПараметрИмяТаблицыХранения = ИмяТаблицыХранения;
Форма.ПараметрПоказыватьSDBL = Не ЛиИменаБД;
Форма.ПараметрПоказыватьСУБД = ЛиИменаБД;
Возврат Форма
КонецФункции
Функция РедактироватьАлгоритмЧерезСтрокуXMLЛкс(СтрокаXMLАлгоритма, ВнешниеПараметры = Неопределено, НаСервере = Ложь, ИмяАлгоритма = "") Экспорт
СтруктураАлгоритма = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаXMLАлгоритма);
Результат = РедактироватьАлгоритмЧерезСтруктуруЛкс(СтруктураАлгоритма, ВнешниеПараметры,, НаСервере, ИмяАлгоритма);
Если Результат Тогда
СтрокаXMLАлгоритма = ирОбщий.СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураАлгоритма);
КонецЕсли;
Возврат Результат;
КонецФункции
// Открыть редактирование текста алгоритма с параметрами в консоли кода
// Парамерты:
// СтруктураАлгоритма - Структура - возвращаемый
// "ТекстАлгоритма" - Строка - текст алгоритма,
// "ВнутренниеПараметры" - ТаблицаЗначений - таблица с конструктором НоваяТаблицаПараметровАлгоритмаЛкс с внутренними (значения определяются при редактировании) параметрами алгоритма;
// ВнешниеПараметры* - ТаблицаЗначений - таблица с конструктором НоваяТаблицаПараметровАлгоритмаЛкс с внешними (значения определяются при каждом выполнении) параметрами алгоритма;
// Методы* - ТаблицаЗначений - таблица с конструктором НоваяТаблицаМетодовПодсказкиЛкс с дополнительными методами доступными в алгоритме;
// Результат - Булево - принял ли изменения пользователь
Функция РедактироватьАлгоритмЧерезСтруктуруЛкс(СтруктураАлгоритма, ВнешниеПараметры = Неопределено, Методы = Неопределено, НаСервере = Ложь, ИмяАлгоритма = "") Экспорт
#Если Сервер И Не Сервер Тогда
ВнешниеПараметры = Новый ТаблицаЗначений;
#КонецЕсли
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ОбработкаКонсольКода = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольКода");
ФормаКонсоли = ОбработкаКонсольКода.ПолучитьФорму();
Если ВнешниеПараметры <> Неопределено Тогда
КопияПараметров = ВнешниеПараметры.Скопировать();
Если КопияПараметров.Колонки.Найти("ТаблицаСтруктурТипов") = Неопределено Тогда
КопияПараметров.Колонки.Добавить("ТаблицаСтруктурТипов");
КонецЕсли;
Если КопияПараметров.Колонки.Найти("Значение") = Неопределено Тогда
КопияПараметров.Колонки.Добавить("Значение");
КонецЕсли;
Если КопияПараметров.Колонки.Найти("Фиксированный") = Неопределено Тогда
КопияПараметров.Колонки.Добавить("Фиксированный");
КонецЕсли;
Для Каждого СтрокаПараметра Из КопияПараметров Цикл
Если Истина
И ТипЗнч(СтрокаПараметра.ТипЗначения) = Тип("ОписаниеТипов")
И СтрокаПараметра.ТаблицаСтруктурТипов = Неопределено
Тогда
СтрокаПараметра.ТаблицаСтруктурТипов = мПлатформа.ПолучитьТаблицуСтруктурТиповИзОписанияТипов(СтрокаПараметра.ТипЗначения);
КонецЕсли;
КонецЦикла;
КопияПараметров.ЗаполнитьЗначения(Истина, "Фиксированный");
ФормаКонсоли.мСписокВнешнихПараметров = КопияПараметров;
КонецЕсли;
Если СтруктураАлгоритма <> Неопределено Тогда
Если СтруктураАлгоритма.Свойство("ТекстАлгоритма") Тогда
ФормаКонсоли.ПараметрТекст = СтруктураАлгоритма.ТекстАлгоритма;
КонецЕсли;
Если СтруктураАлгоритма.Свойство("ВнутренниеПараметры") Тогда
ЗагрузитьВТаблицуЗначенийЛкс(СтруктураАлгоритма.ВнутренниеПараметры, КопияПараметров, Новый Структура("Вход", Истина));
КонецЕсли;
КонецЕсли;
ФормаКонсоли.ПараметрНаСервере = НаСервере;
ФормаКонсоли.мМетоды = Методы;
ФормаКонсоли.мРежимРедактора = Истина;
ФормаКонсоли.мИмяАлгоритмаДляРедактора = ИмяАлгоритма;
ФормаКонсоли.ОткрытьМодально();
РезультатФормы = ФормаКонсоли.РезультатФормы;
Результат = РезультатФормы <> Неопределено;
Если Результат Тогда
ВнутренниеПараметры = РезультатФормы.Параметры.Скопировать(Новый Структура("Вход, Фиксированный", Истина, Ложь), "Имя, Значение");
СтруктураАлгоритма = Новый Структура("ТекстАлгоритма, ВнутренниеПараметры", РезультатФормы.Текст, ВнутренниеПараметры);
КонецЕсли;
Возврат Результат;
КонецФункции
// Конструктор таблицы параметров алгоритма
// Результат - ТаблицаЗначений - колонки "Имя, Значение, Вход, Выход, ТипЗначения, Комментарий"
Функция НоваяТаблицаПараметровАлгоритмаЛкс() Экспорт
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("Значение");
Результат.Колонки.Добавить("Вход", Новый ОписаниеТипов("Булево"));
Результат.Колонки.Добавить("Выход", Новый ОписаниеТипов("Булево"));
Результат.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("ОписаниеТипов"));
Результат.Колонки.Добавить("Комментарий", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("ТаблицаСтруктурТипов");
Возврат Результат;
КонецФункции
// Конструктор таблицы методов контекстной подсказки
// Результат - ТаблицаЗначений - колонки "Имя, ТипЗначения"
Функция НоваяТаблицаМетодовПодсказкиЛкс() Экспорт
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("ОписаниеТипов"));
Результат.Колонки.Добавить("ТаблицаСтруктурТипов");
Возврат Результат;
КонецФункции
Функция СтрокаСобытияАлгоритмНачалоВыбораЛкс(Знач СтрокаСобытия, НаСервере = Ложь) Экспорт
АлгоритмИзменен = РедактироватьАлгоритмЧерезСтрокуXMLЛкс(СтрокаСобытия.Алгоритм, СтрокаСобытия.Параметры, НаСервере, СтрокаСобытия.СинонимСобытия);
Если СтрокаСобытия.Параметры.Колонки.Найти("Значение") <> Неопределено Тогда
СтрокаСобытия.Параметры.ЗаполнитьЗначения(, "Значение");
КонецЕсли;
Если СтрокаСобытия.Владелец().Колонки.Найти("АлгоритмОбъект") <> Неопределено Тогда
СтрокаСобытия.АлгоритмОбъект = Неопределено;
КонецЕсли;
Если СтрокаСобытия.Владелец().Колонки.Найти("ТаблицаСтруктурТипов") <> Неопределено Тогда
СтрокаСобытия.Параметры.ЗаполнитьЗначения(Неопределено, "ТаблицаСтруктурТипов");
КонецЕсли;
Возврат АлгоритмИзменен;
КонецФункции
Процедура ОформитьЯчейкуАлгоритмаВТабличномПолеЛкс(Знач ОформлениеСтроки, ИмяКолонки = "Алгоритм") Экспорт
Если ЗначениеЗаполнено(ОформлениеСтроки.ДанныеСтроки[ИмяКолонки]) Тогда
СтруктураАлгоритма = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(ОформлениеСтроки.ДанныеСтроки[ИмяКолонки],,, Ложь);
Если СтруктураАлгоритма <> Неопределено И СтруктураАлгоритма.Свойство("ТекстАлгоритма") Тогда
ОформлениеСтроки.Ячейки[ИмяКолонки].УстановитьТекст(СокрП(СтруктураАлгоритма.ТекстАлгоритма));
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// ИсторияФайлов - СписокЗначений
// Кнопки - КнопкиКоманднойПанели
Процедура ОбновитьПодменюИсторииФайловЛкс(ИсторияФайлов, Кнопки, ИмяДействия = "ОткрытьФайлИзИстории") Экспорт
Кнопки.Очистить();
ДлинаПредставления = 100;
ДействиеКнопки = Новый Действие(ИмяДействия);
Для Каждого СтрокаФайла Из ИсторияФайлов Цикл
Файл = Новый Файл(СтрокаФайла.Значение);
ДлинаПути = ДлинаПредставления - СтрДлина(Файл.Имя);
Представление = Лев(Файл.Имя, ДлинаПредставления);
Если ДлинаПути > 0 Тогда
Если ДлинаПути < СтрДлина(Файл.Путь) + 3 Тогда
Представление = Лев(Файл.Путь, ДлинаПути) + "...\" + Представление;
Иначе
Представление = Файл.Путь + Представление;
КонецЕсли;
КонецЕсли;
КнопкаФайла = Кнопки.Добавить("_" + Формат(ИсторияФайлов.Индекс(СтрокаФайла), "ЧГ=;ЧН="), ТипКнопкиКоманднойПанели.Действие, Представление, ДействиеКнопки);
КонецЦикла;
КонецПроцедуры
Процедура ДобавитьВИсториюЭлементЛкс(СписокИстории, ЗначениеЭлемента, РазмерИстории = 20) Экспорт
ЭлементИстории = СписокИстории.НайтиПоЗначению(ЗначениеЭлемента);
Если ЭлементИстории <> Неопределено Тогда
СписокИстории.Удалить(ЭлементИстории);
КонецЕсли;
СписокИстории.Вставить(0, ЗначениеЭлемента);
Пока СписокИстории.Количество() > РазмерИстории Цикл
СписокИстории.Удалить(РазмерИстории);
КонецЦикла;
КонецПроцедуры
Процедура УстановитьДоступностьПодменюЛкс(Знач Подменю, НоваяДоступность = Ложь) Экспорт
Для Каждого Кнопка Из Подменю.Кнопки Цикл
Кнопка.Доступность = НоваяДоступность;
КонецЦикла;
КонецПроцедуры
Процедура ПоместитьТекстВБуферОбменаОСЛкс(Знач Текст, ВариантПросмотра = "ВстроенныйЯзык") Экспорт
// http://partners.v8.1c.ru/forum/thread.jsp?id=1075241#1075241
Попытка
//Документ = ирКэш.Получить().СлужебноеПолеHtmlДокумента.Документ; // Так выбрасывается исключение после нескольких вызовов и сразу на 8.3.14+
Документ = Новый COMОбъект("HTMLFILE"); // 10мс
Окно = Документ.parentWindow;
Окно.ClipboardData.SetData("Text", Текст);
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
КонецПопытки;
Если ПолучитьТекстИзБуфераОбменаОСЛкс() <> Текст Тогда
ОткрытьТекстЛкс(Текст,, ВариантПросмотра,,,, Истина);
КонецЕсли;
Конецпроцедуры
Функция ПолучитьТекстИзБуфераОбменаОСЛкс() Экспорт
// http://partners.v8.1c.ru/forum/thread.jsp?id=1075241#1075241
Попытка
//Документ = ирКэш.Получить().СлужебноеПолеHtmlДокумента.Документ; // Так выбрасывается исключение после нескольких вызовов и сразу на 8.3.14+
Документ = Новый COMОбъект("HTMLFILE"); // 10мс
Окно = Документ.parentWindow;
Результат = "" + Окно.ClipboardData.GetData("Text"); // Похоже здесь может вернуться не строка
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
Результат = "";
КонецПопытки;
Возврат Результат;
КонецФункции
// Параметры:
// Отбор - Структура, Отбор, *Неопределено
Функция ОткрытьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено, ВладелецФормы = Неопределено, РежимВыбора = Ложь,
МножественныйВыбор = Ложь, ТекущаяСтрока = Неопределено, Модально = Ложь, ПользовательскийОтбор = Неопределено, ТекущаяКолонка = Неопределено) Экспорт
ФормаСписка = ПолучитьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор, ИспользоватьДинамическийСписокИР, ВладелецФормы, РежимВыбора, МножественныйВыбор, ТекущаяСтрока, ПользовательскийОтбор,,
ТекущаяКолонка);
Если ФормаСписка = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если Модально Тогда
Если ФормаСписка.Открыта() Тогда
ФормаСписка = ПолучитьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор, ИспользоватьДинамическийСписокИР, ВладелецФормы, РежимВыбора, МножественныйВыбор, ТекущаяСтрока, ПользовательскийОтбор,
Новый УникальныйИдентификатор, ТекущаяКолонка);
КонецЕсли;
Результат = ФормаСписка.ОткрытьМодально();
Возврат Результат;
Иначе
ФормаСписка.Открыть();
Возврат ФормаСписка;
КонецЕсли;
КонецФункции
// Параметры:
// Отбор - Структура, Отбор, *Неопределено
Функция ПолучитьФормуСпискаЛкс(Знач ИмяТаблицыИлиМДИлиТип, Знач Отбор = Неопределено, Знач ИспользоватьДинамическийСписокИР = Неопределено, Знач ВладелецФормы = Неопределено, Знач РежимВыбора = Ложь,
Знач МножественныйВыбор = Ложь, Знач ТекущаяСтрока = Неопределено, Знач ПользовательскийОтбор = Неопределено, Знач КлючУникальности = Неопределено, Знач ТекущаяКолонка = Неопределено) Экспорт
мПлатформа = ирКэш.Получить();
Если ТипЗнч(ИмяТаблицыИлиМДИлиТип) = Тип("ОбъектМетаданных") Тогда
ИмяТаблицы = ИмяТаблицыИлиМДИлиТип.ПолноеИмя();
ИначеЕсли ТипЗнч(ИмяТаблицыИлиМДИлиТип) = Тип("Тип") Тогда
ИмяТаблицы = ПолучитьПолноеИмяМДТипаЛкс(ИмяТаблицыИлиМДИлиТип);
Иначе
ИмяТаблицы = ИмяТаблицыИлиМДИлиТип;
КонецЕсли;
ТипТаблицы = ТипТаблицыБДЛкс(ИмяТаблицы);
//МассивФрагментов = СтрРазделитьЛкс(ПолноеИмяМД);
Если Ложь
Или ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы)
Или ТипТаблицы = "Изменения"
Или ТипТаблицы = "Перерасчет"
//Или МассивФрагментов.Количество() > 2
Тогда
СообщитьЛкс("Для таблицы """ + ИмяТаблицы + """ динамический список не предусмотрен");
ФормаСписка = ирОбщий.ПолучитьФормуЛкс("Обработка.ирПодборИОбработкаОбъектов.Форма",,, ИмяТаблицы);
Возврат ФормаСписка;
КонецЕсли;
Если ИспользоватьДинамическийСписокИР = Неопределено Тогда
ИспользоватьДинамическийСписокИР = ПолучитьИспользованиеДинамическогоСпискаВместоОсновнойФормыЛкс(ИмяТаблицы);
КонецЕсли;
Если Истина
И РежимВыбора = Истина
И ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы)
Тогда
ИспользоватьДинамическийСписокИР = Истина; // Потому что у форм списков регистров режим выбора можно включить только через основной элемент управления
КонецЕсли;
Если ТипТаблицы = "Точки" Тогда
ИспользоватьДинамическийСписокИР = Истина;
КонецЕсли;
Если ИспользоватьДинамическийСписокИР = Неопределено Тогда
Ответ = Вопрос("Хотите использовать Динамический список (ИР)?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет);
ИспользоватьДинамическийСписокИР = Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если ПользовательскийОтбор <> Неопределено Тогда
ПользовательскиеНастройки = Новый ПользовательскиеНастройкиКомпоновкиДанных;
ПользовательскийОтборКомпоновки = ПользовательскиеНастройки.Элементы.Добавить(Тип("ОтборКомпоновкиДанных"));
Если ТипЗнч(ПользовательскийОтбор) = Тип("Отбор") Тогда
Для Каждого ЭлементОтбора Из ПользовательскийОтбор Цикл
Если ЭлементОтбора.Использование Тогда
СтрокаВидаСравнения = мПлатформа.СоответствиеВидовСравнения.Найти(ЭлементОтбора.ВидСравнения, "Построитель");
Если СтрокаВидаСравнения = Неопределено Тогда
// %%%% Здесь можно добавить интеллекта
Продолжить;
КонецЕсли;
ЭлементОтбора = НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ПользовательскийОтборКомпоновки, ЭлементОтбора.Имя, ЭлементОтбора.Значение, СтрокаВидаСравнения.Компоновка);
ПроверитьВключитьЭлементНастроекКомпоновкиВПользовательскиеНастройки(ЭлементОтбора);
КонецЕсли;
КонецЦикла;
Иначе
СкопироватьОтборЛюбойЛкс(ПользовательскийОтборКомпоновки, ПользовательскийОтбор);
КонецЕсли;
// Важно: установка идентификатора должна выполняться в конце настройки элемента,
// иначе он будет скопирован в пользовательские настройки частично заполненным.
// Идентификатор установлен экспериментально https://partners.v8.1c.ru/forum/t/1644571/m/1644571, также подтвержден тут http://forum.infostart.ru/forum9/topic163501/message2246750/#message2246750
ПроверитьВключитьЭлементНастроекКомпоновкиВПользовательскиеНастройки(ПользовательскийОтборКомпоновки, "dfcece9d-5077-440b-b6b3-45a5cb4538eb");
КонецЕсли;
Если ТипЗнч(Отбор) = Тип("Отбор") Тогда
СтруктураОтбора = Новый Структура;
Для Каждого ЭлементОтбора Из Отбор Цикл
Если ЭлементОтбора.Использование Тогда
Если ЭлементОтбора.ВидСравнения = ВидСравнения.Равно Тогда
СтруктураОтбора.Вставить(ЭлементОтбора.Имя, ЭлементОтбора.Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе
СтруктураОтбора = Отбор;
КонецЕсли;
ПараметрыФормы = Новый Структура("РежимВыбора, МножественныйВыбор, ЗакрыватьПриВыборе, ТекущаяСтрока, Отбор, ПользовательскиеНастройки, ТекущаяКолонка",
РежимВыбора, МножественныйВыбор, Не МножественныйВыбор, ТекущаяСтрока, СтруктураОтбора, ПользовательскиеНастройки, ТекущаяКолонка);
МожноИспользоватьДинамическийСписокИР = Истина;
#Если ТолстыйКлиентОбычноеПриложение Тогда
МожноИспользоватьДинамическийСписокИР = Ложь
Или ТипТаблицы <> "Внешняя"
Или Не ирКэш.ЛиПортативныйРежимЛкс();
#КонецЕсли
Если Истина
И ИспользоватьДинамическийСписокИР
И МожноИспользоватьДинамическийСписокИР
Тогда
КлючУникальности = КлючУникальностиДинамическогоСпискаЛкс(ИмяТаблицы, КлючУникальности);
ПараметрыФормы.Вставить("ИмяТаблицы", ИмяТаблицы);
//Если Не РежимВыбора Тогда
// КлючУникальности = Новый УникальныйИдентификатор;
//КонецЕсли;
ИмяФормы = "Обработка.ирДинамическийСписок.Форма";
Если Не ирКэш.ЛиПортативныйРежимЛкс() И ТипТаблицы = "Внешняя" Тогда
ИмяФормы = ИмяФормы + ".ФормаУпр";
КонецЕсли;
ФормаСписка = ПолучитьФормуЛкс(ИмяФормы, ПараметрыФормы, ВладелецФормы, КлючУникальности);
ФормаСписка.РежимВыбора = РежимВыбора; // Чтобы заголовок сразу правильный сформировался
ФормаСписка.УстановитьОбъектМетаданных(ИмяТаблицы);
ОтборДинамическогоСписка = ФормаСписка.Отбор();
ПользовательскийОтборДинамическогоСписка = ФормаСписка.ПользовательскийОтбор();
Иначе
Если РежимВыбора Тогда
Попытка
ФормаСписка = ПолучитьФормуЛкс(ИмяТаблицы + ".ФормаВыбора", ПараметрыФормы, ВладелецФормы, КлючУникальности);
Исключение
// Например у регистров нет форм выбора
КонецПопытки;
КонецЕсли;
Если ФормаСписка = Неопределено Тогда
ФормаСписка = ПолучитьФормуЛкс(ИмяТаблицы + ".ФормаСписка", ПараметрыФормы, ВладелецФормы, КлючУникальности);
КонецЕсли;
Если ТипЗнч(ФормаСписка) = Тип("Форма") Тогда
Попытка
ОтборДинамическогоСписка = ФормаСписка.Отбор;
Исключение
КонецПопытки;
ПользовательскийОтборДинамическогоСписка = ОтборДинамическогоСписка;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ФормаСписка) = Тип("Форма") Тогда
ФормаСписка.РежимВыбора = РежимВыбора;
ФормаСписка.ЗакрыватьПриВыборе = Не МножественныйВыбор;
ФормаСписка.НачальноеЗначениеВыбора = ТекущаяСтрока;
Попытка
ФормаСписка.МножественныйВыбор = МножественныйВыбор;
Исключение
// Есть не у всех форм
КонецПопытки;
Попытка
ФормаСписка.ПараметрТекущаяСтрока = ТекущаяСтрока;
Исключение
// Есть не у всех форм
КонецПопытки;
Попытка
ФормаСписка.ПараметрТекущаяКолонка = ТекущаяКолонка;
Исключение
// Есть не у всех форм
КонецПопытки;
КонецЕсли;
Если Истина
И ОтборДинамическогоСписка <> Неопределено
И Отбор <> Неопределено
Тогда
СкопироватьОтборЛюбойЛкс(ОтборДинамическогоСписка, Отбор);
КонецЕсли;
Если Истина
И ПользовательскийОтборДинамическогоСписка <> Неопределено
И ПользовательскийОтбор <> Неопределено
Тогда
СкопироватьОтборЛюбойЛкс(ПользовательскийОтборДинамическогоСписка, ПользовательскийОтбор);
КонецЕсли;
Возврат ФормаСписка;
КонецФункции
Функция КлючУникальностиДинамическогоСпискаЛкс(Знач ИмяТаблицы, Знач КлючУникальности = "") Экспорт
КлючУникальности = ИмяТаблицы + ";" + КлючУникальности;
Возврат КлючУникальности;
КонецФункции
Процедура ПолеФайловогоКаталога_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка) Экспорт
СтандартнаяОбработка = Ложь;
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
ВыборФайла.Каталог = Элемент.Значение;
Если Не ВыборФайла.Выбрать() Тогда
Возврат;
КонецЕсли;
ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, ВыборФайла.Каталог);
КонецПроцедуры
Функция ОткрытьСсылкуВСпискеЛкс(Ссылка) Экспорт
ПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)).ПолноеИмя();
СтруктураПараметры = Новый Структура;
СтруктураПараметры.Вставить("ТекущаяСтрока", Ссылка);
ФормаСписка = ПолучитьФормуЛкс(ПолноеИмяМД + ".ФормаСписка", СтруктураПараметры, , Новый УникальныйИдентификатор);
ФормаСписка.Открыть();
Возврат ФормаСписка;
КонецФункции
// ИменаКолонок - Строка - имена колонок через запятую
Процедура ТабличноеПолеОтобразитьФлажкиЛкс(ОформлениеСтроки, Знач ИменаКолонок) Экспорт
Если ТипЗнч(ИменаКолонок) = Тип("Строка") Тогда
ИменаКолонок = СтрРазделитьЛкс(ИменаКолонок, ",", Истина);
КонецЕсли;
Для Каждого ИмяКолонки Из ИменаКолонок Цикл
Ячейка = ОформлениеСтроки.Ячейки[ИмяКолонки];
//Если Ячейка.ТолькоПросмотр Тогда
// Продолжить;
//КонецЕсли;
Если ТипЗнч(Ячейка.Значение) = Тип("Булево") Тогда
Ячейка.УстановитьФлажок(Ячейка.Значение);
Ячейка.УстановитьТекст("");
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ТабличноеПолеПриИзмененииФлажкаЛкс(ТабличноеПоле, Знач Колонка) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
Если ТипЗнч(Колонка.ЭлементУправления) = Тип("ПолеВвода") Тогда
ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(ТабличноеПоле.ТекущаяСтрока);
Ячейка = ОформлениеСтроки.Ячейки[Колонка.Имя];
Если Не Ячейка.ТолькоПросмотр Тогда
Если Истина
И Колонка.Данные = ""
И Колонка.ДанныеФлажка = ""
Тогда
Колонка.ЭлементУправления.Значение = Не Ячейка.Значение;
//ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(Элемент, Колонка, Не ОформлениеСтроки.Ячейки[Колонка.Имя].Значение);
Иначе
//МетаданныеТипа = глПолучитьМетаданныеТипа(ТипЗнч(Элемент.Значение), "ТипСписка", Истина);
//РедактированиеВДиалоге = Ложь;
//Если Истина
// И МетаданныеТипа <> Неопределено
// И МетаданныеТипа.КлассМетаданных.Предок = оСсылочный
//Тогда
// Попытка
// ВыбранныйСпособРедактирования = Элемент.СпособРедактирования;
// Исключение
// КонецПопытки;
// РедактированиеВДиалоге = ВыбранныйСпособРедактирования <> СпособРедактированияСписка.ВСписке;
//КонецЕсли;
//РазрешитьИзменение = Истина;
//Если РедактированиеВДиалоге Тогда
//Иначе
//Элемент.ЗакончитьРедактированиеСтроки(Ложь);
ТабличноеПоле.ИзменитьСтроку();
ЗначениеЯчейки = Колонка.ЭлементУправления.Значение;
Если ТипЗнч(ЗначениеЯчейки) = Тип("Булево") Тогда
//ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(Элемент, Колонка, Не ЗначениеЯчейки, , , Ложь); // Так возникает рассогласование флажка и данных в колонке формы ИсследовательКоллекций
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, Не ЗначениеЯчейки, , , Ложь, Ложь);
//Элемент.ТекущаяКолонка = Колонка;
КонецЕсли;
ТабличноеПоле.ЗакончитьРедактированиеСтроки(Ложь);
//КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция СоздатьМенеджерСохраненияНастроекФормыЛкс(ЭтаФорма, КлючНазначенияИспользования = "", Знач ЗагружатьСохранятьНастройкуПоУмолчанию = Истина, ПараметрыЗагрузкиНастройкиПоУмолчанию = Неопределено,
РасширениеФайла = "", СоставНастройкиФормы = Неопределено) Экспорт
СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
#Если Сервер И Не Сервер Тогда
СлужебныеДанныеФормы = Новый Структура;
#КонецЕсли
МенеджерСохраненияНастроек = Новый Структура("СохраненныеНастройки, ПоследняяНастройка, КлючНастроек, ЗагружатьСохранятьНастройкуПоУмолчанию, РасширениеФайла, СоставНастройкиФормы");
МенеджерСохраненияНастроек.КлючНастроек = КлючХраненияНастроекФормыЛкс(ЭтаФорма) + ".Настройки";
МенеджерСохраненияНастроек.ЗагружатьСохранятьНастройкуПоУмолчанию = ЗагружатьСохранятьНастройкуПоУмолчанию;
МенеджерСохраненияНастроек.РасширениеФайла = РасширениеФайла;
МенеджерСохраненияНастроек.СоставНастройкиФормы = СоставНастройкиФормы;
Если ЗначениеЗаполнено(КлючНазначенияИспользования) Тогда
МенеджерСохраненияНастроек.КлючНастроек = МенеджерСохраненияНастроек.КлючНастроек + "." + КлючНазначенияИспользования;
КонецЕсли;
СохраненныеНастройкиНовые = Новый ТаблицаЗначений;
СохраненныеНастройкиНовые.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
СохраненныеНастройкиНовые.Колонки.Добавить("Значение");
СохраненныеНастройкиНовые.Колонки.Добавить("Пометка", Новый ОписаниеТипов("Булево"));
СохраненныеНастройкиНовые.Колонки.Добавить("ДатаИзменения", Новый ОписаниеТипов("Дата"));
СчитанныеСохраненныеНастройки = ирОбщий.ВосстановитьЗначениеЛкс(МенеджерСохраненияНастроек.КлючНастроек);
Если СчитанныеСохраненныеНастройки = Неопределено Тогда
СтарыйКлючХранения = КлючХраненияНастроекФормыЛкс(ЭтаФорма) + ".СохраненныеНастройки";
СчитанныеСохраненныеНастройки = ирОбщий.ВосстановитьЗначениеЛкс(СтарыйКлючХранения);
Если СчитанныеСохраненныеНастройки <> Неопределено Тогда
УдалитьХранимуюНастройкуЛкс(СтарыйКлючХранения);
КонецЕсли;
КонецЕсли;
Если ТипЗнч(СчитанныеСохраненныеНастройки) = Тип("ТаблицаЗначений") Тогда
Для Каждого СтрокаСтаройНастройки Из СчитанныеСохраненныеНастройки Цикл
Если СтрокаСтаройНастройки.Значение <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СохраненныеНастройкиНовые.Добавить(), СтрокаСтаройНастройки);
КонецЕсли;
КонецЦикла;
КонецЕсли;
МенеджерСохраненияНастроек.СохраненныеНастройки = СохраненныеНастройкиНовые;
СлужебныеДанныеФормы.МенеджерСохраненияНастроек = МенеджерСохраненияНастроек;
Попытка
ЗагрузитьНастройкуФормыПоУмолчаниюЛкс(ЭтаФорма, Не ЗагружатьСохранятьНастройкуПоУмолчанию, ПараметрыЗагрузкиНастройкиПоУмолчанию);
Исключение
СообщитьЛкс(ОписаниеОшибки(), СтатусСообщения.Внимание);
Ответ = Вопрос("При загрузке последней настройки """ + ПервыйФрагментЛкс(ЭтаФорма.Заголовок, ":") + """ возникла ошибка. Хотите загрузить пустую настройку?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
ЗагрузитьНастройкуФормыПоУмолчаниюЛкс(ЭтаФорма, Истина, ПараметрыЗагрузкиНастройкиПоУмолчанию);
Иначе
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
КонецФункции
Процедура ЗагрузитьНастройкуФормыПоУмолчаниюЛкс(Знач ЭтаФорма, Знач ЗагрузитьПустуюНастройку = Ложь, Знач ПараметрыЗагрузкиНастройкиПоУмолчанию = Неопределено) Экспорт
Если ЗагрузитьПустуюНастройку Тогда
НастройкаФормы = Неопределено;
Иначе
МенеджерСохраненияНастроек = СлужебныеДанныеФормыЛкс(ЭтаФорма).МенеджерСохраненияНастроек;
НастройкаПоУмолчанию = ПолучитьНастройкуПоУмолчаниюИзСпискаСохраненныхНастроекЛкс(МенеджерСохраненияНастроек.СохраненныеНастройки);
Если НастройкаПоУмолчанию.Значение = Неопределено Тогда
СохранитьНастройкуФормыЛкс(ЭтаФорма);
НастройкаПоУмолчанию = ПолучитьНастройкуПоУмолчаниюИзСпискаСохраненныхНастроекЛкс(МенеджерСохраненияНастроек.СохраненныеНастройки);
КонецЕсли;
НастройкаФормы = НастройкаПоУмолчанию.Значение;
КонецЕсли;
//ПоследняяНастройка = МенеджерСохраненияНастроек.СохраненныеНастройки.Индекс(НастройкаПоУмолчанию);
ЗагрузитьНастройкуФормыЧерезОбработчикЛкс(ЭтаФорма, НастройкаФормы, ПараметрыЗагрузкиНастройкиПоУмолчанию);
КонецПроцедуры
Процедура ЗагрузитьНастройкуФормыЧерезОбработчикЛкс(Знач ЭтаФорма, Знач НастройкаФормы, Знач ПараметрыЗагрузкиНастройкиПоУмолчанию = Неопределено) Экспорт
Если ПараметрыЗагрузкиНастройкиПоУмолчанию = Неопределено Тогда
ПараметрыЗагрузкиНастройкиПоУмолчанию = Новый Структура;
КонецЕсли;
Если ЭтаФорма.ВводДоступен() Тогда
МенеджерСохраненияНастроек = СлужебныеДанныеФормыЛкс(ЭтаФорма).МенеджерСохраненияНастроек;
СоставНастройкиФормы = МенеджерСохраненияНастроек.СоставНастройкиФормы;
Если СоставНастройкиФормы <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
СоставНастройкиФормы = Новый СписокЗначений;
#КонецЕсли
Если Не СоставНастройкиФормы.ОтметитьЭлементы("Выберите состав загружаемой настройки") Тогда
Возврат;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ПараметрыЗагрузкиНастройкиПоУмолчанию.Вставить("СоставНастройкиФормы", СоставНастройкиФормы);
Если МетодРеализованЛкс(ЭтаФорма, "ЗагрузитьНастройкуВФорме") Тогда
ЭтаФорма.ЗагрузитьНастройкуВФорме(НастройкаФормы, ПараметрыЗагрузкиНастройкиПоУмолчанию);
Иначе
ЗагрузитьНастройкуФормыЛкс(ЭтаФорма, НастройкаФормы);
КонецЕсли;
КонецПроцедуры
Процедура ЗагрузитьНастройкуФормыЛкс(Знач ЭтаФорма, Знач НастройкаФормы, БелыеСвойства = Неопределено, ЧерныеСвойства = Неопределено, ЗагружатьОстальные = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
БелыеСвойства = Новый Структура;
ЧерныеСвойства = Новый Структура;
#КонецЕсли
Если НастройкаФормы = Неопределено Тогда
Возврат;
КонецЕсли;
//ЗаполнитьЗначенияСвойств(ЭтаФорма, НастройкаФормы);
Для Каждого КлючИЗначение Из НастройкаФормы Цикл
Если Ложь
Или Не ЕстьСвойствоОбъектаЛкс(ЭтаФорма, КлючИЗначение.Ключ)
Или (Истина
И ЧерныеСвойства <> Неопределено
И ЧерныеСвойства.Свойство(КлючИЗначение.Ключ))
Или (Истина
И БелыеСвойства <> Неопределено
И Не БелыеСвойства.Свойство(КлючИЗначение.Ключ)
И Не ЗагружатьОстальные)
Тогда
Продолжить;
КонецЕсли;
ТипЗначения = ТипЗнч(ЭтаФорма[КлючИЗначение.Ключ]);
Если ЛиТипЗначенияТабличнойЧастиЛкс(ТипЗначения) Тогда
ЭтаФорма[КлючИЗначение.Ключ].Загрузить(КлючИЗначение.Значение);
ИначеЕсли ТипЗначения = Тип("КомпоновщикНастроекКомпоновкиДанных") Тогда
ЭтаФорма[КлючИЗначение.Ключ].ЗагрузитьНастройки(КлючИЗначение.Значение);
ИначеЕсли ТипЗначения = Тип("ТаблицаЗначений") Тогда
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(КлючИЗначение.Значение, ЭтаФорма[КлючИЗначение.Ключ],,, Истина);
ИначеЕсли ТипЗначения = Тип("ДеревоЗначений") Тогда
ирОбщий.ЗагрузитьВДеревоЗначенийЛкс(КлючИЗначение.Значение, ЭтаФорма[КлючИЗначение.Ключ],,, Истина);
Иначе
ЗначениеСвойства = КлючИЗначение.Значение;
ЗначениеСвойства = КопияОбъектаЛкс(ЗначениеСвойства);
ЭтаФорма[КлючИЗначение.Ключ] = ЗначениеСвойства;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура СохранитьНастройкуФормыЛкс(Знач ЭтаФорма) Экспорт
МенеджерСохраненияНастроек = СлужебныеДанныеФормыЛкс(ЭтаФорма).МенеджерСохраненияНастроек;
Если МенеджерСохраненияНастроек <> Неопределено И МенеджерСохраненияНастроек.ЗагружатьСохранятьНастройкуПоУмолчанию Тогда
НастройкаПоУмолчанию = ПолучитьНастройкуПоУмолчаниюИзСпискаСохраненныхНастроекЛкс(МенеджерСохраненияНастроек.СохраненныеНастройки);
НастройкаПоУмолчанию.Значение = СохраняемаяНастройкаФормыЛкс(ЭтаФорма);
СохранитьЗначениеЛкс(МенеджерСохраненияНастроек.КлючНастроек, МенеджерСохраненияНастроек.СохраненныеНастройки);
КонецЕсли;
КонецПроцедуры
Функция ПолучитьНастройкуПоУмолчаниюИзСпискаСохраненныхНастроекЛкс(СписокСохраненныхНастроек) Экспорт
ИмяОсновнойНастройки = "Основная";
СтрокаСписка = СписокСохраненныхНастроек.Найти(Истина, "Пометка");
Если СтрокаСписка = Неопределено Тогда
СтрокаСписка = СписокСохраненныхНастроек.Найти(ИмяОсновнойНастройки, "Представление");
КонецЕсли;
Если СтрокаСписка = Неопределено Тогда
СтрокаСписка = СписокСохраненныхНастроек.Добавить();
СтрокаСписка.Представление = ИмяОсновнойНастройки;
КонецЕсли;
СтрокаСписка.Пометка = Истина;
Возврат СтрокаСписка;
КонецФункции
Функция ВыбратьИСохранитьНастройкуФормыЛкс(ЭтаФорма) Экспорт
МенеджерСохраненияНастроек = СлужебныеДанныеФормыЛкс(ЭтаФорма).МенеджерСохраненияНастроек;
НовоеНаименование = Неопределено;
СохраняемаяНастройкаФормы = СохраняемаяНастройкаФормыЛкс(ЭтаФорма, НовоеНаименование);
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаСохраненияНастройки = мПлатформа.ПолучитьФорму("ВыборНастройкиДляСохранения");
ФормаСохраненияНастройки.НачальноеЗначениеВыбора = МенеджерСохраненияНастроек.ПоследняяНастройка;
ФормаСохраненияНастройки.НовоеНаименование = НовоеНаименование;
Если МенеджерСохраненияНастроек.СохраненныеНастройки <> Неопределено Тогда
ФормаСохраненияНастройки.СписокНастроек = МенеджерСохраненияНастроек.СохраненныеНастройки;
КонецЕсли;
ТекущиеДанные = ФормаСохраненияНастройки.ОткрытьМодально();
МенеджерСохраненияНастроек.СохраненныеНастройки = ФормаСохраненияНастройки.СписокНастроек;
МенеджерСохраненияНастроек.ПоследняяНастройка = ФормаСохраненияНастройки.НачальноеЗначениеВыбора;
Если ТекущиеДанные <> Неопределено Тогда
ТекущиеДанные.Значение = СохраняемаяНастройкаФормы;
КонецЕсли;
СохранитьНастройкуФормыЛкс(ЭтаФорма);
КонецФункции
// Параметры:
// КопироватьЗначения - Булево - Ложь сильно ускоряет
//
// Параметры:
// ЭтаФорма - Форма -
// выхНовоеНаименование - Строка -
// ПорогТаблицыЗначений - Число - Чтобы не засорять БД
//
// Возвращаемое значение:
// -
//
Функция СохраняемаяНастройкаФормыЛкс(Знач ЭтаФорма, выхНовоеНаименование = "", ПорогТаблицыЗначений = 100000) Экспорт
выхНовоеНаименование = "";
ИменаСвойств = "";
СохраняемаяНастройкаФормы = ЭтаФорма.СохраняемаяНастройкаФормы(выхНовоеНаименование, ИменаСвойств);
Если ЗначениеЗаполнено(ИменаСвойств) Тогда
Если СохраняемаяНастройкаФормы = Неопределено Тогда
СохраняемаяНастройкаФормы = Новый Структура;
КонецЕсли;
ИменаСвойств = СтрЗаменить(ИменаСвойств, "Реквизит.", "");
ИменаСвойств = СтрЗаменить(ИменаСвойств, "Форма.", "");
ИменаСвойств = СтрЗаменить(ИменаСвойств, "Табличная часть.", "");
МассивИмен = СтрРазделитьЛкс(ИменаСвойств, ",", Истина, Ложь);
ЗначенияСвойств = Новый Структура();
Для Каждого ИмяСвойства Из МассивИмен Цикл
Если Не ЗначениеЗаполнено(ИмяСвойства) Или СохраняемаяНастройкаФормы.Свойство(ИмяСвойства) Тогда
Продолжить;
КонецЕсли;
ЗначенияСвойств.Вставить(ИмяСвойства);
ТипЗначения = ТипЗнч(ЭтаФорма[ИмяСвойства]);
Если ЛиТипЗначенияТабличнойЧастиЛкс(ТипЗначения) Тогда
ЗначенияСвойств[ИмяСвойства] = ЭтаФорма[ИмяСвойства].Выгрузить();
ИначеЕсли ТипЗначения = Тип("КомпоновщикНастроекКомпоновкиДанных") Тогда
ЗначенияСвойств[ИмяСвойства] = ЭтаФорма[ИмяСвойства].ПолучитьНастройки();
Иначе
ЗначениеСвойства = ЭтаФорма[ИмяСвойства];
ЗначениеСвойства = КопияОбъектаЛкс(ЗначениеСвойства);
ЗначенияСвойств[ИмяСвойства] = ЗначениеСвойства;
КонецЕсли;
Если ТипЗнч(ЗначенияСвойств[ИмяСвойства]) = Тип("ТаблицаЗначений") Тогда
ТаблицаЗначений = ЗначенияСвойств[ИмяСвойства];
Если ТаблицаЗначений.Количество() > ПорогТаблицыЗначений Тогда
СообщитьЛкс("Сохраняемая таблица " + ИмяСвойства + " настройки формы обрезана " + ТаблицаЗначений.Количество() + " -> " + ПорогТаблицыЗначений + " строк");
Пока ТаблицаЗначений.Количество() > ПорогТаблицыЗначений Цикл
ТаблицаЗначений.Удалить(ТаблицаЗначений.Количество() - 1);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЦикла;
СкопироватьУниверсальнуюКоллекциюЛкс(ЗначенияСвойств, СохраняемаяНастройкаФормы);
КонецЕсли;
Возврат СохраняемаяНастройкаФормы;
КонецФункции
Функция ЛиТипЗначенияТабличнойЧастиЛкс(Знач ТипЗначения) Экспорт
Возврат Найти(НРег(ТипЗначения), ПеревестиСтроку("табличная часть")) > 0;
КонецФункции
Функция ВыбратьИЗагрузитьНастройкуФормыЛкс(ЭтаФорма) Экспорт
МенеджерСохраненияНастроек = СлужебныеДанныеФормыЛкс(ЭтаФорма).МенеджерСохраненияНастроек;
Если МенеджерСохраненияНастроек.СохраненныеНастройки = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если Не ПроверитьЗавершениеФоновыхЗаданийФормыЛкс(ЭтаФорма) Тогда
СообщитьЛкс("Нельзя выполнять загрузку настроек, пока форма выполняет фоновые задания");
Возврат Неопределено;
КонецЕсли;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаСохраненияНастройки = мПлатформа.ПолучитьФорму("ВыборНастройкиДляЗагрузки");
ФормаСохраненияНастройки.НачальноеЗначениеВыбора = МенеджерСохраненияНастроек.ПоследняяНастройка;
Если МенеджерСохраненияНастроек.СохраненныеНастройки <> Неопределено Тогда
ФормаСохраненияНастройки.СписокНастроек = МенеджерСохраненияНастроек.СохраненныеНастройки;
КонецЕсли;
ТекущиеДанные = ФормаСохраненияНастройки.ОткрытьМодально();
МенеджерСохраненияНастроек.СохраненныеНастройки = ФормаСохраненияНастройки.СписокНастроек;
МенеджерСохраненияНастроек.ПоследняяНастройка = ФормаСохраненияНастройки.НачальноеЗначениеВыбора;
Если ТекущиеДанные <> Неопределено И ТекущиеДанные.Значение <> Неопределено Тогда
ЗагрузитьНастройкуФормыЧерезОбработчикЛкс(ЭтаФорма, ТекущиеДанные.Значение);
КонецЕсли;
СохранитьНастройкуФормыЛкс(ЭтаФорма);
КонецФункции
Функция ПолучитьПиктограммуТипаЛкс(Тип) Экспорт
ИмяОбщегоТипа = Неопределено;
КлючПоиска = Новый Структура("ИД,ТипТипа", ПолучитьИдентификаторТипаЛкс(Тип), "Основной");
мПлатформа = ирКэш.Получить();
мПлатформа.ИнициализацияОписанияОбщихТипов();
НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
Иначе
//СтруктураТипа = ирКэш.Получить().ПолучитьСтруктуруТипаИзКонкретногоТипа(Тип);
//ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
ОбъектМД = Метаданные.НайтиПоТипу(Тип);
Если ОбъектМД <> Неопределено Тогда
ТекущееИмяТипа = ОбъектМД.ПолноеИмя();
ИмяОбщегоТипа = ПервыйФрагментЛкс(ТекущееИмяТипа);
КонецЕсли;
КонецЕсли;
Картинка = Неопределено;
Если ИмяОбщегоТипа <> Неопределено Тогда
ИмяКартинки = "ир" + ПервыйФрагментЛкс(ИмяОбщегоТипа);
Попытка
Картинка = ирКэш.КартинкаПоИмениЛкс(ИмяКартинки);
Исключение
ИмяКартинки = ИмяОбщегоТипа;
Попытка
Картинка = БиблиотекаКартинок[ИмяКартинки];
Исключение
КонецПопытки;
КонецПопытки;
КонецЕсли;
Возврат Картинка;
КонецФункции
Функция ПрочитатьДополнительныеПоляСсылающихсяОбъектовЛкс(Знач ТабличноеПоле, Знач КомпоновщикДопПолей, Знач ТаблицаДанных = Неопределено, ИмяПоляСсылки = "Данные") Экспорт
#Если Сервер И Не Сервер Тогда
КомпоновщикДопПолей = Новый КомпоновщикНастроекКомпоновкиДанных;
#КонецЕсли
Если ТаблицаДанных = Неопределено Тогда
ТаблицаДанных = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
КонецЕсли;
КомпоновщикДопПолей.Восстановить(СпособВосстановленияНастроекКомпоновкиДанных.Полное);
МассивДопПолей = Новый Структура();
ДопустимоеЧислоДопПолей = 5;
Счетчик = 1;
СтрокаПорядка = "";
СтрокаВыбора = "";
Для Каждого ПолеПорядка Из КомпоновщикДопПолей.Настройки.Порядок.Элементы Цикл
Если ПолеПорядка.Использование Тогда
ИмяПоля = "" + ПолеПорядка.Поле;
ИмяКолонки = "Реквизит" + Счетчик;
ДоступноеПоле = КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(ПолеПорядка.Поле);
Если Счетчик > ДопустимоеЧислоДопПолей Тогда
СообщитьЛкс("Дополнительное поле """ + ДоступноеПоле.Заголовок + """ пропущено, т.к. допускается не более " + ДопустимоеЧислоДопПолей + " полей");
Продолжить;
КонецЕсли;
МассивДопПолей.Вставить(ИмяКолонки, ИмяПоля);
КолонкаТП = ТабличноеПоле.Колонки[ИмяКолонки];
КолонкаТП.Видимость = Истина;
КолонкаТП.ТекстШапки = ДоступноеПоле.Заголовок;
Если СтрокаПорядка <> "" Тогда
СтрокаПорядка = СтрокаПорядка + ",";
КонецЕсли;
СтрокаПорядка = СтрокаПорядка + ИмяКолонки + " ";
Если ПолеПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда
СтрокаПорядка = СтрокаПорядка + "Возр";
Иначе
СтрокаПорядка = СтрокаПорядка + "Убыв";
КонецЕсли;
СтрокаВыбора = СтрокаВыбора + ",
| Т." + ИмяПоля + " КАК " + ИмяКолонки;
Счетчик = Счетчик + 1;
КонецЕсли;
КонецЦикла;
Если Не ЗначениеЗаполнено(СтрокаПорядка) Тогда
СтрокаПорядка = "Дата";
КонецЕсли;
Для Счетчик = Счетчик По ДопустимоеЧислоДопПолей Цикл
ИмяКолонки = "Реквизит" + Счетчик;
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
КолонкаТП = ТабличноеПоле.ПодчиненныеЭлементы[ТабличноеПоле.Имя + ИмяКолонки];
Иначе
КолонкаТП = ТабличноеПоле.Колонки[ИмяКолонки];
КонецЕсли;
КолонкаТП.Видимость = Ложь;
КонецЦикла;
СтандартныеРеквизиты = Новый Структура;
СтандартныеРеквизиты.Вставить("ПометкаУдаления", "ЛОЖЬ");
СтандартныеРеквизиты.Вставить("Проведен", "ЛОЖЬ");
СтандартныеРеквизиты.Вставить("ЭтоГруппа", "ЛОЖЬ");
СтандартныеРеквизиты.Вставить("Дата", "ДАТАВРЕМЯ(1,1,1)");
Для Каждого КлючИЗначение Из СтандартныеРеквизиты Цикл
ИмяРеквизита = КлючИЗначение.Ключ;
Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(Новый ПолеКомпоновкиДанных("Объект." + ИмяРеквизита)) = Неопределено Тогда
Продолжить;
КонецЕсли;
СтрокаВыбора = СтрокаВыбора + ",
| ЕСТЬNULL(Т.Объект." + ИмяРеквизита + ", " + КлючИЗначение.Значение + ") КАК " + ИмяРеквизита;
КонецЦикла;
Если ТипЗнч(ТаблицаДанных) <> Тип("ТаблицаЗначений") Тогда
//КопияТаблицыДанных = ТаблицаДанных.Выгрузить(, ИмяПоляСсылки);
КопияТаблицыДанных = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле);
Иначе
КопияТаблицыДанных = ТаблицаДанных;
КонецЕсли;
КопияТаблицыДанных = ирОбщий.ТаблицаСМинимальнымиТипамиКолонокЛкс(КопияТаблицыДанных,, ИмяПоляСсылки);
#Если Сервер И Не Сервер Тогда
КопияТаблицыДанных = Новый ТаблицаЗначений;
#КонецЕсли
ОписаниеТиповСсылки = КопияТаблицыДанных.Колонки[ИмяПоляСсылки].ТипЗначения;
ПорцияОбъектов = Новый ТаблицаЗначений;
ПорцияОбъектов.Колонки.Добавить("Объект", ОписаниеТиповСсылки);
ПорцияОбъектов.Колонки.Добавить("Индекс", Новый ОписаниеТипов("Число"));
РазмерПорции = 10000;
КоличествоПорций = Цел(ТаблицаДанных.Количество() / РазмерПорции) + 1;
Запрос = Новый Запрос;
ТекстЗапроса = "
|ВЫБРАТЬ Т.* ПОМЕСТИТЬ Т ИЗ &Т КАК Т;
|ВЫБРАТЬ Т.Объект, Т.Индекс" + СтрокаВыбора + "
|ИЗ Т КАК Т";
Запрос.Текст = ТекстЗапроса;
ИндексСтроки = 0;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоПорций, "Чтение дополнительных полей");
ДоступноеПолеОбъект = КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(Новый ПолеКомпоновкиДанных("Объект"));
Для СчетчикПорций = 1 По КоличествоПорций Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
ПорцияОбъектов.Очистить();
Для Счетчик = 1 По РазмерПорции Цикл
Если ИндексСтроки = ТаблицаДанных.Количество() Тогда
Прервать;
КонецЕсли;
СтрокаОбъекта = ТаблицаДанных[ИндексСтроки];
ИндексСтроки = ИндексСтроки + 1;
Если Ложь
Или ТипЗнч(СтрокаОбъекта[ИмяПоляСсылки]) = Тип("Строка")
Или СтрокаОбъекта[ИмяПоляСсылки] = Неопределено
Или ДоступноеПолеОбъект = Неопределено
Или Не ДоступноеПолеОбъект.ТипЗначения.СодержитТип(ТипЗнч(СтрокаОбъекта[ИмяПоляСсылки]))
Тогда
СтрокаОбъекта.ИндексКартинки = 12; // Регистр сведений
Продолжить;
КонецЕсли;
СтрокаПорции = ПорцияОбъектов.Добавить();
СтрокаПорции.Объект = СтрокаОбъекта[ИмяПоляСсылки];
СтрокаПорции.Индекс = ИндексСтроки - 1;
КонецЦикла;
Запрос.УстановитьПараметр("Т", ПорцияОбъектов);
РезультатЗапроса = Запрос.Выполнить();
РеквизитыПорции = РезультатЗапроса.Выгрузить();
Для Каждого СтрокаПорции Из РеквизитыПорции Цикл
СтрокаОбъекта = ТаблицаДанных[СтрокаПорции.Индекс];
СтрокаОбъекта.ИндексКартинки = ирОбщий.ПолучитьИндексКартинкиСсылкиЛкс(СтрокаПорции.Объект, Истина, СтрокаПорции);
ЗаполнитьЗначенияСвойств(СтрокаОбъекта, СтрокаПорции);
КонецЦикла;
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
СтрокаПорядка = "Метаданные," + СтрокаПорядка;
Возврат СтрокаПорядка;
КонецФункции
Процедура ОбновитьДоступныеПоляДляДополнительныхПолейЛкс(Знач ТаблицаДанных, Знач КомпоновщикДопПолей, Знач ТабличноеПолеДоступныхПолей) Экспорт
//Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы.Количество() = 0 Тогда
Если ТипЗнч(ТаблицаДанных) = Тип("ТаблицаЗначений") Тогда
ПолныеИменаМД = ТаблицаДанных.Скопировать(, "Метаданные");
Иначе
ПолныеИменаМД = ТаблицаДанных.Выгрузить(, "Метаданные");
КонецЕсли;
ПолныеИменаМД.Свернуть("Метаданные");
ПолныеИменаМД = ПолныеИменаМД.ВыгрузитьКолонку(0);
МассивТипов = Новый Массив();
Для Каждого ПолноеИмяМД Из ПолныеИменаМД Цикл
Если ТипЗнч(ПолноеИмяМД) = Тип("ОбъектМетаданных") Тогда
ПолноеИмяМД = ПолноеИмяМД.ПолноеИмя();
КонецЕсли;
Попытка
Тип = Тип(ирОбщий.ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяМД));
Исключение
Продолжить;
КонецПопытки;
МассивТипов.Добавить(Тип);
КонецЦикла;
Если МассивТипов.Количество() > 0 Тогда
КоллекцияПолей = Новый Массив();
КоллекцияПолей.Добавить(Новый Структура("Имя, ТипЗначения", "Объект", Новый ОписаниеТипов(МассивТипов)));
ТекстЗапроса = ирОбщий.ПолучитьЗапросИмитаторКоллекцииПолейЛкс(КоллекцияПолей);
СхемаКомпоновки = ирОбщий.СоздатьСхемуКомпоновкиПоЗапросу(ТекстЗапроса);
Иначе
СхемаКомпоновки = Новый СхемаКомпоновкиДанных;
КонецЕсли;
Если ТипЗнч(ТабличноеПолеДоступныхПолей) = Тип("ТаблицаФормы") Тогда
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПолеДоступныхПолей);
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(ПоместитьВоВременноеХранилище(СхемаКомпоновки), ЭтаФорма.УникальныйИдентификатор);
Иначе
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки);
КонецЕсли;
КомпоновщикДопПолей.Инициализировать(ИсточникДоступныхНастроек);
Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы.Количество() > 0 Тогда
#Если Клиент И Не Сервер Тогда
ТабличноеПолеДоступныхПолей.Развернуть(КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы[0]);
#КонецЕсли
КонецЕсли;
//КонецЕсли;
КонецПроцедуры
// ИменаКолонок - Строка - имена колонок через запятую
Процедура ТабличноеПолеОтобразитьПиктограммыТиповЛкс(ОформлениеСтроки, ИменаКолонок) Экспорт
Если ТипЗнч(ИменаКолонок) = Тип("Строка") Тогда
ИменаКолонок = СтрРазделитьЛкс(ИменаКолонок, ",", Истина);
КонецЕсли;
Для Каждого ИмяКолонки Из ИменаКолонок Цикл
Ячейка = ОформлениеСтроки.Ячейки.Найти(ИмяКолонки);
//:Ячейка = Новый("ОформлениеЯчейки")
Если Ячейка <> Неопределено Тогда
ДанныеКартинки = Ячейка.Значение;
Если ТипЗнч(ДанныеКартинки) = Тип("ПолеКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
СсылкаКартинка = Неопределено;
ТипЗначения = ТипЗнч(ДанныеКартинки);
Если Истина
И ТипЗначения = Тип("Булево")
И Ячейка.ОтображатьФлажок
Тогда
Продолжить;
КонецЕсли;
КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения);
Если КартинкаТипа <> Неопределено Тогда
Ячейка.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Получает картинку для корневого типа конфигурации.
//
// Параметры:
// пКорневойТип – Строка – корневой тип конфигурации.
//
// Возвращаемое значение:
// – Картинка – корневого типа конфигурации.
//
Функция ПолучитьКартинкуКорневогоТипаЛкс(Знач пКорневойТип) Экспорт
Если СтрокиРавныЛкс("Изменения", пКорневойТип) Тогда
Картинка = ирКэш.КартинкаПоИмениЛкс("ирТаблицаИзменений");
КонецЕсли;
Если Картинка = Неопределено Тогда
Картинка = ирКэш.КартинкаПоИмениЛкс("ир" + пКорневойТип);
КонецЕсли;
Если Картинка = Неопределено Или Картинка.Вид = ВидКартинки.Пустая Тогда
//Попытка
// Так почему то медленно работает
// Картинка = БиблиотекаКартинок[пКорневойТип];
//Исключение
//КонецПопытки;
Картинка = ирКэш.КартинкаПоИмениЛкс(пКорневойТип);
КонецЕсли;
Если Картинка = Неопределено Тогда
Картинка = Новый Картинка();
КонецЕсли;
Возврат Картинка;
КонецФункции // ПолучитьКартинкуКорневогоТипа()
Функция ОткрытьТекущуюСтрокуТабличногоПоляТаблицыБДВРедактореОбъектаБДЛкс(ТабличноеПоле, ПолноеИмяМД = Неопределено, ДоступныеПоляВыбора = Неопределено, Связанный = Ложь,
ФормаРедактора = Неопределено, ОбъектыНаСервере = Неопределено, ДляПодчиненногоРегистраСведенийНомерСтроки = Истина, ПриОтсутствииСтрокиОткрытьНовыйОбъект = Ложь,
ИмяКолонкиДанных = Неопределено) Экспорт
ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
Если Не ПриОтсутствииСтрокиОткрытьНовыйОбъект И ТекущаяСтрока = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
Если ПолноеИмяМД = Неопределено Тогда
ПолноеИмяМД = ДанныеЭлементаФормыЛкс(ТабличноеПоле).ОсновнаяТаблица;
КонецЕсли;
Если ИмяКолонкиДанных = Неопределено Тогда
ТекущаяКолонка = ТабличноеПоле.ТекущийЭлемент;
Если ТекущаяКолонка <> Неопределено Тогда
ИмяКолонкиДанных = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТекущаяКолонка, Истина);
КонецЕсли;
КонецЕсли;
Иначе
Если ПолноеИмяМД = Неопределено Тогда
ПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение)).ПолноеИмя();
КонецЕсли;
Если ИмяКолонкиДанных = Неопределено Тогда
ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка;
Если ТекущаяКолонка <> Неопределено Тогда
ИмяКолонкиДанных = ТекущаяКолонка.Данные;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И ИмяКолонкиДанных <> Неопределено
И (Ложь
Или ДоступныеПоляВыбора = Неопределено
Или ДоступныеПоляВыбора.НайтиПоле(Новый ПолеКомпоновкиДанных(ИмяКолонкиДанных)) <> Неопределено)
Тогда
ИмяКолонки = ИмяКолонкиДанных;
Иначе
ИмяКолонки = "";
КонецЕсли;
ПолноеИмяТаблицы = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
Если ТабличноеПоле.ТекущиеДанные <> Неопределено Тогда
КлючОбъекта = КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, ТабличноеПоле.ТекущиеДанные, ДляПодчиненногоРегистраСведенийНомерСтроки,, ОбъектыНаСервере);
КонецЕсли;
КорневойТип = ПервыйФрагментЛкс(ПолноеИмяТаблицы);
Если КлючОбъекта = Неопределено Тогда
Если Ложь
Или ЛиКорневойТипСсылкиЛкс(КорневойТип)
Или ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип)
Тогда
Если ТекущаяСтрока <> Неопределено Тогда
ТипКлюча = ТипЗнч(ТекущаяСтрока.Ссылка);
Иначе
ТипКлюча = Тип(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(ПолноеИмяМД));
КонецЕсли;
КлючОбъекта = Новый (ТипКлюча);
ПолноеИмяТаблицы = Метаданные.НайтиПоТипу(ТипКлюча).ПолноеИмя();
Иначе
КлючОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ПолноеИмяТаблицы,,, Ложь, ОбъектыНаСервере);
КонецЕсли;
КонецЕсли;
ОткрытьРедакторОбъектаБДЛкс(ПолноеИмяТаблицы, ИмяКолонки, Связанный, КлючОбъекта, ОбъектыНаСервере, ТабличноеПоле.ТекущиеДанные, ТабличноеПоле.ТекущаяСтрока, ФормаРедактора);
Возврат ФормаРедактора;
КонецФункции
Функция ОткрытьРедакторОбъектаБДЛкс(ПолноеИмяТаблицы, ИмяРеквизита, Связанный = Ложь, Знач КлючОбъекта = Неопределено, Знач ОбъектыНаСервере = Неопределено,
Знач ТекущиеДанныеТабличногоПоля = Неопределено, ТекущаяСтрокаТабличногоПоля = Неопределено, ФормаРедактора = Неопределено) Экспорт
Если ФормаРедактора = Неопределено Тогда
КлючУникальности = ТекущаяСтрокаТабличногоПоля;
Если Связанный Тогда
КлючУникальности = "Связанный";
КонецЕсли;
ФормаРедактора = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", , , КлючУникальности);
КонецЕсли;
Если КлючОбъекта <> Неопределено Тогда
Если Не ФормаРедактора.Открыта() Тогда
ПараметрыФормы = Новый Структура("ПараметрКлючИлиОбъект, ПараметрПрочитатьОбъект", КлючОбъекта, Истина);
ЗаполнитьЗначенияСвойств(ФормаРедактора.фОбъект, ПараметрыФормы);
Иначе
ФормаРедактора.ЗагрузитьОбъектПоКлючу(КлючОбъекта);
КонецЕсли;
Иначе
ФормаРедактора.УстановитьТаблицуБД(ПолноеИмяТаблицы);
КонецЕсли;
ФормаРедактора.Открыть();
СтруктураЛокальногоКлючаСтроки = Неопределено;
Если ТекущиеДанныеТабличногоПоля <> Неопределено Тогда
КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, ТекущиеДанныеТабличногоПоля, Истина, СтруктураЛокальногоКлючаСтроки, ОбъектыНаСервере);
КонецЕсли;
ФормаРедактора.ПоказатьЯчейкуДанныхОбъекта(ПолноеИмяТаблицы, ИмяРеквизита, СтруктураЛокальногоКлючаСтроки);
Возврат ФормаРедактора;
КонецФункции
Функция _КонтрольРазмераВыборкиПользователемЛкс(ЗапросИлиПостроитель, МаксимальноеЧислоСтрок = 500000) Экспорт
КоличествоСтрокРезультата = ирКэш.Получить().ПолучитьГрубоКоличествоСтрокВРезультатеЗапроса(ЗапросИлиПостроитель);
Если Истина
И ТипЗнч(КоличествоСтрокРезультата) = Тип("Число")
И КоличествоСтрокРезультата > МаксимальноеЧислоСтрок
Тогда
Кнопки = Новый СписокЗначений;
Кнопки.Добавить("Все", "Все");
Кнопки.Добавить("Часть", "Первые " + Формат(МаксимальноеЧислоСтрок, "ЧГ="));
Ответ = Вопрос("Загружаемая таблица содержит " + КоличествоСтрокРезультата + " строк. Сколько строк загружать?", Кнопки, , "Часть");
//Если Ответ <> КодВозвратаДиалога.ОК Тогда
// Возврат;
//КонецЕсли;
Если Ответ = "Все" Тогда
МаксимальноеЧислоСтрок = 0;
КонецЕсли;
Иначе
МаксимальноеЧислоСтрок = 0;
КонецЕсли;
Возврат МаксимальноеЧислоСтрок;
КонецФункции
Процедура ОбновитьСтатистикуПоТаблицеОбъектаМДВРезультатеПакетаЛкс(РезультатПакета, ПолноеИмяМД, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок", ЛиТаблицыИзменений = Ложь,
СтруктураОтбора = Неопределено, ТолькоРазрешенные = Истина) Экспорт
ТекстЗапроса = ПолучитьТекстЗапросаСтатистикиПоТаблицеЛкс(ПолноеИмяМД, ИмяКлючевойКолонки, ИмяКолонкиКоличества, ЛиТаблицыИзменений, СтруктураОтбора, ТолькоРазрешенные);
Если Не ЗначениеЗаполнено(ТекстЗапроса) Тогда
// В запрос попали только недоступные таблицы
Возврат;
КонецЕсли;
Запрос = Новый Запрос(ТекстЗапроса);
Если СтруктураОтбора <> Неопределено Тогда
СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураОтбора, Запрос.Параметры);
КонецЕсли;
СтруктураКлюча = Новый Структура(ИмяКлючевойКолонки);
КолонкиКоличества = Новый Массив();
КолонкиКоличества.Добавить(ИмяКолонкиКоличества);
Если ЛиТаблицыИзменений Тогда
СтруктураКлюча.Вставить("Узел");
КолонкиКоличества.Добавить("КоличествоВыгруженных");
КолонкиКоличества.Добавить("КоличествоНевыгруженных");
КонецЕсли;
СтатистикаПоТаблице = Запрос.Выполнить().Выгрузить();
СтатистикаПоТаблице.Колонки.Добавить("Найдена", Новый ОписаниеТипов("булево"));
Для Каждого ЭлементПакета Из РезультатПакета Цикл
СтрокиРезультата = ЭлементПакета.НайтиСтроки(Новый Структура(ИмяКлючевойКолонки, ПолноеИмяМД));
Если СтрокиРезультата.Количество() > 0 Тогда
Для Каждого СтрокаРезультата Из СтрокиРезультата Цикл
ЗаполнитьЗначенияСвойств(СтруктураКлюча, СтрокаРезультата);
Для Каждого ИмяКолонкиКоличества Из КолонкиКоличества Цикл
СтрокаРезультата[ИмяКолонкиКоличества] = 0;
КонецЦикла;
Для Каждого СтрокаСтатистики Из СтатистикаПоТаблице.НайтиСтроки(СтруктураКлюча) Цикл
СтрокаСтатистики.Найдена = Истина;
Для Каждого ИмяКолонкиКоличества Из КолонкиКоличества Цикл
СтрокаРезультата[ИмяКолонкиКоличества] = СтрокаСтатистики[ИмяКолонкиКоличества];
КонецЦикла;
КонецЦикла;
КонецЦикла;
Прервать;
КонецЕсли;
КонецЦикла;
Для Каждого СтрокаСтатистики Из СтатистикаПоТаблице.НайтиСтроки(Новый Структура("Найдена", Ложь)) Цикл
СтрокаРезультата = ЭлементПакета.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаРезультата, СтрокаСтатистики);
КонецЦикла;
КонецПроцедуры
Процедура ЗаполнитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, РезультатПакета = Неопределено, ИмяКлючевойКолонки = "ПолноеИмяОбъекта",
СуммируемыеКолонки = "КоличествоСтрок", СтруктураОтбора = Неопределено, КлючеваяКолонкаСодержитИмяТаблицы = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ДеревоМетаданных = Новый ДеревоЗначений
#КонецЕсли
ВсеСтрокиДерева = ВсеСтрокиДереваЗначенийЛкс(ДеревоМетаданных);
СтруктураСуммируемыхКолонок = Новый Структура(СуммируемыеКолонки);
МассивСуммируемыхКолонок = Новый Массив();
Для Каждого КлючИЗначение Из СтруктураСуммируемыхКолонок Цикл
МассивСуммируемыхКолонок.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
ИмяСуммируемойКолонки = МассивСуммируемыхКолонок[0];
Для Каждого СтрокаДерева Из ВсеСтрокиДерева Цикл
Для Каждого ИмяСуммируемойКолонки Из МассивСуммируемыхКолонок Цикл
СтрокаДерева[ИмяСуммируемойКолонки] = Неопределено;
КонецЦикла;
КонецЦикла;
Если РезультатПакета = Неопределено Тогда
ТаблицаКоличества = ирКэш.ТаблицаВсехТаблицБДЛкс();
Если КлючеваяКолонкаСодержитИмяТаблицы Тогда
ИмяКлючевойКолонкиИсточника = "ПолноеИмя";
Иначе
ИмяКлючевойКолонкиИсточника = "ПолноеИмяМД";
КонецЕсли;
ИмяСуммируемойКолонки = "КоличествоСтрок";
Иначе
ИмяКлючевойКолонкиИсточника = ИмяКлючевойКолонки;
Для Каждого ТаблицаРезультата Из РезультатПакета Цикл
Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл
Если ТаблицаКоличества = Неопределено Тогда
ТаблицаКоличества = ТаблицаРезультата.СкопироватьКолонки();
ТаблицаКоличества.Колонки.Удалить(ИмяКлючевойКолонкиИсточника);
ТаблицаКоличества.Колонки.Добавить(ИмяКлючевойКолонкиИсточника); // Чтобы убрать ограничение на длину строки, которое может быть разным в результатах запросов пакета
КонецЕсли;
Если СтруктураОтбора <> Неопределено Тогда
ПодходитФильтру = Истина;
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
ЗначениеРезультата = СтрокаРезультата[КлючИЗначение.Ключ];
Если ТипЗнч(КлючИЗначение.Значение) = Тип("Массив") Тогда
Если КлючИЗначение.Значение.Найти(ЗначениеРезультата) = Неопределено Тогда
ПодходитФильтру = Ложь;
Прервать;
КонецЕсли;
Иначе
Если КлючИЗначение.Значение <> ЗначениеРезультата Тогда
ПодходитФильтру = Ложь;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Не ПодходитФильтру Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
ЗаполнитьЗначенияСвойств(ТаблицаКоличества.Добавить(), СтрокаРезультата);
КонецЦикла;
КонецЦикла;
КонецЕсли;
Если ТаблицаКоличества <> Неопределено Тогда
Для Каждого СтрокаКоличества Из ТаблицаКоличества Цикл
Если СтрокаКоличества[ИмяСуммируемойКолонки] = Неопределено Тогда
Продолжить;
КонецЕсли;
СтрокаДерева = ДеревоМетаданных.Строки.Найти(СтрокаКоличества[ИмяКлючевойКолонкиИсточника], ИмяКлючевойКолонки, Истина);
Если СтрокаДерева <> Неопределено Тогда
Для Каждого ИмяСуммируемойКолонки Из МассивСуммируемыхКолонок Цикл
ДобавитьКоличествоСтрокСРодителемЛкс(СтрокаДерева, СтрокаКоличества[ИмяСуммируемойКолонки], ИмяСуммируемойКолонки);
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьКоличествоСтрокСРодителемЛкс(Знач СтрокаДерева, Знач ДобавкаККоличеству, Знач ИмяСуммируемойКолонки= "КоличествоСтрок") Экспорт
СтароеКоличество = СтрокаДерева[ИмяСуммируемойКолонки];
Если СтароеКоличество = Неопределено Тогда
СтароеКоличество = 0;
КонецЕсли;
НовоеКоличество = ?(СтрокаДерева[ИмяСуммируемойКолонки] = Неопределено, 0, СтрокаДерева[ИмяСуммируемойКолонки]) + ДобавкаККоличеству;
СтрокаДерева[ИмяСуммируемойКолонки] = НовоеКоличество;
Если СтрокаДерева.Уровень() > 1 Тогда
Возврат;
КонецЕсли;
Родитель = СтрокаДерева.Родитель;
Пока Родитель <> Неопределено Цикл
Если ТипЗнч(НовоеКоличество) <> Тип("Число") Тогда
Родитель[ИмяСуммируемойКолонки] = "?";
КонецЕсли;
КоличествоРодителя = Родитель[ИмяСуммируемойКолонки];
Если КоличествоРодителя = "?" Тогда
Прервать;
КонецЕсли;
Если ТипЗнч(КоличествоРодителя) <> Тип("Число") Тогда
КоличествоРодителя = 0;
КонецЕсли;
Родитель[ИмяСуммируемойКолонки] = КоличествоРодителя - СтароеКоличество + НовоеКоличество;
Родитель = Родитель.Родитель;
КонецЦикла;
КонецПроцедуры // ЗаполнитьДеревоИсточников()
Процедура ОбновитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок",
ЛиТаблицыИзменений = Ложь, СтруктураОтбора = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ДеревоМетаданных = Новый ДеревоЗначений
#КонецЕсли
РезультатПакета = ВычислитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, ИмяКлючевойКолонки, ИмяКолонкиКоличества, ЛиТаблицыИзменений, СтруктураОтбора);
ЗаполнитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, РезультатПакета, ИмяКлючевойКолонки, ИмяКолонкиКоличества);
КонецПроцедуры
Процедура УстановитьЗначениеКолонкиДереваЛкс(ДеревоЗначений, ИмяКолонки = "Пометка", НовоеЗначение = Истина) Экспорт
ВсеСтроки = ВсеСтрокиДереваЗначенийЛкс(ДеревоЗначений);
Для Каждого СтрокаДерева Из ВсеСтроки Цикл
СтрокаДерева.Пометка = НовоеЗначение;
КонецЦикла;
КонецПроцедуры
// НовыйРежим - Булево - Имя/Синоним
Процедура ТабличноеПолеОбновитьКолонкиИмяСинонимЛкс(ТабличноеПоле, НовыйРежим, ИмяКолонкиИмя = "Имя", ИмяКолонкиСиноним = "Представление") Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
КолонкиТП = ТабличноеПоле.Колонки;
КолонкаИмя = КолонкиТП[ИмяКолонкиИмя];
КолонкаСиноним = КолонкиТП[ИмяКолонкиСиноним];
КолонкаИмя.Видимость = НовыйРежим;
КолонкаСиноним.Видимость = Не НовыйРежим;
Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда
КолонкаИмя.ОтображатьИерархию = НовыйРежим;
КолонкаСиноним.ОтображатьИерархию = Не НовыйРежим;
КонецЕсли;
ИндексКолонкиИмя = КолонкиТП.Индекс(КолонкаИмя);
ИндексКолонкиСиноним = КолонкиТП.Индекс(КолонкаСиноним);
Если НовыйРежим = (ИндексКолонкиИмя > ИндексКолонкиСиноним) Тогда
КолонкиТП.Сдвинуть(КолонкаИмя, ИндексКолонкиСиноним - ИндексКолонкиИмя);
КонецЕсли;
Если НовыйРежим Тогда
ТабличноеПоле.ТекущаяКолонка = ТабличноеПоле.Колонки.Имя;
Иначе
ТабличноеПоле.ТекущаяКолонка = ТабличноеПоле.Колонки.Представление;
КонецЕсли;
КонецПроцедуры
Процедура ТабличноеПолеОформитьЯчейкиИмяСинонимЛкс(ТабличноеПоле, ОформлениеСтроки,
ИмяКолонкиИмя = "Имя", ИмяКолонкиСиноним = "Представление", ИмяКолонкиИндексКартинки = "ИндексКартинки", ДанныеФлажка = "") Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
Если ДанныеСтроки = Неопределено Тогда
// Свернутое табличное поле может такое присылать
Возврат;
КонецЕсли;
Если ТабличноеПоле.Колонки[ИмяКолонкиИмя].Видимость Тогда
ВедущаяКолонка = ТабличноеПоле.Колонки[ИмяКолонкиИмя];
ВедущийИндекс = ТабличноеПоле.Колонки.Индекс(ВедущаяКолонка);
КонецЕсли;
Если ТабличноеПоле.Колонки[ИмяКолонкиСиноним].Видимость Тогда
Если Ложь
Или ВедущаяКолонка = Неопределено
Или ТабличноеПоле.Колонки.Индекс(ТабличноеПоле.Колонки[ИмяКолонкиСиноним]) < ВедущийИндекс
Тогда
ВедущаяКолонка = ТабличноеПоле.Колонки[ИмяКолонкиСиноним];
КонецЕсли;
КонецЕсли;
Если ВедущаяКолонка <> Неопределено Тогда
Ячейка = ОформлениеСтроки.Ячейки[ВедущаяКолонка.Имя];
Если ЗначениеЗаполнено(ИмяКолонкиИндексКартинки) Тогда
ИндексКартинки = ДанныеСтроки[ИмяКолонкиИндексКартинки];
Если ИндексКартинки >= 0 Тогда
Ячейка.ОтображатьКартинку = Истина;
Ячейка.ИндексКартинки = ИндексКартинки;
КонецЕсли;
КонецЕсли;
Если ДанныеФлажка <> "" Тогда
Ячейка.ОтображатьФлажок = Истина;
Ячейка.Флажок = ДанныеСтроки[ДанныеФлажка];
КонецЕсли;
Если ТипЗнч(ДанныеСтроки) = Тип("СтрокаДереваЗначений") Тогда
КоличествоДочерних = ДанныеСтроки.Строки.Количество();
Если КоличествоДочерних > 0 Тогда
Ячейка.УстановитьТекст(Ячейка.Текст + " (" + КоличествоДочерних + ")");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ТабличноеПолеПозицияТекущейСтрокиЛкс(Знач ТабличноеПоле) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
СтарыйИндекс = Неопределено;
Если ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда
СтарыйИндекс = ТабличноеПоле.Значение.Индекс(ТабличноеПоле.ТекущаяСтрока);
КонецЕсли;
Возврат СтарыйИндекс;
КонецФункции
Процедура ПолеВводаРоли_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка) Экспорт
СтандартнаяОбработка = Ложь;
СписокВыбора = Новый СписокЗначений;
Для Каждого РольЛ Из Метаданные.Роли Цикл
#Если Сервер И Не Сервер Тогда
РольЛ = Метаданные.Роли.Пользователь;
#КонецЕсли
НовыйЭлемент = СписокВыбора.Добавить(РольЛ.Имя, РольЛ.Представление());
Если РольЛ.Имя = Элемент.Значение Тогда
НачальныйВыбор = НовыйЭлемент;
КонецЕсли;
КонецЦикла;
РезультатВыбора = ирОбщий.ВыбратьЭлементСпискаЗначенийЛкс(СписокВыбора, НачальныйВыбор, Истина, "Выберите роль");
Если РезультатВыбора <> Неопределено Тогда
ирОбщий.ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, РезультатВыбора.Значение);
КонецЕсли;
КонецПроцедуры
Процедура ПолеВводаПользователя_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка) Экспорт
СтандартнаяОбработка = Ложь;
ФормаВыбора = ирОбщий.ПолучитьФормуЛкс("Обработка.ирРедакторПользователей.Форма",, Элемент);
ФормаВыбора.РежимВыбора = Истина;
ФормаВыбора.НачальноеЗначениеВыбора = Элемент.Значение;
РезультатВыбора = ФормаВыбора.ОткрытьМодально();
Если РезультатВыбора <> Неопределено Тогда
ирОбщий.ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, РезультатВыбора);
КонецЕсли;
КонецПроцедуры
Процедура ПолеВводаСтрокиСоединенияADODBНачалоВыбораЛкс(Знач Элемент, СтандартнаяОбработка) Экспорт
СтандартнаяОбработка = Ложь;
СоединениеADO = Новый COMОбъект("ADODB.Connection");
СоединениеADO.ConnectionString = Элемент.Значение;
ДатаЛинк = Новый COMОбъект("DataLinks");
Если ДатаЛинк.PromptEdit(СоединениеADO) Тогда
ирОбщий.ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, СоединениеADO.ConnectionString);
КонецЕсли;
КонецПроцедуры
Функция ОпределитьВедущуюСтроковуюКолонкуТабличногоПоляЛкс(ТабличноеПолеДерева) Экспорт
Если Истина
И ТабличноеПолеДерева.ТекущаяКолонка <> Неопределено
И ЗначениеЗаполнено(ТабличноеПолеДерева.ТекущаяКолонка.Данные)
И ТабличноеПолеДерева.Значение.Колонки[ТабличноеПолеДерева.ТекущаяКолонка.Данные].ТипЗначения.СодержитТип(Тип("Строка"))
Тогда
ТекущаяКолонкаТП = ТабличноеПолеДерева.ТекущаяКолонка;
Иначе
Для Каждого КолонкаТП Из ТабличноеПолеДерева.Колонки Цикл
Если Не КолонкаТП.Видимость Тогда
Продолжить;
КонецЕсли;
КолонкаДерева = ТабличноеПолеДерева.Значение.Колонки[КолонкаТП.Данные];
Если КолонкаДерева.ТипЗначения.СодержитТип(Тип("Строка")) Тогда
ТекущаяКолонкаТП = КолонкаТП;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ТекущаяКолонкаТП;
КонецФункции
Функция НайтиСтрокуТабличногоПоляДереваЗначенийСоСложнымФильтромЛкс(ТабличноеПолеДерева, ПолеВводаФильтра, Подстроки = "") Экспорт
ТекущаяКолонкаТП = ОпределитьВедущуюСтроковуюКолонкуТабличногоПоляЛкс(ТабличноеПолеДерева);
Если ТекущаяКолонкаТП = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ИмяТекущейКолонки = ТекущаяКолонкаТП.Данные;
Если Не ЗначениеЗаполнено(ИмяТекущейКолонки) Тогда
Возврат Неопределено;
КонецЕсли;
ВсеСтроки = ВсеСтрокиДереваЗначенийЛкс(ТабличноеПолеДерева.Значение);
ТекущаяСтрока = ТабличноеПолеДерева.ТекущаяСтрока;
Если Подстроки = "" Тогда
Подстроки = ПолеВводаФильтра.Значение;
КонецЕсли;
Фрагменты = СтрРазделитьЛкс(НРег(Подстроки), " ", Истина);
ИндексСтроки = 0;
Если ТекущаяСтрока <> Неопределено Тогда
Если ЛиСтрокаСодержитВсеПодстрокиЛкс(ТекущаяСтрока[ИмяТекущейКолонки], Фрагменты) Тогда
ИндексСтроки = ВсеСтроки.Найти(ТекущаяСтрока) + 1;
КонецЕсли;
КонецЕсли;
Успех = Ложь;
Для ИндексСтроки = ИндексСтроки По ВсеСтроки.Количество() - 1 Цикл
ТекущаяСтрока = ВсеСтроки[ИндексСтроки];
Если ЛиСтрокаСодержитВсеПодстрокиЛкс(ТекущаяСтрока[ИмяТекущейКолонки], Фрагменты) Тогда
ТабличноеПолеДерева.ТекущаяСтрока = ТекущаяСтрока;
ТабличноеПолеДерева.ТекущаяКолонка = ТекущаяКолонкаТП;
Успех = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Успех Тогда
ПолеВводаФильтра.ЦветФонаПоля = Новый Цвет();
Иначе
ТекущаяСтрока = Неопределено;
ПолеВводаФильтра.ЦветФонаПоля = ПолучитьЦветСтиляЛкс("ирЦветФонаОшибки");
КонецЕсли;
Возврат ТекущаяСтрока;
КонецФункции
Процедура ВыделитьСтрокиТабличногоПоляПоКлючуЛкс(ТабличноеПоле, СтруктураИлиСтрокаТаблицы, Знач СтрокаКлюча = "", Сортировать = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
СтруктураИлиСтрокаТаблицы = Новый Структура;
#КонецЕсли
Если Не ЗначениеЗаполнено(СтрокаКлюча) Тогда
СтрокаКлюча = ИменаСвойствСтруктурыЛкс(СтруктураИлиСтрокаТаблицы);
КонецЕсли;
КлючПоиска = Новый Структура(СтрокаКлюча);
ЗаполнитьЗначенияСвойств(КлючПоиска, СтруктураИлиСтрокаТаблицы);
КоллекцияСтрок = ТабличноеПоле.Значение;
Если ТипЗнч(КоллекцияСтрок) = Тип("ДеревоЗначений") Тогда
КоллекцияСтрок = КоллекцияСтрок.Строки;
КонецЕсли;
Если ЗначениеЗаполнено(СтрокаКлюча) И Сортировать Тогда
Если ПредупреждениеПередСортировкойПоСсылочнымКолонкамЛкс(СтрокаКлюча, ТабличноеПоле) Тогда
КоллекцияСтрок.Сортировать(СтрокаКлюча);
КонецЕсли;
КонецЕсли;
ТабличноеПоле.ВыделенныеСтроки.Очистить();
ТекущаяСтрокаУстановлена = Ложь;
Если ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияСтрокДереваЗначений") Тогда
НайденныеСтроки = КоллекцияСтрок.НайтиСтроки(КлючПоиска, Истина);
Иначе
НайденныеСтроки = КоллекцияСтрок.НайтиСтроки(КлючПоиска);
КонецЕсли;
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ТабличноеПоле.ВыделенныеСтроки.Добавить(НайденнаяСтрока);
Если Не ТекущаяСтрокаУстановлена Тогда
ТабличноеПоле.ТекущаяСтрока = НайденнаяСтрока;
ТекущаяСтрокаУстановлена = Истина;
КонецЕсли;
КонецЦикла;
//ТабличноеПоле.ОбновитьСтроки();
КонецПроцедуры
Процедура ТабличноеПолеДеревоЗначений_РазвернутьВсеСтрокиЛкс(ТабличноеПоле, ЧислоПервыхИгнорируемыхСтрок = 0) Экспорт
Счетчик = 0;
Для Каждого Строка Из ТабличноеПоле.Значение.Строки Цикл
Счетчик = Счетчик + 1;
Если Счетчик > ЧислоПервыхИгнорируемыхСтрок Тогда
ТабличноеПоле.Развернуть(Строка, Истина);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ТабличноеПолеДеревоЗначений_СвернутьВсеСтрокиЛкс(ТабличноеПоле, ВосстановитьТекущуюСтроку = Ложь) Экспорт
МассивТекущихУзлов = Новый Массив;
Если ВосстановитьТекущуюСтроку Тогда
ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
Пока ТекущаяСтрока <> Неопределено Цикл
МассивТекущихУзлов.Добавить(ТекущаяСтрока);
ТекущаяСтрока = ТекущаяСтрока.Родитель;
КонецЦикла;
КонецЕсли;
ВсеСтрокиДерева = ВсеСтрокиДереваЗначенийЛкс(ТабличноеПоле.Значение);
Индикатор = ПолучитьИндикаторПроцессаЛкс(ВсеСтрокиДерева.Количество());
Для Каждого СтрокаДерева Из ВсеСтрокиДерева Цикл
ОбработатьИндикаторЛкс(Индикатор);
Если Истина
И ТабличноеПоле.Развернут(СтрокаДерева)
И СтрокаДерева.Строки.Количество() > 0
И МассивТекущихУзлов.Найти(СтрокаДерева) = Неопределено
Тогда
ТабличноеПоле.Свернуть(СтрокаДерева);
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
КонецПроцедуры
// Изменяет свернутость всех строк табличного поля дерева значений.
//
// Параметры:
// ДЗ – ТабличноеПоле – связанное с деревом значений и включенным режимом Дерево;
// Свернуть – Булево, *Истина - новое значение свернутости.
//
Процедура ДеревоЗначенийСвернутьРазвернутьЛкс(ДЗ, Свернуть = Ложь, Строки = Неопределено) Экспорт
Если Свернуть Тогда
ПредставлениеПроцесса = "Сворачиваем строки дерева";
Иначе
ПредставлениеПроцесса = "Разворачиваем строки дерева";
КонецЕсли;
Если Строки = Неопределено Тогда
Строки = ДЗ.Значение.Строки;
КонецЕсли;
Индикатор = ПолучитьИндикаторПроцессаЛкс(Строки.Количество(), ПредставлениеПроцесса);
Для Каждого СтрокаДерева Из Строки Цикл
ОбработатьИндикаторЛкс(Индикатор);
Если Истина
И Свернуть
И ДЗ.Развернут(СтрокаДерева)
Тогда
ДЗ.Свернуть(СтрокаДерева);
ИначеЕсли Истина
И Не Свернуть
И Не ДЗ.Развернут(СтрокаДерева)
Тогда
ДЗ.Развернуть(СтрокаДерева, Истина);
КонецЕсли;
//ДеревоЗначенийСвернутьРазвернутьЛкс(ДЗ, Свернуть, СтрокаДерева.Строки, Индикатор);
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс(Индикатор);
КонецПроцедуры
Процедура ТабличноеПолеДеревоЗначений_АвтоРазвернутьВсеСтрокиЛкс(ТабличноеПоле, МаксимальноеЧислоСтрок = 30, ТекущаяСтрокаУстановлена = Ложь) Экспорт
ВсеСтроки = ВсеСтрокиДереваЗначенийЛкс(ТабличноеПоле.Значение);
ЧислоДинамическихСтрок = ВсеСтроки.Количество();
Если ЧислоДинамическихСтрок > 0 Тогда
Если ЧислоДинамическихСтрок <= МаксимальноеЧислоСтрок Тогда
ТабличноеПолеДеревоЗначений_РазвернутьВсеСтрокиЛкс(ТабличноеПоле);
Если Не ТекущаяСтрокаУстановлена Тогда
ТабличноеПоле.ТекущаяСтрока = ТабличноеПоле.Значение.Строки[0].Строки[0];
КонецЕсли;
Иначе
Если Не ТекущаяСтрокаУстановлена Тогда
ТабличноеПоле.ТекущаяСтрока = ТабличноеПоле.Значение.Строки[0];
Если ТабличноеПоле.Значение.Строки.Количество() = 1 Тогда
ТабличноеПоле.Развернуть(ТабличноеПоле.ТекущаяСтрока);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ТабличноеПолеРезультатаЗапросаНастроитьКолонкиЛкс(Знач ТабличноеПолеРезультата, Знач СтарыеКолонкиТабличногоПоля = Неопределено, Знач ШиринаПустойКолонки = 5,
МаксКоличествоСтрокДляАнализа = 10000) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПолеРезультата = Новый ТабличноеПоле;
#КонецЕсли
Если ТипЗнч(ТабличноеПолеРезультата.Значение) = Тип("ДеревоЗначений") Тогда
// КоличествоСтрокВТаблице = ирОбщий.ВсеСтрокиДереваЗначенийЛкс(ТабличноеПолеРезультата.Значение); // Долго
КоличествоСтрокВТаблице = 10000000;
Иначе
КоличествоСтрокВТаблице = ТабличноеПолеРезультата.Значение.Количество();
КонецЕсли;
ВыполнятьАнализДанных = КоличествоСтрокВТаблице < МаксКоличествоСтрокДляАнализа;
Для Каждого Колонка Из ТабличноеПолеРезультата.Колонки Цикл
ДанныеКолонки = Колонка.Данные;
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
ДанныеКолонки = Колонка.ДанныеФлажка; // Здесь по крайней мере в 8.3 уже всегда пусто
КонецЕсли;
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
Продолжить;
КонецЕсли;
Колонка.ТолькоПросмотр = Истина;
Колонка.Формат = "ЧН=";
КолонкаТЗ = ТабличноеПолеРезультата.Значение.Колонки[ДанныеКолонки];
Если СтарыеКолонкиТабличногоПоля <> Неопределено Тогда
СохраненныеНастройкиКолонки = СтарыеКолонкиТабличногоПоля[КлючХраненияНастроекКолонкиРезультатаЗапросаЛкс(ТабличноеПолеРезультата, Колонка)];
КонецЕсли;
Если СохраненныеНастройкиКолонки <> Неопределено Тогда
Колонка.Ширина = СохраненныеНастройкиКолонки.Ширина;
Колонка.АвтоВысотаЯчейки = СохраненныеНастройкиКолонки.АвтоВысотаЯчейки;
Колонка.ВысотаЯчейки = СохраненныеНастройкиКолонки.ВысотаЯчейки;
Иначе
Если Истина
И КолонкаТЗ.ТипЗначения.СодержитТип(Тип("Строка"))
И (Ложь
Или КолонкаТЗ.ТипЗначения.КвалификаторыСтроки.Длина = 0
Или КолонкаТЗ.ТипЗначения.КвалификаторыСтроки.Длина > 100)
Тогда
Колонка.Ширина = 20;
КонецЕсли;
КонецЕсли;
Если ВыполнятьАнализДанных Тогда
ОписаниеТиповБезNull = Новый ОписаниеТипов(КолонкаТЗ.ТипЗначения, , "NUll");
ПустыеСтрокиБезNUll = ТабличноеПолеРезультата.Значение.НайтиСтроки(Новый Структура(ДанныеКолонки, ОписаниеТиповБезNull.ПривестиЗначение()));
ПустыеСтрокиNull = ТабличноеПолеРезультата.Значение.НайтиСтроки(Новый Структура(ДанныеКолонки, Null));
Если ПустыеСтрокиБезNUll.Количество() + ПустыеСтрокиNull.Количество() = КоличествоСтрокВТаблице Тогда
Колонка.Ширина = ШиринаПустойКолонки;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция _БезопасноеОписаниеТиповЛкс(ОписаниеТипов) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов = Новый ОписаниеТипов;
#КонецЕсли
Типы = ОписаниеТипов.Типы();
Если Типы.Количество() > 0 Тогда
ПростойТип = Типы[0];
Если Истина
И Типы.Количество() = 1
//// Антибаг платформы 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1015693#1015693
//И (Ложь
// Или ПростойТип = Тип("КоллекцияАтрибутовDOM")
// Или ПростойТип = Тип("ДокументDOM")
// Или ПростойТип = Тип("СписокУзловDOM")
// Или ПростойТип = Тип("АтрибутDOM")
// Или ПростойТип = Тип("ТипУзлаDOM")
// Или ПростойТип = Тип("ЭлементDOM")
// Или ПростойТип = Тип("КонфигурацияДокументаDOM")
// Или ПростойТип = Тип("ОпределениеТипаДокументаDOM")
// Или ПростойТип = Тип("КоллекцияНотацийDOM")
// Или ПростойТип = Тип("КоллекцияСущностейDOM")
// Или ПростойТип = Тип("ТипЗначенияXDTO")
// Или ПростойТип = Тип("ТипОбъектаXDTO")
// // Эти актуальны и в 8.3.18
// Или ПростойТип = Тип("ЗначениеXDTO")
// Или ПростойТип = Тип("ПакетXDTO"))
Тогда
ВсеРедактируемыеТипы = ирОбщий.ОписаниеТиповВсеРедактируемыеТипыЛкс();
#Если Сервер И Не Сервер Тогда
ВсеРедактируемыеТипы = Новый ОписаниеТипов;
#КонецЕсли
Если Не ВсеРедактируемыеТипы.СодержитТип(Типы[0]) Тогда
// Антибаг платформы 8.2-8.3.6 https://partners.v8.1c.ru/forum/t/1401671/m/1401671
ОписаниеТипов = Новый ОписаниеТипов;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ОписаниеТипов;
КонецФункции
Функция КлючХраненияНастроекКолонкиРезультатаЗапросаЛкс(Знач ТабличноеПолеРезультата, Знач СтараяКолонкаТП) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПолеРезультата = Новый ТабличноеПоле;
#КонецЕсли
СтараяКолонкаТЗ = ТабличноеПолеРезультата.Значение.Колонки[СтараяКолонкаТП.Имя];
Возврат СтараяКолонкаТП.Имя + " // " + Лев(СтараяКолонкаТЗ.ТипЗначения, 300);
КонецФункции
Процедура ТабличноеПолеСортироватьЛкс(ЭтаФорма, ТабличноеПоле, ПоВозрастанию = Истина) Экспорт
Если ТабличноеПоле.ТолькоПросмотр Тогда
Возврат;
КонецЕсли;
ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка;
Если ТекущаяКолонка = Неопределено Тогда
Возврат;
КонецЕсли;
ИмяКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
СообщитьЛкс("Сортировка по этой колонке невозможна");
Возврат;
КонецЕсли;
Продолжаем = ПредупреждениеПередСортировкойПоСсылочнымКолонкамЛкс(ИмяКолонки, ТабличноеПоле);
Если Не Продолжаем Тогда
Возврат;
КонецЕсли;
Если ПоВозрастанию Тогда
СтрокаСортировки = ИмяКолонки + " Возр";
Иначе
СтрокаСортировки = ИмяКолонки + " Убыв";
КонецЕсли;
Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда
Родитель = ПолучитьРодителяСтрокиДереваЛкс(ТабличноеПоле.ТекущаяСтрока);
КоллекцияСтрок = Родитель.Строки;
Иначе
КоллекцияСтрок = ТабличноеПоле.Значение;
КонецЕсли;
КоллекцияСтрок.Сортировать(СтрокаСортировки);
КонецПроцедуры
// http://www.hostedredmine.com/issues/877327 https://partners.v8.1c.ru/forum/t/1919734/m/1919734
Функция ПредупреждениеПередСортировкойПоСсылочнымКолонкамЛкс(Знач ИменаКолонок, Знач ТабличноеПоле, ОпасноеКоличествоСсылок = 5000) Экспорт
Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда
Родитель = ПолучитьРодителяСтрокиДереваЛкс(ТабличноеПоле.ТекущаяСтрока);
КоллекцияСтрок = Родитель.Строки;
Иначе
КоллекцияСтрок = ТабличноеПоле.Значение;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
КоллекцияСтрок = Новый ТаблицаЗначений;
#КонецЕсли
Продолжаем = Истина;
МассивИмен = СтрРазделитьЛкс(ИменаКолонок, ",", Истина);
Если КоллекцияСтрок.Количество() * МассивИмен.Количество() > ОпасноеКоличествоСсылок Тогда
МетаТЧ = Метаданные.НайтиПоТипу(ТипЗнч(КоллекцияСтрок[0]));
Если МетаТЧ <> Неопределено Тогда
Колонки = ТабличноеПоле.Значение.ВыгрузитьКолонки().Колонки;
Иначе
Колонки = КоллекцияСтрок[0].Владелец().Колонки;
КонецЕсли;
КоличествоСсылочныхКолонок = 0;
НепустыеЗначенияПростыхСсылочныхКолонок = Новый СписокЗначений;
Для Каждого ИмяКолонки Из МассивИмен Цикл
КоличествоСсылочныхТипов = 0;
Для Каждого Тип Из Колонки[ИмяКолонки].ТипЗначения.Типы() Цикл
Если ирОбщий.ЛиТипСсылкиБДЛкс(Тип) Тогда
КоличествоСсылочныхТипов = КоличествоСсылочныхТипов + 1;
Если КоличествоСсылочныхТипов > 1 Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если КоличествоСсылочныхТипов = 1 Тогда
НепустыеЗначенияПростыхСсылочныхКолонок.Добавить(, ИмяКолонки);
КонецЕсли;
Если КоличествоСсылочныхТипов > 0 Тогда
КоличествоСсылочныхКолонок = КоличествоСсылочныхКолонок + 1;
КонецЕсли;
КонецЦикла;
Если КоличествоСсылочныхКолонок * КоллекцияСтрок.Количество() > ОпасноеКоличествоСсылок Тогда
Ответ = Вопрос("Сортировка в памяти большого числа ссылочных значений может длиться долго, если для них задано динамическое представление. Сортировать?", РежимДиалогаВопрос.ДаНет,
10, КодВозвратаДиалога.Да);
Если Ответ = КодВозвратаДиалога.Нет Тогда
Продолжаем = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Продолжаем;
КонецФункции
Процедура ТабличноеПолеПорядкаКомпоновкиВыборЛкс(Знач Элемент, Знач ВыбраннаяСтрока, Знач Колонка, СтандартнаяОбработка) Экспорт
Если Колонка = Элемент.Колонки.ТипУпорядочивания Тогда
Если ВыбраннаяСтрока.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда
ВыбраннаяСтрока.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв;
Иначе
ВыбраннаяСтрока.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр;
КонецЕсли;
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецПроцедуры
Процедура ТабличноеПолеЭлементовКомпоновкиПеретаскиваниеЛкс(Знач Элемент, Знач ПараметрыПеретаскивания, СтандартнаяОбработка, Знач Строка, Знач Колонка) Экспорт
ЭлементыКомпоновки = Элемент.Значение;
#Если Сервер И Не Сервер Тогда
Пустышка = Новый НастройкиКомпоновкиДанных;
ЭлементыКомпоновки = Пустышка.Порядок;
#КонецЕсли
ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение;
Если ТипЗнч(ЗначениеПеретаскивания) = Тип("Массив") Тогда
Если ТипЗнч(ЗначениеПеретаскивания[0]) = Тип("ДоступноеПолеКомпоновкиДанных") Тогда
СтандартнаяОбработка = Ложь;
Для Каждого ЭлементПеретаскивания Из ЗначениеПеретаскивания Цикл
КоллекцияПриемник = ЭлементыКомпоновки.Элементы;
Если Строка <> Неопределено Тогда
Попытка
КоллекцияПриемник = Строка.Элементы;
Исключение
КонецПопытки;
КонецЕсли;
НовыйЭлемент = НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(КоллекцияПриемник, ЭлементПеретаскивания.Поле, ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Перемещение);
Если Строка <> Неопределено Тогда
СдвинутьЭлементКоллекцииНаПозициюДругогоЭлементаЛкс(КоллекцияПриемник, НовыйЭлемент, Строка);
КонецЕсли;
КонецЦикла;
Элемент.ТекущаяСтрока = НовыйЭлемент;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура СдвинутьЭлементКоллекцииНаПозициюДругогоЭлементаЛкс(Знач Коллекция, Знач СдвигаемыйЭлемент, Знач ЭлементСЦелевойПозицией) Экспорт
#Если Сервер И Не Сервер Тогда
Коллекция = Новый ТаблицаЗначений;
#КонецЕсли
Коллекция.Сдвинуть(СдвигаемыйЭлемент, Коллекция.Индекс(ЭлементСЦелевойПозицией) - Коллекция.Индекс(СдвигаемыйЭлемент));
КонецПроцедуры
Процедура ПрименитьСтрокуПоискаКТабличномуПолюДереваЛкс(ТабличноеПолеДерева, СтрокаПоиска, ИменаКолонокДанныхДляПоиска, выхСтруктураПоиска, АктивизироватьПервуюСтроку = Истина) Экспорт
СтруктураКолонок = Новый Структура(ИменаКолонокДанныхДляПоиска);
НайденныеСтрокиДерева = Новый Массив();
Если ЗначениеЗаполнено(СтрокаПоиска) Тогда
ВсеСтроки = ВсеСтрокиДереваЗначенийЛкс(ТабличноеПолеДерева.Значение);
ИндексТекущейСтроки = ВсеСтроки.Найти(ТабличноеПолеДерева.ТекущаяСтрока);
ИндексАктивизируемойСтроки = Неопределено;
Для Каждого СтрокаДерева Из ВсеСтроки Цикл
Для Каждого КлючИЗначение Из СтруктураКолонок Цикл
ИнтереснаяКолонка = КлючИЗначение.Ключ;
Значение = СтрокаДерева[ИнтереснаяКолонка];
Если ТипЗнч(Значение) = Тип("Строка") Тогда
Значение = НРег(Значение);
Если Найти(Значение, НРег(СтрокаПоиска)) > 0 Тогда
НайденныеСтрокиДерева.Добавить(СтрокаДерева);
Если ИндексТекущейСтроки <> Неопределено И ВсеСтроки.Найти(СтрокаДерева) >= ИндексТекущейСтроки И ИндексАктивизируемойСтроки = Неопределено Тогда
ИндексАктивизируемойСтроки = НайденныеСтрокиДерева.Количество() - 1;
КонецЕсли;
Родитель = СтрокаДерева;
Пока Родитель <> Неопределено Цикл
Если Не ТабличноеПолеДерева.Развернут(Родитель) Тогда
ТабличноеПолеДерева.Развернуть(Родитель);
КонецЕсли;
Родитель = Родитель.Родитель;
КонецЦикла;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если НайденныеСтрокиДерева.Количество() > 1000 Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если АктивизироватьПервуюСтроку И НайденныеСтрокиДерева.Количество() > 0 Тогда
Если ИндексАктивизируемойСтроки = Неопределено Тогда
ИндексАктивизируемойСтроки = 0;
КонецЕсли;
ТабличноеПолеДерева.ТекущаяСтрока = НайденныеСтрокиДерева[ИндексАктивизируемойСтроки];
КонецЕсли;
КонецЕсли;
ТекущийИндексНайденнойСтроки = 0;
выхСтруктураПоиска = Новый Структура("ТекущийИндексНайденнойСтроки, НайденныеСтрокиДерева", ТекущийИндексНайденнойСтроки, НайденныеСтрокиДерева);
КонецПроцедуры
Процедура СледующееВхождениеСтрокиПоискаВТабличномПолеДереваЛкс(ТабличноеПолеДерева, СтруктураПоиска) Экспорт
Если СтруктураПоиска = Неопределено Тогда
Возврат;
КонецЕсли;
Если СтруктураПоиска.НайденныеСтрокиДерева.Количество() > 0 Тогда
СтруктураПоиска.ТекущийИндексНайденнойСтроки = СтруктураПоиска.ТекущийИндексНайденнойСтроки + 1;
Если СтруктураПоиска.ТекущийИндексНайденнойСтроки >= СтруктураПоиска.НайденныеСтрокиДерева.Количество() Тогда
СтруктураПоиска.ТекущийИндексНайденнойСтроки = 0;
КонецЕсли;
ТабличноеПолеДерева.ТекущаяСтрока = СтруктураПоиска.НайденныеСтрокиДерева[СтруктураПоиска.ТекущийИндексНайденнойСтроки];
КонецЕсли;
КонецПроцедуры
Процедура ПредыдущееВхождениеСтрокиПоискаВТабличномПолеДереваЛкс(ТабличноеПолеДерева, СтруктураПоиска) Экспорт
Если СтруктураПоиска = Неопределено Тогда
Возврат;
КонецЕсли;
Если СтруктураПоиска.НайденныеСтрокиДерева.Количество() > 0 Тогда
СтруктураПоиска.ТекущийИндексНайденнойСтроки = СтруктураПоиска.ТекущийИндексНайденнойСтроки - 1;
Если СтруктураПоиска.ТекущийИндексНайденнойСтроки < 0 Тогда
СтруктураПоиска.ТекущийИндексНайденнойСтроки = СтруктураПоиска.НайденныеСтрокиДерева.Количество() - 1;
КонецЕсли;
ТабличноеПолеДерева.ТекущаяСтрока = СтруктураПоиска.НайденныеСтрокиДерева[СтруктураПоиска.ТекущийИндексНайденнойСтроки];
КонецЕсли;
КонецПроцедуры
Процедура ОформитьСтрокуВТабличномПолеДереваСПоискомЛкс(ТабличноеПолеДерева, ОформлениеСтроки, ДанныеСтроки, СтруктураПоиска) Экспорт
Если СтруктураПоиска = Неопределено Тогда
Возврат;
КонецЕсли;
Если СтруктураПоиска.НайденныеСтрокиДерева.Найти(ДанныеСтроки) <> Неопределено Тогда
ОформлениеСтроки.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаРасширенногоПредставленияЗначения");
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьСсылкуВИсториюРаботыЛкс(Ссылка, ДобавлятьВИсториюРаботыПлатформы = Истина, ДобавлятьВИсториюИнтерфейснойПанели = Истина) Экспорт
Если ДобавлятьВИсториюРаботыПлатформы Тогда
ИсторияРаботыПользователя.Добавить(ПолучитьНавигационнуюСсылку(Ссылка));
КонецЕсли;
Если ДобавлятьВИсториюИнтерфейснойПанели Тогда
ФормаИнтерфейснойПанели = ПолучитьФормуЛкс("Обработка.ирИнтерфейснаяПанель.Форма");
СтруктураЭлемента = Новый Структура();
СтруктураЭлемента.Вставить("Вид", Ссылка.Метаданные().ПолноеИмя());
СтруктураЭлемента.Вставить("Имя", Ссылка);
ФормаИнтерфейснойПанели.ДобавитьСтрокуВСтатическуюВетку(СтруктураЭлемента, Ложь);
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьИнструментВИсториюРаботыЛкс(Форма, ДобавлятьВИсториюРаботыПлатформы = Истина, ДобавлятьВИсториюИнтерфейснойПанели = Истина) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ИмяФормы = ИмяФормыИзФормыЛкс(Форма);
Если Не ЗначениеЗаполнено(ИмяФормы) Тогда
Возврат;
КонецЕсли;
Попытка
ОсновнойОбъект = Форма.ЭтотОбъект;
Исключение
Возврат;
КонецПопытки;
ПолноеИмяМД = ОсновнойОбъект.Метаданные().ПолноеИмя();
Фрагменты = ирОбщий.СтрРазделитьЛкс(ПолноеИмяМД);
Если Ложь
Или Фрагменты[1] = "ирДинамическийСписок"
Или Фрагменты[1] = "ирРедакторОбъектаБД"
Или Фрагменты[1] = "ирИнтерфейснаяПанель"
Тогда
Возврат;
КонецЕсли;
Фрагменты[0] = ПеревестиВРусский(Фрагменты[0]);
мПлатформа.ЗаполнитьСписокИнструментов();
СтрокаИнструмента = мПлатформа.СписокИнструментов.НайтиСтроки(Новый Структура("Видимость, ПолноеИмя", Истина, Фрагменты[0] + "." + Фрагменты[1]));
Если СтрокаИнструмента.Количество() > 0 Тогда
Если ДобавлятьВИсториюИнтерфейснойПанели Тогда
ФормаИнтерфейснойПанели = ПолучитьФормуЛкс("Обработка.ирИнтерфейснаяПанель.Форма");
СтруктураЭлемента = Новый Структура();
СтруктураЭлемента.Вставить("Вид", ирОбщий.МножественноеИмяМДЛкс(Фрагменты[0]));
СтруктураЭлемента.Вставить("Имя", Фрагменты[1]);
ФормаИнтерфейснойПанели.ДобавитьСтрокуВСтатическуюВетку(СтруктураЭлемента, Ложь);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьСсылкуВИзбранноеЛкс(Ссылка, ДобавлятьВИзбранноеРаботыПользователя = Истина, ДобавлятьВИзрабнноеИнтерфейснойПанели = Истина) Экспорт
//Если ДобавлятьВИзбранноеРаботыПользователя И ирОбщий.ЛиСсылкаНаОбъектБДЛкс(Ссылка) Тогда
// // e1cib/command/Справочник.ирАлгоритмы.ОткрытьСписок
// // e1cib/command/Обработка.ирДинамическийСписок.Открыть
// // e1cib/command/Обработка.ирКонсольЗапросов.Команда1
// Избранное = ХранилищеСистемныхНастроек.Загрузить("Общее/ИзбранноеРаботыПользователя");
// Если Избранное = Неопределено Тогда
// Избранное = Новый ИзбранноеРаботыПользователя;
// КонецЕсли;
// ЭлементИзбранного = Новый ЭлементИзбранногоРаботыПользователя;
// ЭлементИзбранного.НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(Ссылка);
// Избранное.Добавить(ЭлементИзбранного);
// ХранилищеСистемныхНастроек.Сохранить("Общее/ИзбранноеРаботыПользователя", "", Избранное);
// ОбновитьИнтерфейс();
//КонецЕсли;
Если ДобавлятьВИзрабнноеИнтерфейснойПанели Тогда
ФормаИнтерфейснойПанели = ПолучитьФормуЛкс("Обработка.ирИнтерфейснаяПанель.Форма");
СтруктураЭлемента = Новый Структура();
СтруктураЭлемента.Вставить("Вид", Ссылка.Метаданные().ПолноеИмя());
СтруктураЭлемента.Вставить("Имя", Ссылка);
ФормаИнтерфейснойПанели.ДобавитьСтрокуВСтатическуюВетку(СтруктураЭлемента, Истина);
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьТаблицуВИзбранноеЛкс(ИмяТаблицыБД, ДобавлятьВИзбранноеРаботыПользователя = Истина, ДобавлятьВИзрабнноеИнтерфейснойПанели = Истина) Экспорт
//Если ДобавлятьВИзбранноеРаботыПользователя Тогда
// Избранное = ХранилищеСистемныхНастроек.Загрузить("Общее/ИзбранноеРаботыПользователя");
// Если Избранное = Неопределено Тогда
// Избранное = Новый ИзбранноеРаботыПользователя;
// КонецЕсли;
// ЭлементИзбранного = Новый ЭлементИзбранногоРаботыПользователя;
// ЭлементИзбранного.НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(Ссылка);
// Избранное.Добавить(ЭлементИзбранного);
// ХранилищеСистемныхНастроек.Сохранить("Общее/ИзбранноеРаботыПользователя", "", Избранное);
// ОбновитьИнтерфейс();
//КонецЕсли;
Если ДобавлятьВИзрабнноеИнтерфейснойПанели Тогда
ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ИмяТаблицыБД);
Если ОбъектМД = Неопределено Тогда
Возврат;
КонецЕсли;
ФормаИнтерфейснойПанели = ПолучитьФормуЛкс("Обработка.ирИнтерфейснаяПанель.Форма");
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Справочники.Валюты;
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ОбъектМД.ПолноеИмя());
СтрокаТипаМетаОбъектов = мПлатформа.ПолучитьСтрокуТипаМетаОбъектов(КорневойТип);
СтруктураЭлемента = Новый Структура();
СтруктураЭлемента.Вставить("Вид", СтрокаТипаМетаОбъектов.Множественное);
СтруктураЭлемента.Вставить("Имя", ОбъектМД.Имя);
ФормаИнтерфейснойПанели.ДобавитьСтрокуВСтатическуюВетку(СтруктураЭлемента);
КонецЕсли;
КонецПроцедуры
//
Процедура ОткрытьОбъектыИзВыделенныхЯчеекВПодбореИОбработкеОбъектовЛкс(ТабличноеПоле, Знач ИмяКолонки = "", Знач ЭтаФорма = Неопределено, Знач ПолноеИмяТаблицыБД = "") Экспорт
Если ЗначениеЗаполнено(ПолноеИмяТаблицыБД) Тогда
Ответ = Вопрос("Использовать значения текущей колонки (да) или ключи строк (нет)?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет);
СобиратьКлючи = Ответ = КодВозвратаДиалога.Нет;
Иначе
СобиратьКлючи = Ложь;
КонецЕсли;
Если СобиратьКлючи Тогда
МассивСсылок = Новый Массив();
Для Каждого ВыделеннаяСтрока Из ТабличноеПоле.ВыделенныеСтроки Цикл
КлючОбъекта = КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицыБД, ВыделеннаяСтрока);
МассивСсылок.Добавить(КлючОбъекта);
КонецЦикла;
КлючТекущейСтроки = КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицыБД, ТабличноеПоле.ТекущаяСтрока);
Иначе
МассивСсылок = СсылкиИзВыделенныхЯчеекТабличногоПоляЛкс(ТабличноеПоле, ИмяКолонки);
КонецЕсли;
ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(МассивСсылок,, ЭтаФорма,, КлючТекущейСтроки);
КонецПроцедуры
Функция СсылкиИзВыделенныхЯчеекТабличногоПоляЛкс(ТабличноеПоле, ИмяКолонки = "") Экспорт
МассивСсылок = Новый Массив;
ВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТабличноеПоле);
Если ВыделенныеСтроки.Количество() = 0 Тогда
Возврат МассивСсылок;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ИмяКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Возврат МассивСсылок;
КонецЕсли;
Для Каждого КлючСтроки Из ВыделенныеСтроки Цикл
ДанныеСтроки = ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле, КлючСтроки);
ЗначениеСтроки = ДанныеСтроки[ИмяКолонки];
ТипЗначения = ТипЗнч(ЗначениеСтроки);
Если Метаданные.НайтиПоТипу(ТипЗначения) = Неопределено Тогда
Продолжить;
КонецЕсли;
МассивСсылок.Добавить(ЗначениеСтроки);
КонецЦикла;
Возврат МассивСсылок;
КонецФункции
Функция ТекущаяКолонкаТаблицыФормыЛкс(ТаблицаФормы) Экспорт
Если ТипЗнч(ТаблицаФормы) = Тип("ТаблицаФормы") Тогда
Результат = ТаблицаФормы.ТекущийЭлемент;
ИначеЕсли ТипЗнч(ТаблицаФормы) = Тип("ТабличноеПоле") Тогда
Результат = ТаблицаФормы.ТекущаяКолонка;
Иначе
ВызватьИсключение "Неверный тип (" + ТипЗнч(ТаблицаФормы) + ") параметра";
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОткрытьПодборИОбработкуОбъектовИзТабличногоПоляДинамическогоСпискаЛкс(ТабличноеПоле, Знач НастройкиСписка = Неопределено, ВыделенныеСтроки = Неопределено) Экспорт
ДинамическийСписок = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
ПолноеИмяМД = "";
ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле, ПолноеИмяМД);
Если ЗначениеЗаполнено(ПолноеИмяМД) Тогда
Ответ = Вопрос("Обработать только выделенные строки (Да) иначе будет использован текущий отбор (Нет)?", РежимДиалогаВопрос.ДаНет);
Иначе
Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
ВыбранныеПоля = Новый Массив;
МассивКолонок = Неопределено;
КолонкиТаблицыФормыИлиТабличногоПоляЛкс(ТабличноеПоле, МассивКолонок);
ТекущееПолеТаблицы = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Для Каждого КолонкаТП Из МассивКолонок Цикл
Если Не КолонкаТП.Видимость Тогда
Продолжить;
КонецЕсли;
ДанныеКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле, КолонкаТП);
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
Продолжить;
КонецЕсли;
ВыбранныеПоля.Добавить(ДанныеКолонки);
КонецЦикла;
Если Ответ = КодВозвратаДиалога.Да Тогда
Если ВыделенныеСтроки = Неопределено Тогда
ВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТабличноеПоле);
КонецЕсли;
ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда
ВыделенныеСтроки = КлючиВыделенныхСтрокИмитатораДинамическогоСпискаЛкс(ТабличноеПоле, ВыделенныеСтроки);
ТекущиеСтроки = Новый Массив;
ТекущиеСтроки.Добавить(ТекущаяСтрока);
ТекущаяСтрока = КлючиВыделенныхСтрокИмитатораДинамическогоСпискаЛкс(ТабличноеПоле, ТекущиеСтроки)[0];
КонецЕсли;
Форма = ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(ВыделенныеСтроки, ВыбранныеПоля,, ТекущееПолеТаблицы, ТекущаяСтрока);
Иначе
Форма = ПолучитьФормуЛкс("Обработка.ирПодборИОбработкаОбъектов.Форма",,, ПолноеИмяМД);
Форма.ПараметрВыбранныеПоля = ВыбранныеПоля;
Форма.ПараметрТекущееПоле = ТекущееПолеТаблицы;
Форма.ПараметрКлючТекущейСтроки = ТабличноеПоле.ТекущаяСтрока;
Если НастройкиСписка = Неопределено Тогда
НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДинамическийСписок);
КонецЕсли;
Форма.ПараметрНастройкаКомпоновки = НастройкиСписка;
Форма.Открыть();
КонецЕсли;
Возврат Форма;
КонецФункции
Функция КолонкиТаблицыФормыИлиТабличногоПоляЛкс(Знач ТабличноеПолеИлиТаблицаФормы, выхМассивКолонок = Неопределено, выхТекущаяКолонка = Неопределено) Экспорт
Колонки = Новый Массив;
Если ТипЗнч(ТабличноеПолеИлиТаблицаФормы) = Тип("ТабличноеПоле") Тогда
Колонки = ТабличноеПолеИлиТаблицаФормы.Колонки;
выхМассивКолонок = Колонки;
выхТекущаяКолонка = ТабличноеПолеИлиТаблицаФормы.ТекущаяКолонка;
ИначеЕсли ТипЗнч(ТабличноеПолеИлиТаблицаФормы) = Тип("ТаблицаФормы") Тогда
Колонки = ТабличноеПолеИлиТаблицаФормы.ПодчиненныеЭлементы;
выхМассивКолонок = Новый Массив;
Для Каждого Элемент Из Колонки Цикл
выхМассивКолонок.Добавить(Элемент);
КонецЦикла;
выхТекущаяКолонка = ТабличноеПолеИлиТаблицаФормы.ТекущийЭлемент;
Если выхМассивКолонок.Найти(выхТекущаяКолонка) = Неопределено Тогда
// Пользовательская колонка
выхМассивКолонок.Добавить(выхТекущаяКолонка);
КонецЕсли;
КонецЕсли;
Возврат Колонки;
КонецФункции
// В обычной форме "Динамический список ИР" для перечислений сделан статический список через таблицу значений
Функция КлючиВыделенныхСтрокИмитатораДинамическогоСпискаЛкс(Знач ТабличноеПоле, ВыделенныеСтроки = Неопределено)
Если ВыделенныеСтроки = Неопределено Тогда
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
КонецЕсли;
ПараметрКоманды = Новый Массив();
Для Каждого Строка Из ВыделенныеСтроки Цикл
Если ТипЗнч(Строка) = Тип("СтрокаТаблицыЗначений") Тогда
КлючСтроки = Строка.Ссылка;
Иначе
КлючСтроки = Строка;
КонецЕсли;
ПараметрКоманды.Добавить(КлючСтроки);
КонецЦикла;
Возврат ПараметрКоманды;
КонецФункции
// Параметры:
// ВыбранныеПоля - Массив, *Неопределено
Функция ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(МассивСсылок, ВыбранныеПоля = Неопределено, ЭтаФорма = Неопределено, ТекущееПолеТаблицы = Неопределено,
КлючТекущейСтроки = Неопределено) Экспорт
Если МассивСсылок.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
Если ЭтаФорма <> Неопределено Тогда
ирОбщий.ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма);
КонецЕсли;
Форма = ПолучитьФормуЛкс("Обработка.ирПодборИОбработкаОбъектов.Форма",,, Новый УникальныйИдентификатор);
Форма.ПараметрМассивСсылок = МассивСсылок;
Форма.ПараметрВыбранныеПоля = ВыбранныеПоля;
Форма.ПараметрТекущееПоле = ТекущееПолеТаблицы;
Форма.ПараметрКлючТекущейСтроки = КлючТекущейСтроки;
Форма.Открыть();
//Форма.ЗагрузитьОбъектыДляОбработки(ПолучитьУникальныеЗначенияМассиваЛкс(МассивСсылок),, ВыбранныеПоля);
Возврат Форма;
КонецФункции
Функция ПолучитьУникальныеЗначенияМассиваЛкс(Массив) Экспорт
НовыйМассив = Новый Массив;
Соответствие = Новый Соответствие;
Для Каждого Элемент Из Массив Цикл
Если Соответствие[Элемент] = 1 Тогда
Продолжить;
КонецЕсли;
Соответствие.Вставить(Элемент, 1);
НовыйМассив.Добавить(Элемент);
КонецЦикла;
Возврат НовыйМассив;
КонецФункции
Функция ПолучитьСтруктуруВосстановленияКонсолиЛкс(ИмяИлиОбъектКонсоли) Экспорт
Если ТипЗнч(ИмяИлиОбъектКонсоли) = Тип("Строка") Тогда
ИмяКонсоли = ИмяИлиОбъектКонсоли;
Иначе
ИмяКонсоли = ИмяИлиОбъектКонсоли.Метаданные().Имя;
КонецЕсли;
Структура = Новый Структура();
Структура.Вставить("БлокировкаВосстановления", Неопределено);
ПрефиксИмениФайлаВосстановления = ИмяКонсоли + "_" + ИмяПользователя() + "_";
Структура.Вставить("ПрефиксИмениФайлаВосстановления", ПрефиксИмениФайлаВосстановления);
ИмяФайлаВосстановления = ирКэш.Получить().КаталогФайловогоКэша + "\" + ПрефиксИмениФайлаВосстановления + Новый УникальныйИдентификатор + ".tmp";
Структура.Вставить("ФайлВосстановления", Новый Файл(ИмяФайлаВосстановления));
Возврат Структура;
КонецФункции
Функция СохранитьФайлВКонсолиСВосстановлениемЛкс(ДиалогВыбораФайла, Знач ИмяСохраняемогоФайла, ИмяОткрытогоФайла = "", ДанныеДляФайла, СтруктураВосстановления, ЗапрашиватьИмяФайла = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ДиалогВыбораФайла = Новый ДиалогВыбораФайла();
#КонецЕсли
ФайлВосстановления = СтруктураВосстановления.ФайлВосстановления;
ПрефиксИмениФайлаВосстановления = СтруктураВосстановления.ПрефиксИмениФайлаВосстановления;
БлокировкаВосстановления = СтруктураВосстановления.БлокировкаВосстановления;
СохранитьФайл = Истина;
Если Не СтрокиРавныЛкс(ИмяСохраняемогоФайла, ФайлВосстановления.ПолноеИмя) Тогда
// Здесь можно вставить проверочную сериализацию+десериализацию
ФайлВыбран = Истина;
лФайл = Новый Файл(ИмяОткрытогоФайла);
ДиалогВыбораФайла.ПолноеИмяФайла = ИмяСохраняемогоФайла;
Если Ложь
Или ПустаяСтрока(ИмяСохраняемогоФайла)
Или ЗапрашиватьИмяФайла
Или Найти(Нрег(лФайл.Имя), НРег(ПрефиксИмениФайлаВосстановления)) = 1
Тогда
Пока Истина Цикл
Если ДиалогВыбораФайла.Выбрать() Тогда
лФайл = Новый Файл(ДиалогВыбораФайла.ПолноеИмяФайла);
Если Найти(Нрег(лФайл.Имя), НРег(ПрефиксИмениФайлаВосстановления)) = 1 Тогда
КодОтвета = Вопрос("Это имя файла зарезервировано. Хотите выбрать другое?", РежимДиалогаВопрос.ОКОтмена);
Если КодОтвета = КодВозвратаДиалога.ОК Тогда
Продолжить;
Иначе
ФайлВыбран = Ложь;
Прервать;
КонецЕсли;
КонецЕсли;
ИмяСохраняемогоФайла = ДиалогВыбораФайла.ПолноеИмяФайла;
ФайлВыбран = Истина;
Прервать;
Иначе
ФайлВыбран = Ложь;
СохранитьФайл = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Иначе
ФайлВыбран = Ложь;
КонецЕсли;
Если СохранитьФайл Тогда
МоментНачала = ТекущаяДата();
Если Истина
И НРег(ИмяСохраняемогоФайла) = НРег(ФайлВосстановления.ПолноеИмя)
И БлокировкаВосстановления <> Неопределено
Тогда
БлокировкаВосстановления = Неопределено;
КонецЕсли;
ПроверитьСериализациюXMLПередВызовомЗначениеВФайлЛкс(ДанныеДляФайла);
Если Не ЗначениеВФайл(ИмяСохраняемогоФайла, ДанныеДляФайла) Тогда
СообщитьЛкс("Ошибка записи файла """ + ИмяСохраняемогоФайла + """", СтатусСообщения.Внимание);
ФайлВыбран = Ложь;
КонецЕсли;
выхДлительность = ТекущаяДата() - МоментНачала;
Если выхДлительность > 1 Тогда
СообщитьЛкс("Автосохранение файла восстановления выполнено за " + выхДлительность + " секунд");
КонецЕсли;
Если НРег(ИмяСохраняемогоФайла) = НРег(ФайлВосстановления.ПолноеИмя) Тогда
БлокировкаВосстановления = Новый ЗаписьТекста(ИмяСохраняемогоФайла,,,Истина);
КонецЕсли;
КонецЕсли;
Возврат ФайлВыбран;
КонецФункции
Функция ПроверитьВыбратьФайлВосстановленияКонсолиЛкс(СтруктураВосстановления) Экспорт
ПрефиксИмениФайлаВосстановления = СтруктураВосстановления.ПрефиксИмениФайлаВосстановления;
СписокВосстановления = Новый СписокЗначений;
КаталогФайлов = ирКэш.Получить().КаталогФайловогоКэша;
ФайлыВосстановления = НайтиФайлы(КаталогФайлов, ПрефиксИмениФайлаВосстановления + "*.tmp");
Для Каждого Файл Из ФайлыВосстановления Цикл
#Если Сервер И Не Сервер Тогда
Файл = Новый Файл;
#КонецЕсли
СписокВосстановления.Добавить(Файл.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс(), Файл.Имя);
КонецЦикла;
СписокВосстановления.СортироватьПоЗначению(НаправлениеСортировки.Убыв);
СписокВыбора = Новый СписокЗначений;
Для Каждого ЭлементСписка Из СписокВосстановления Цикл
ДатаИзменения = ЭлементСписка.Значение;
Файл = Новый Файл(КаталогФайлов + "\" + ЭлементСписка.Представление);
Попытка
Файл.УстановитьВремяИзменения(ДатаИзменения);
//Пустышка = Новый ЗаписьТекста(ФайлВосстановления.ПолноеИмя, , , Истина);
Исключение
// Файла заблокирован и значит сессия продолжается.
Продолжить;
КонецПопытки;
СписокВыбора.Добавить(Файл.ПолноеИмя, "" + ДатаИзменения + " - " + Файл.ИмяБезРасширения);
КонецЦикла;
ИмяФайлаВосстановления = "";
Если СписокВыбора.Количество() > 0 Тогда
СписокВыбора.Добавить("<Удалить все файлы восстановления>");
ВыбранныйЭлемент = СписокВыбора.ВыбратьЭлемент("Вы можете открыть файл восстановления прерванной сессии");
Если ВыбранныйЭлемент <> Неопределено Тогда
Если ВыбранныйЭлемент.Значение = "<Удалить все файлы восстановления>" Тогда
Для Каждого ЭлементСписка Из СписокВыбора Цикл
Если ВыбранныйЭлемент = ЭлементСписка Тогда
Продолжить;
КонецЕсли;
УдалитьФайлы(ЭлементСписка.Значение);
КонецЦикла;
Иначе
ИмяФайлаВосстановления = ВыбранныйЭлемент.Значение;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ИмяФайлаВосстановления;
КонецФункции
Процедура УдалитьФайлВосстановленияКонсолиСБлокировкойЛкс(СтруктураВосстановления) Экспорт
СтруктураВосстановления.БлокировкаВосстановления = Неопределено;
Попытка
УдалитьФайлы(СтруктураВосстановления.ФайлВосстановления.ПолноеИмя);
Исключение
КонецПопытки;
КонецПроцедуры
Процедура СчитатьПорциюВыборкиВТаблицуЛкс(Выборка, ТаблицаПриемник, Знач РазмерПорции = 9999, СчитыватьЧерезКопиюТаблицы = Истина,
СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый Запрос;
Выборка = Пустышка.Выполнить();
#КонецЕсли
Если СчитыватьЧерезКопиюТаблицы Тогда
// Иначе добавление и заполнение строк при связи с табличным полем будет дольше выполняться
КопияТаблицыПриемника = ТаблицаПриемник.Скопировать();
Если СсылкаНаБуфернуюТаблицу <> Неопределено Тогда
СсылкаНаБуфернуюТаблицу.Вставить("Таблица", КопияТаблицыПриемника);
КонецЕсли;
Иначе
КопияТаблицыПриемника = ТаблицаПриемник;
КонецЕсли;
КоличествоРезультата = Выборка.Количество();
Несчитано = КоличествоРезультата - КопияТаблицыПриемника.Количество();
Если Ложь
Или РазмерПорции > Несчитано
Или РазмерПорции = 0
Тогда
РазмерПорции = Несчитано;
КонецЕсли;
Если Несчитано = РазмерПорции Тогда
ПредставлениеПроцесса = "Загрузка выборки";
Иначе
ПредставлениеПроцесса = "Загрузка порции выборки";
КонецЕсли;
#Если Клиент Тогда
Индикатор = ПолучитьИндикаторПроцессаЛкс(РазмерПорции, ПредставлениеПроцесса);
#КонецЕсли
КолонкиВложенныхТаблиц = Новый Массив();
Для Каждого Колонка Из Выборка.Владелец().Колонки Цикл
Если Колонка.ТипЗначения.СодержитТип(Тип("РезультатЗапроса")) Тогда
КолонкиВложенныхТаблиц.Добавить(Колонка.Имя);
КонецЕсли;
КонецЦикла;
ЕстьКолонкиВложенныхТаблиц = КолонкиВложенныхТаблиц.Количество() > 0;
РазмерПорцииОсталось = РазмерПорции;
Пока Выборка.Следующий() Цикл
НоваяСтрока = КопияТаблицыПриемника.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
Если ЕстьКолонкиВложенныхТаблиц Тогда
Для Каждого КолонкаВложеннойТаблицы Из КолонкиВложенныхТаблиц Цикл
НоваяСтрока[КолонкаВложеннойТаблицы] = Выборка[КолонкаВложеннойТаблицы].Выгрузить();
КонецЦикла;
КонецЕсли;
Если РазмерПорцииОсталось > 0 Тогда
РазмерПорцииОсталось = РазмерПорцииОсталось - 1;
Если РазмерПорцииОсталось = 0 Тогда
Прервать;
КонецЕсли;
КонецЕсли;
#Если Клиент Тогда
ОбработатьИндикаторЛкс(Индикатор);
#КонецЕсли
КонецЦикла;
Если РазмерПорции = Несчитано Тогда
Выборка = Неопределено;
КонецЕсли;
#Если Клиент Тогда
ОсвободитьИндикаторПроцессаЛкс();
#КонецЕсли
ТаблицаПриемник = КопияТаблицыПриемника;
КонецПроцедуры
// ТабличноеПоле определяется как источник действий командной панели.
// Параметру ВыборкаРезультата внутри присваивается значение!
Процедура ЗагрузитьВыборкуВТабличноеПолеПервуюПорциюЛкс(ЭтаФорма, РезультатЗапроса, ВыборкаРезультата, КоманднаяПанель,
ИмяОбработчикаОбновления = "ОбновитьРазмерДинамическойТаблицы", БезопасныйПорогКоличестваСтрок = 100000, СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
лЗапрос = Новый Запрос;
РезультатЗапроса = лЗапрос.Выполнить();
#КонецЕсли
//БезопасныйПорогКоличестваСтрок = 1; // Для отладки
ВыборкаРезультата = РезультатЗапроса.Выбрать();
ТабличноеПоле = КоманднаяПанель.ИсточникДействий;
НачалоЗагрузки = ТекущаяДата();
Если Ложь
Или БезопасныйПорогКоличестваСтрок = 0
Или ВыборкаРезультата.Количество() < БезопасныйПорогКоличестваСтрок
Тогда
ВыборкаРезультата = Неопределено;
КоманднаяПанель.Кнопки.ЗагрузитьПолностью.Доступность = Ложь;
ТабличноеПоле.Значение = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.Прямой);
Попытка
Выполнить("ЭтаФорма." + ИмяОбработчикаОбновления + "()");
Исключение
ВызватьИсключение ОписаниеОшибки();
КонецПопытки;
Иначе
ТабличноеПоле.Значение = Новый ТаблицаЗначений;
Для Каждого Колонка Из РезультатЗапроса.Колонки Цикл
ТипЗначения = Колонка.ТипЗначения;
Если ТипЗначения.СодержитТип(Тип("РезультатЗапроса")) Тогда
ТипЗначения = Новый ОписаниеТипов("ТаблицаЗначений");
КонецЕсли;
ТабличноеПоле.Значение.Колонки.Добавить(Колонка.Имя, ТипЗначения, Колонка.Имя, Колонка.Ширина);
КонецЦикла;
ЭтаФорма.ПодключитьОбработчикОжидания(ИмяОбработчикаОбновления, 0.1, Истина);
СчитатьПорциюВыборкиВТаблицуЛкс(ВыборкаРезультата, ТабличноеПоле.Значение, БезопасныйПорогКоличестваСтрок, , СсылкаНаБуфернуюТаблицу);
КонецЕсли;
Длительность = ТекущаяДата() - НачалоЗагрузки;
Если Длительность > 30 Тогда
СообщитьЛкс("Загрузка выборки выполнена за " + XMLСтрока(Длительность) + " секунд");
КонецЕсли;
КонецПроцедуры
// ТабличноеПоле определяется как источник действий командной панели.
Процедура ЗагрузитьВыборкуВТабличноеПолеПолностьюЛкс(ЭтаФорма, мВыборкаРезультата, КоманднаяПанель,
ИмяОбработчикаОбновления = "ОбновитьРазмерДинамическойТаблицы", СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
ЭтаФорма.ПодключитьОбработчикОжидания(ИмяОбработчикаОбновления, 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
Если ирКэш.ДоступныОбщиеРеквизитыЛкс() Тогда
Если Истина
И СтрокаСвязаннойКолонки.ТипТаблицы = "Изменения"
И Найти(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, "РегистрСведений.") = 1
Тогда
Если Метаданные.ОбщиеРеквизиты.Количество() > 0 Тогда
Возврат Неопределено;
КонецЕсли;
//Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл
// ВыбранноеПоле = Построитель.ВыбранныеПоля.Найти(ОбщийРеквизит.Имя);
// Если Истина
// И ВыбранноеПоле <> Неопределено
// И ОбъектМетаданных.Измерения.Найти(ОбщийРеквизит.Имя) = Неопределено
// Тогда
// Если ирОбщий.ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Тогда
// Построитель.ВыбранныеПоля.Удалить(ВыбранноеПоле);
// КонецЕсли;
// КонецЕсли;
//КонецЦикла;
КонецЕсли;
КонецЕсли;
Попытка
РезультатСтрокиТаблицы = Построитель.Результат;
Исключение
// Антибаг платформы 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=1031481#1031481
СообщитьЛкс(ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
ирОбщий.ЗагрузитьВыборкуВТабличноеПолеПервуюПорциюЛкс(ЭтаФорма, РезультатСтрокиТаблицы, мВыборкаРезультатаСтрокиТаблицы, КоманднаяПанельСвязанныхСтрок);
//Если СтрокиТаблицыБД.Количество() = МаксимальныйРазмер Тогда
// СообщитьЛкс("Были выбраны первые " + МаксимальныйРазмер + " строк таблицы");
//КонецЕсли;
СтруктураОтбора = Новый Структура("ПолноеИмяТаблицы, ИмяКолонки", СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки);
ЗаполнитьЗначенияСвойств(СтруктураОтбора, СтрокаСвязаннойКолонки);
ТабличноеПолеСвязанныхСтрок.СоздатьКолонки();
ТабличноеПолеСвязанныхСтрок.ТекущаяКолонка = ТабличноеПолеСвязанныхСтрок.Колонки[СтрокаСвязаннойКолонки.ИмяКолонки];
Для Каждого КолонкаТП Из ТабличноеПолеСвязанныхСтрок.Колонки Цикл
КолонкаТП.ТолькоПросмотр = Истина;
КонецЦикла;
Попытка
ИскомаяСсылка = СтрокаСвязаннойКолонки.Ссылка
Исключение
ИскомаяСсылка = Неопределено;
КонецПопытки;
Если ИскомаяСсылка <> Неопределено Тогда
ТекущаяСтрока = ТабличноеПолеСвязанныхСтрок.Значение.Найти(ИскомаяСсылка, СтрокаСвязаннойКолонки.ИмяКолонки);
Если ТекущаяСтрока <> Неопределено Тогда
ТабличноеПолеСвязанныхСтрок.ТекущаяСтрока = ТекущаяСтрока;
КонецЕсли;
КонецЕсли;
Возврат СтрокаСвязаннойКолонки.ПолноеИмяТаблицы;
КонецФункции
Процедура ОбновитьЧислоЗагруженныхЭлементовВыборкиЛкс(ТабличноеПоле, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, КоличествоЗагружено, КоличествоРезультата, ВсеСчитано) Экспорт
Если ВсеСчитано Тогда
СтрокаКоличествоРезультата = "" + КоличествоЗагружено;
ПолеСтрокиКоличестваРезультата.ЦветФона = Новый Цвет();
Иначе
СтрокаКоличествоРезультата = "" + КоличествоЗагружено + "/" + КоличествоРезультата;
ПолеСтрокиКоличестваРезультата.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаВычисляемогоЗначения");
КонецЕсли;
ПолеСтрокиКоличестваРезультата.Значение = СтрокаКоличествоРезультата;
КоманднаяПанель.Кнопки.ЗагрузитьПолностью.Доступность = Не ВсеСчитано;
КонецПроцедуры
Функция ТекстОтбораЗапросаКомпоновкиЛкс(ТекстЗапросаСОтбором, ПсевдонимТаблицыПередГДЕ = "Т") Экспорт
ТекстОтбора = ПоследнийФрагментЛкс(ТекстЗапросаСОтбором, "КАК " + ПсевдонимТаблицыПередГДЕ + "
|ГДЕ", Ложь);
Если Не ЗначениеЗаполнено(ТекстОтбора) Тогда
ТекстОтбора = " ИСТИНА ";
КонецЕсли;
Возврат ТекстОтбора;
КонецФункции
// Функция - Найти показать строку в поле текстового документа лкс
//
// Параметры:
// Форма - -
// ПолеТекстовогоДокумента - -
// СтрокаПоиска - -
// СловоЦеликом - -
//
// Возвращаемое значение:
// - Булево - была ли найдена и выделена строка
//
Функция НайтиПоказатьСтрокуВПолеТекстовогоДокументаЛкс(Форма = Неопределено, ПолеТекстовогоДокумента, СтрокаПоиска, СловоЦеликом = Ложь) Экспорт
Перем НачальнаяПозиция;
Перем КонечнаяПозиция;
ГраницыВыделенияВПолеТекстаЛкс(ПолеТекстовогоДокумента, НачальнаяПозиция, КонечнаяПозиция);
Позиция = 0;
Вхождения = ирОбщий.НайтиРегулярноеВыражениеЛкс(ПолеТекстовогоДокумента.ПолучитьТекст(), ШаблонПоискаСловаЛкс(СтрокаПоиска, СловоЦеликом));
#Если Сервер И Не Сервер Тогда
Вхождения = Обработки.ирПлатформа.Создать().ВхожденияРегулярногоВыражения;
#КонецЕсли
Для каждого Вхождение Из Вхождения Цикл
Если Вхождение.ПозицияВхождения >= КонечнаяПозиция Тогда
Позиция = Вхождение.ПозицияВхождения + 1;
Если СловоЦеликом Тогда
Позиция = Позиция + СтрДлина(Вхождение.Подгруппы[0]);
КонецЕсли;
Прервать;
КонецЕсли;
КонецЦикла;
Если Вхождения.Количество() > 0 И Позиция = 0 Тогда
Позиция = Вхождения[0].ПозицияВхождения + 1;
Если СловоЦеликом Тогда
Позиция = Позиция + СтрДлина(Вхождения[0].Подгруппы[0]);
КонецЕсли;
КонецЕсли;
Если Позиция > 0 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(Позиция, Позиция + СтрДлина(СтрокаПоиска));
Если Форма <> Неопределено Тогда
Форма.ТекущийЭлемент = ПолеТекстовогоДокумента;
КонецЕсли;
Результат = Истина;
Иначе
Если СтрДлина(ПолеТекстовогоДокумента.ВыделенныйТекст) > 0 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1);
КонецЕсли;
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ГраницыВыделенияВПолеТекстаЛкс(Знач ПолеТекста, НачальнаяПозиция, КонечнаяПозиция) Экспорт
Перем КонечнаяКолонка, КонечнаяСтрока, НачальнаяКолонка, НачальнаяСтрока;
#Если Сервер И Не Сервер Тогда
ПолеТекстовогоДокумента = Новый ТекстовыйДокумент;
#КонецЕсли
ПолеТекста.ПолучитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка);
НачальнаяПозиция = ПозицияВПолеТекстаПоНомеруСтрокиИКолонкиЛкс(ПолеТекста, НачальнаяСтрока, НачальнаяКолонка);
КонечнаяПозиция = ПозицияВПолеТекстаПоНомеруСтрокиИКолонкиЛкс(ПолеТекста, КонечнаяСтрока, КонечнаяКолонка);
КонецПроцедуры
Функция ПозицияВПолеТекстаПоНомеруСтрокиИКолонкиЛкс(Знач ПолеТекста, Знач КонечнаяСтрока, Знач КонечнаяКолонка) Экспорт
Если ТипЗнч(ПолеТекста) = Тип("ПолеВвода") Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ПолеТекста.Значение);
Иначе
ТекстовыйДокумент = ПолеТекста;
КонецЕсли;
КонечнаяПозиция = 0;
Для Счетчик = 1 По КонечнаяСтрока - 1 Цикл
КонечнаяПозиция = КонечнаяПозиция + СтрДлина(ТекстовыйДокумент.ПолучитьСтроку(Счетчик)) + 1;
КонецЦикла;
КонечнаяПозиция = КонечнаяПозиция + СтрДлина(Лев(ТекстовыйДокумент.ПолучитьСтроку(Счетчик), КонечнаяКолонка));
Возврат КонечнаяПозиция;
КонецФункции
Функция ШаблонПоискаСловаЛкс(Знач СтрокаПоиска, СловоЦеликом = Истина) Экспорт
Шаблон = ПреобразоватьТекстДляРегулярныхВыраженийЛкс(СтрокаПоиска);
Если СловоЦеликом Тогда
Шаблон = "(^|[^_a-zа-яё0-9])(" + Шаблон + ")($|[^_a-zа-яё0-9])";
КонецЕсли;
Возврат Шаблон;
КонецФункции
// Параметры:
// Элемент - ПолеТабличногоДокумента
//
Функция ПолеТабличногоДокумента_ПолучитьПредставлениеСуммыВыделенныхЯчеекЛкс(Знач Элемент) Экспорт
Сумма = 0;
СчетчикЯчеекСуммы = 0;
СчетчикЯчеекОбщий = 0;
ВыделенныеОбласти = Элемент.ВыделенныеОбласти;
ЕстьИгнорированныеОбласти = Ложь;
НачальноеКоличество = ВыделенныеОбласти.Количество();
Для СчетчикВыделенныеОбласти = 1 По НачальноеКоличество Цикл
Область = ВыделенныеОбласти[НачальноеКоличество - СчетчикВыделенныеОбласти];
Если ТипЗнч(Область) = Тип("РисунокТабличногоДокумента") Тогда
Продолжить;
КонецЕсли;
ПлощадьОбласти = (Область.Право - Область.Лево + 1) * (Область.Низ - Область.Верх + 1);
СчетчикЯчеекОбщий = СчетчикЯчеекОбщий + ПлощадьОбласти;
Если ПлощадьОбласти < 10000 Тогда
Для НомерКолонки = Область.Лево по Область.Право Цикл
Для НомерСтроки = Область.Верх по Область.Низ Цикл
ОбластьЯчейки = Элемент.Область(НомерСтроки, НомерКолонки);
Если ОбластьЯчейки.Лево <> НомерКолонки Или ОбластьЯчейки.Верх <> НомерСтроки Тогда
// Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой
Продолжить;
КонецЕсли;
Попытка
Число = Число(ОбластьЯчейки.Текст);
Исключение
Продолжить;
КонецПопытки;
Сумма = Сумма + Число;
СчетчикЯчеекСуммы = СчетчикЯчеекСуммы + 1;
КонецЦикла;
КонецЦикла;
Иначе
ЕстьИгнорированныеОбласти = Истина;
КонецЕсли;
КонецЦикла;
СчетчикЯчеекСуммы = "" + СчетчикЯчеекСуммы;
Сумма = "" + Сумма;
Если ЕстьИгнорированныеОбласти Тогда
СчетчикЯчеекСуммы = СчетчикЯчеекСуммы + "+?";
Сумма = Сумма + "+?";
КонецЕсли;
Текст = "" + СчетчикЯчеекСуммы + " из " + СчетчикЯчеекОбщий + " яч. = " + Сумма + "";
Возврат Текст;
КонецФункции
// Параметры:
// Таблица - ТаблицаЗначений - может быть модифицирована здесь, поэтому нужно передавать копию, если нужна неизменность
Функция ВывестиТаблицуВТабличныйДокументИлиТаблицуЗначенийЛкс(ТаблицаЗначений, Знач Приемник = Неопределено, ДанныеРасшифровки = Неопределено, ИтогиЧисловыхКолонок = Истина,
АвтофиксацияШапки = Истина, ВстроитьЗначенияВРасшифровки = Истина, ОтображатьПустые = Ложь, ДобавлятьКолонкиИдентификаторов = Ложь, ДобавлятьКолонкиТипов = Ложь,
ДобавлятьКолонкиПредставлений = Истина, Знач ВыбранныеКолонки = Неопределено, ИмяТекущейКолонки = "", ВыводВТаблицуЗначений = Ложь, Отладка = Ложь, ДобавлятьКолонкиРазмеров = Ложь,
СузитьТипы = Ложь) Экспорт
ТребоватьТипЛкс(ТаблицаЗначений,, Тип("ТаблицаЗначений"));
ирПлатформа = ирКэш.Получить();
Если ДобавлятьКолонкиТипов Или ДобавлятьКолонкиИдентификаторов Тогда
//ТаблицаЗначений = ТаблицаСКолонкамиБезТипаNullЛкс(ТаблицаЗначений);
ТаблицаЗначений = ТаблицаСМинимальнымиТипамиКолонокЛкс(ТаблицаЗначений);
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ирПлатформа = Обработки.ирПлатформа.Создать();
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
ВнешниеНаборыДанных = Новый Структура("Основной", ТаблицаЗначений);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
КолонкиИдентификаторов = Новый Массив;
КолонкиТипов = Новый Массив;
КолонкиРазмеров = Новый Массив;
Если ВыбранныеКолонки = Неопределено Тогда
ВыбранныеКолонки = Новый Массив;
Для Каждого Колонка Из КолонкиИсточникаДанныхЛкс(ТаблицаЗначений) Цикл
ВыбранныеКолонки.Добавить(Колонка.Имя);
КонецЦикла;
КонецЕсли;
//ПримитивныеТипы = Новый Массив;
//ПримитивныеТипы.Добавить(Тип("Число"));
//ПримитивныеТипы.Добавить(Тип("Строка"));
//ПримитивныеТипы.Добавить(Тип("Дата"));
//ПримитивныеТипы.Добавить(Тип("Булево"));
//ПримитивныеТипы.Добавить(Тип("Неопределено"));
//ПримитивныеТипы.Добавить(Тип("Null"));
//ПримитивныеТипы.Добавить(Тип("УникальныйИдентификатор"));
ИменаТипов = Новый Структура;
ПозицииКолонок = Новый Структура;
ИндексТекущейКолонки = 0;
Для Каждого ВыбраннаяКолонка Из ВыбранныеКолонки Цикл
Если Не ЗначениеЗаполнено(ВыбраннаяКолонка) Тогда
Продолжить;
КонецЕсли;
ИмяКолонки = СтрЗаменить(ВыбраннаяКолонка, ".", "_");
Колонка = ТаблицаЗначений.Колонки.Найти(ИмяКолонки);
Если Колонка = Неопределено Тогда
// Например "ИдентификаторСсылкиЛкс" в таблице формы
Продолжить;
КонецЕсли;
ТипыКолонки = Колонка.ТипЗначения.Типы();
ПозицииКолонок.Вставить(Колонка.Имя, НастройкаКомпоновки.Выбор.Элементы.Количество());
Если ДобавлятьКолонкиПредставлений Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ВыбраннаяКолонка);
КонецЕсли;
Если Ложь
Или ОтображатьПустые
Или (Истина
И ДобавлятьКолонкиТипов
И ТипыКолонки.Количество() > 1)
Тогда
КолонкиТипов.Добавить(Колонка.Имя);
ТаблицаЗначений.Колонки.Вставить(ТаблицаЗначений.Колонки.Индекс(Колонка) + 1, ИмяКолонки + "_ИмяТипаЗначения_", Новый ОписаниеТипов("Строка"),
Колонка.Заголовок + " (тип)");
Если ДобавлятьКолонкиТипов Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ИмяКолонки + "_ИмяТипаЗначения_");
КонецЕсли;
ИменаТиповКолонки = Новый Соответствие;
Для Каждого Тип Из ТипыКолонки Цикл
ИменаТиповКолонки.Вставить(Тип, ПредставлениеТипаЛкс(Тип, Колонка.ТипЗначения, Истина));
КонецЦикла;
ИменаТипов.Вставить(Колонка.Имя, ИменаТиповКолонки);
КонецЕсли;
Если ДобавлятьКолонкиИдентификаторов Тогда
ЕстьСсылочныйТип = ТипыКолонки.Количество() = 0;
Если Не ЕстьСсылочныйТип Тогда
Для Каждого Тип Из ТипыКолонки Цикл
Если ЛиТипСсылкиБДЛкс(Тип, Ложь) Тогда
ЕстьСсылочныйТип = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЕстьСсылочныйТип Тогда
Если ИндексТекущейКолонки = 0 И ЗначениеЗаполнено(ИмяТекущейКолонки) И СтрокиРавныЛкс(ВыбраннаяКолонка, ИмяТекущейКолонки) Тогда
ИндексТекущейКолонки = НастройкаКомпоновки.Выбор.Элементы.Количество();
КонецЕсли;
КолонкиИдентификаторов.Добавить(Колонка.Имя);
ТаблицаЗначений.Колонки.Вставить(ТаблицаЗначений.Колонки.Индекс(Колонка) + 1, ИмяКолонки + "_ИдентификаторЗначения_", Новый ОписаниеТипов("Строка"),
Колонка.Заголовок + " (идентификатор)");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ИмяКолонки + "_ИдентификаторЗначения_");
КонецЕсли;
КонецЕсли;
Если ДобавлятьКолонкиРазмеров Тогда
Если Ложь
Или Колонка.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения"))
Или (Истина
И Колонка.ТипЗначения.СодержитТип(Тип("Строка"))
И Колонка.ТипЗначения.КвалификаторыСтроки.ДопустимаяДлина = 0)
Тогда
Если ИндексТекущейКолонки = 0 И ЗначениеЗаполнено(ИмяТекущейКолонки) И СтрокиРавныЛкс(ВыбраннаяКолонка, ИмяТекущейКолонки) Тогда
ИндексТекущейКолонки = НастройкаКомпоновки.Выбор.Элементы.Количество();
КонецЕсли;
КолонкиРазмеров.Добавить(Колонка.Имя);
ТаблицаЗначений.Колонки.Вставить(ТаблицаЗначений.Колонки.Индекс(Колонка) + 1, ИмяКолонки + "_РазмерЗначения_", Новый ОписаниеТипов("Число"),
Колонка.Заголовок + " (размер)");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ИмяКолонки + "_РазмерЗначения_");
КонецЕсли;
КонецЕсли;
Если ОтображатьПустые Тогда
ПустыеЗначения = Новый Массив;
ПустыеЗначения.Добавить(Неопределено);
ПустыеЗначения.Добавить(0);
ПустыеЗначения.Добавить(Дата(1,1,1));
ПустыеЗначения.Добавить(Ложь);
ПустыеЗначения.Добавить("");
Для Каждого ПустоеЗначение Из ПустыеЗначения Цикл
Если Ложь
Или Колонка.ТипЗначения.Типы().Количество() = 0
Или Колонка.ТипЗначения.СодержитТип(ТипЗнч(ПустоеЗначение))
Тогда
ЭлементУсловногоОформления = НастройкаКомпоновки.УсловноеОформление.Элементы.Добавить();
ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("Текст", ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ПустоеЗначение));
//ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", ЦветФонаЯчеекПустыхЗначенийЛкс());
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ВыбраннаяКолонка, , ВидСравненияКомпоновкиДанных.НеЗаполнено);
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ВыбраннаяКолонка, ПустоеЗначение, ВидСравненияКомпоновкиДанных.Равно);
ПолеЭлементаОформления = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
ПолеЭлементаОформления.Поле = Новый ПолеКомпоновкиДанных(ВыбраннаяКолонка);
КонецЕсли;
КонецЦикла;
// Отдельно для особенного Null
ПустоеЗначение = Null;
Если Истина
И Колонка.ТипЗначения.Типы().Количество() > 0
И Колонка.ТипЗначения.СодержитТип(ТипЗнч(ПустоеЗначение))
Тогда
ЭлементУсловногоОформления = НастройкаКомпоновки.УсловноеОформление.Элементы.Добавить();
ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("Текст", ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ПустоеЗначение));
//ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", ЦветФонаЯчеекПустыхЗначенийЛкс());
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ИмяКолонки + "_ИмяТипаЗначения_", "Null", ВидСравненияКомпоновкиДанных.Равно);
ПолеЭлементаОформления = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
ПолеЭлементаОформления.Поле = Новый ПолеКомпоновкиДанных(ВыбраннаяКолонка);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Ложь
Или КолонкиТипов.Количество() > 0
Или КолонкиИдентификаторов.Количество() > 0
Или КолонкиРазмеров.Количество() > 0
Тогда
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаЗначений.Количество(), "Заполнение доп. колонок");
Для Каждого СтрокаТаблицы Из ТаблицаЗначений Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор); // добавляет значительную долю длительности цикла
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Для Каждого ИмяКолонки Из КолонкиТипов Цикл
Если Ложь
Или ДобавлятьКолонкиТипов
Или СтрокаТаблицы[ИмяКолонки] = Null
Тогда
СтрокаТаблицы[ИмяКолонки + "_ИмяТипаЗначения_"] = ИменаТипов[ИмяКолонки][ТипЗнч(СтрокаТаблицы[ИмяКолонки])];
КонецЕсли;
КонецЦикла;
Если ДобавлятьКолонкиИдентификаторов Тогда
Для Каждого ИмяКолонки Из КолонкиИдентификаторов Цикл
СтрокаТаблицы[ИмяКолонки + "_ИдентификаторЗначения_"] = СтроковыйИдентификаторЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]);
КонецЦикла;
КонецЕсли;
Если ДобавлятьКолонкиРазмеров Тогда
Для Каждого ИмяКолонки Из КолонкиРазмеров Цикл
СтрокаТаблицы[ИмяКолонки + "_РазмерЗначения_"] = РазмерЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]);
КонецЦикла;
КонецЕсли;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Каждого ИмяКолонки Из КолонкиТипов Цикл Если Ложь Или ДобавлятьКолонкиТипов Или СтрокаТаблицы[ИмяКолонки] = Null Тогда СтрокаТаблицы[ИмяКолонки + "_ИмяТипаЗначения_"] = ИменаТипов[ИмяКолонки][ТипЗнч(СтрокаТаблицы[ИмяКолонки])]; КонецЕсли; КонецЦикла; Если ДобавлятьКолонкиИдентификаторов Тогда Для Каждого ИмяКолонки Из КолонкиИдентификаторов Цикл СтрокаТаблицы[ИмяКолонки + "_ИдентификаторЗначения_"] = СтроковыйИдентификаторЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]); КонецЦикла; КонецЕсли; Если ДобавлятьКолонкиРазмеров Тогда Для Каждого ИмяКолонки Из КолонкиРазмеров Цикл СтрокаТаблицы[ИмяКолонки + "_РазмерЗначения_"] = РазмерЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]); КонецЦикла; КонецЕсли;
КонецЦикла;
КонецЕсли;
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура);
КонецЕсли;
СхемаКомпоновки = СоздатьСхемуПоТаблицамЗначенийЛкс(ВнешниеНаборыДанных, , , ИтогиЧисловыхКолонок);
Если Отладка Тогда
ОтладитьЛкс(СхемаКомпоновки, , НастройкаКомпоновки, ВнешниеНаборыДанных);
Возврат Неопределено;
КонецЕсли;
Если ВыводВТаблицуЗначений Тогда
Приемник = СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки, Приемник, ВнешниеНаборыДанных,,,,,,, СузитьТипы);
//Приемник = ТаблицаЗначений.Скопировать(, "...");
Иначе
Приемник = СкомпоноватьВТабличныйДокументЛкс(СхемаКомпоновки, НастройкаКомпоновки, Приемник, ВнешниеНаборыДанных, ДанныеРасшифровки, АвтофиксацияШапки,, ВстроитьЗначенияВРасшифровки);
#Если Сервер И Не Сервер Тогда
Приемник = Новый ТабличныйДокумент;
#КонецЕсли
Если ЗначениеЗаполнено(ИмяТекущейКолонки) И ВыбранныеКолонки.Найти(ИмяТекущейКолонки) <> Неопределено Тогда
Приемник.ТекущаяОбласть = Приемник.Область(2, ПозицииКолонок[ИмяТекущейКолонки] + 1);
КонецЕсли;
Для Счетчик = 1 По ВыбранныеКолонки.Количество() Цикл
ИмяКолонки = ВыбранныеКолонки[Счетчик - 1];
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Продолжить;
КонецЕсли;
Колонка = ТаблицаЗначений.Колонки.Найти(ИмяКолонки);
Если Колонка <> Неопределено Тогда
Приемник.Область(1, ПозицииКолонок[ИмяКолонки] + 1).Примечание.Текст = "Типы значений: " + РасширенноеПредставлениеЗначенияЛкс(Колонка.ТипЗначения);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Приемник;
КонецФункции
Функция СкомпоноватьВТабличныйДокументЛкс(СхемаКомпоновки, НастройкаКомпоновки, Знач ТабличныйДокумент = Неопределено, ВнешниеНаборыДанных = Неопределено,
ДанныеРасшифровки = Неопределено, АвтофиксацияШапки = Истина, ПроверятьДоступностьПолей = Ложь, ВстроитьЗначенияПолейВРасшифровки = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура);
КонецЕсли;
Если ДанныеРасшифровки = Неопределено Тогда
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
КонецЕсли;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, НастройкаКомпоновки, ДанныеРасшифровки,,, ПроверятьДоступностьПолей);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина);
Если ТабличныйДокумент = Неопределено Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
КонецЕсли;
ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(ТабличныйДокумент, ПроцессорКомпоновки, ДанныеРасшифровки.Элементы,,, АвтофиксацияШапки);
Если ВстроитьЗначенияПолейВРасшифровки Тогда
Для НомерСтроки = 1 По ТабличныйДокумент.ВысотаТаблицы Цикл
Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Ячейка = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
ИдентификаторРасшифровки = Ячейка.Расшифровка;
Если ТипЗнч(ИдентификаторРасшифровки) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
ЗначенияПолей = ДанныеРасшифровки.Элементы[ИдентификаторРасшифровки].ПолучитьПоля();
Если ЗначенияПолей.Количество() > 0 Тогда
Ячейка.Расшифровка = ЗначенияПолей[0].Значение;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
Возврат ТабличныйДокумент;
КонецФункции
Функция ДополнительныеДействияРасшифровкиКомпоновкиЛкс(Знач ЭлементРасшифровки, выхКоличествоСсылочныхПолей = 0) Экспорт
#Если Сервер И Не Сервер Тогда
ЭлементРасшифровки = Новый ЭлементРасшифровкиКомпоновкиДанныхПоля;
#КонецЕсли
ДополнительныеПунктыМеню = Новый СписокЗначений;
выхКоличествоСсылочныхПолей = 0;
Для каждого ЗначениеПоля Из ЭлементРасшифровки.ПолучитьПоля() Цикл
ЗначениеПоляЗначение = ЗначениеПоля.Значение;
ПорогДлины = 100;
ПредставлениеЗначения = ПредставлениеЗначенияСОграничениемДлиныЛкс(ЗначениеПоляЗначение, ПорогДлины);
Если ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение) Тогда
ДополнительныеПунктыМеню.Добавить(Новый Структура("Ссылка, ОткрытьВРедактореОбъектаБД", ЗначениеПоля.Значение), "Открыть """ + ЗначениеПоля.Поле + " = " + ПредставлениеЗначения + """",
, ирКэш.КартинкаПоИмениЛкс("ирРедактироватьОбъектБД"));
выхКоличествоСсылочныхПолей = выхКоличествоСсылочныхПолей + 1;
КонецЕсли;
ДополнительныеПунктыМеню.Добавить(Новый Структура("Значение, Открыть", ЗначениеПоля.Значение), "Открыть """ + ЗначениеПоля.Поле + " = " + ПредставлениеЗначения + """",
, ирОбщий.ПолучитьПиктограммуТипаЛкс(ТипЗнч(ЗначениеПоля.Значение)));
КонецЦикла;
Возврат ДополнительныеПунктыМеню;
КонецФункции
Процедура ОбработатьДополнительноеДействиеРасшифровкиКомпоновкиЛкс(Знач ВыбранноеДействие, СтандартнаяОбработка) Экспорт
Если ТипЗнч(ВыбранноеДействие) = Тип("Структура") Тогда
Если ВыбранноеДействие.Свойство("Открыть") Тогда
ирОбщий.ОткрытьЗначениеЛкс(ВыбранноеДействие.Значение, Ложь, СтандартнаяОбработка);
ИначеЕсли ВыбранноеДействие.Свойство("ОткрытьВРедактореОбъектаБД") Тогда
ирОбщий.ОткрытьСсылкуВРедактореОбъектаБДЛкс(ВыбранноеДействие.Ссылка);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Параметры:
// ОтчетОбъект - Форма, ОтчетОбъект
Процедура ОтчетКомпоновкиОбработкаРасшифровкиЛкс(Знач ОтчетОбъект, Знач Расшифровка, СтандартнаяОбработка, ДополнительныеПараметры, ПолеТабличногоДокумента, ДанныеРасшифровки,
Авторасшифровка = Ложь) Экспорт
#Если _ Тогда
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
ЭлементРасшифровки = ДанныеРасшифровки.Элементы[0];
ТабличныйДокумент = Новый ТабличныйДокумент;
ОтчетОбъект = Отчеты.ирАнализЗамераПроизводительности.Создать();
#КонецЕсли
Если ТипЗнч(Расшифровка) <> Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
//Возврат;
КонецЕсли;
ЭлементРасшифровки = ДанныеРасшифровки.Элементы[Расшифровка];
ДоступныеДействия = Новый Массив;
РазрешитьАвтовыборДействия = Истина;
ПараметрВыбранногоДействия = Неопределено;
КоличествоСсылочныхПолей = 0;
СписокДополнительныхДействий = ДополнительныеДействияРасшифровкиКомпоновкиЛкс(ЭлементРасшифровки, КоличествоСсылочныхПолей);
#Если Сервер И Не Сервер Тогда
СписокДополнительныхДействий = Новый СписокЗначений;
#КонецЕсли
КоличествоОбщихДействий = СписокДополнительныхДействий.Количество();
ЗначенияВсехПолей = Новый Соответствие;
ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(ЭлементРасшифровки,, ЗначенияВсехПолей);
Для Каждого ЭлементОтбора Из ДанныеРасшифровки.Настройки.Отбор.Элементы Цикл
Если Ложь
Или Не ЭлементОтбора.Использование
Или ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
Или ЭлементОтбора.ВидСравнения <> ВидСравненияКомпоновкиДанных.Равно
Или ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("ПолеКомпоновкиДанных")
Тогда
Продолжить;
КонецЕсли;
ЗначенияВсехПолей["" + ЭлементОтбора.ЛевоеЗначение] = ЭлементОтбора.ПравоеЗначение;
КонецЦикла;
Если ирОбщий.МетодРеализованЛкс(ОтчетОбъект, "ОбработкаРасшифровки") Тогда
ОтчетОбъект.ОбработкаРасшифровки(ДанныеРасшифровки, ЭлементРасшифровки, ПолеТабличногоДокумента, ДоступныеДействия, СписокДополнительныхДействий, РазрешитьАвтовыборДействия, ЗначенияВсехПолей);
КонецЕсли;
Если Истина
И РазрешитьАвтовыборДействия
И Авторасшифровка
И (ЛОжь
ИЛи СписокДополнительныхДействий.Количество() - КоличествоОбщихДействий = 1
Или СписокДополнительныхДействий.Количество() - КоличествоОбщихДействий = 0 И КоличествоСсылочныхПолей = 1)
Тогда
ВыбранноеДействие = СписокДополнительныхДействий[0].Значение;
КонецЕсли;
Если ВыбранноеДействие = Неопределено Тогда
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(ОтчетОбъект.СхемаКомпоновкиДанных);
ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, ИсточникДоступныхНастроек);
ОбработкаРасшифровки.ВыбратьДействие(Расшифровка, ВыбранноеДействие, ПараметрВыбранногоДействия, ДоступныеДействия, СписокДополнительныхДействий, Авторасшифровка);
КонецЕсли;
Если ВыбранноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.Нет Тогда
СтандартнаяОбработка = Ложь;
//Возврат;
КонецЕсли;
Если ПараметрВыбранногоДействия = Неопределено Тогда
ПараметрВыбранногоДействия = ЗначенияВсехПолей;
КонецЕсли;
ОбработатьДополнительноеДействиеРасшифровкиКомпоновкиЛкс(ВыбранноеДействие, СтандартнаяОбработка);
Если ирОбщий.МетодРеализованЛкс(ОтчетОбъект, "ДействиеРасшифровки") Тогда
ОтчетОбъект.ДействиеРасшифровки(ВыбранноеДействие, ПараметрВыбранногоДействия, СтандартнаяОбработка);
КонецЕсли;
Если СтандартнаяОбработка Тогда
Если ВыбранноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение Тогда
ОткрытьЗначение(ПараметрВыбранногоДействия);
ИначеЕсли ТипЗнч(ВыбранноеДействие) = Тип("ДействиеОбработкиРасшифровкиКомпоновкиДанных") Тогда
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(ОтчетОбъект.СхемаКомпоновкиДанных);
ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, ИсточникДоступныхНастроек);
НовыеНастройки = ОбработкаРасшифровки.ПрименитьНастройки(Расшифровка, ПараметрВыбранногоДействия);
ОтчетОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(НовыеНастройки);
ОтчетОбъект.СкомпоноватьРезультат(ПолеТабличногоДокумента);
КонецЕсли;
КонецЕсли;
СтандартнаяОбработка = Ложь;
КонецПроцедуры
Функция ВыбратьТипСсылкиВПолеВводаЛкс(Элемент, СтандартнаяОбработка, ОткрытьФормуВыбораСсылкиПослеВыбораТипа = Ложь) Экспорт
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", Элемент, Элемент);
ТекущееЗначение = ДанныеЭлементаФормыЛкс(Элемент);
Если ЛиСсылкаНаОбъектБДЛкс(ТекущееЗначение, Ложь) Тогда
НачальноеЗначениеВыбора = ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ТекущееЗначение));
КонецЕсли;
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина);
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
ЗначениеВыбора = Форма.ОткрытьМодально();
Если ТипЗнч(ЗначениеВыбора) = Тип("Структура") Тогда
лПолноеИмяОбъекта = Неопределено;
Если ЗначениеВыбора.Свойство("ПолноеИмяОбъекта", лПолноеИмяОбъекта) Тогда
ИмяТипаСсылки = ИмяТипаИзПолногоИмениМДЛкс(лПолноеИмяОбъекта, "Ссылка");
ОписаниеТипов = Новый ОписаниеТипов(ИмяТипаСсылки);
НовоеЗначение = ОписаниеТипов.ПривестиЗначение(Неопределено);
ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, НовоеЗначение);
// // http://www.hostedredmine.com/issues/884276
//Если ОткрытьФормуВыбораСсылкиПослеВыбораТипа Тогда
// //Если ЛиСсылкаНаОбъектБДЛкс(НовоеЗначение, Ложь) Тогда
// ОткрытьФормуСпискаЛкс(лПолноеИмяОбъекта,,, Элемент, Истина);
// //КонецЕсли;
//КонецЕсли;
КонецЕсли;
КонецЕсли;
СтандартнаяОбработка = Ложь;
Возврат НовоеЗначение;
КонецФункции
// Результат - значение выбранного типа, но не обязательно выбранное (выбор типа выполняется синхронно, а значения - асинхронно)
Функция ПолеВвода_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка, ИгнорироватьОписаниеТипов = Ложь) Экспорт
РезультатВыбора = ДанныеЭлементаФормыЛкс(Элемент);
Если Истина
И ИгнорироватьОписаниеТипов
И (Ложь
Или ТипЗнч(РезультатВыбора) = Тип("Строка")
Или РезультатВыбора = Неопределено)
Тогда
Типы = Элемент.ОграничениеТипа.Типы();
Если Типы.Количество() = 1 Тогда
// Ссылка внешнего источника данных
СтандартнаяОбработка = Ложь;
ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(Типы[0]),,, Элемент, Истина,, РезультатВыбора);
Иначе
РезультатВыбора = ВыбратьТипСсылкиВПолеВводаЛкс(Элемент, СтандартнаяОбработка);
КонецЕсли;
ИначеЕсли ЛиСсылкаНаОбъектБДЛкс(РезультатВыбора, Ложь) Тогда
СтандартнаяОбработка = Ложь;
Отбор = Новый Структура;
Если ТипЗнч(Элемент) = Тип("ПолеВвода") И Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(РезультатВыбора)) Тогда
Если ЗначениеЗаполнено(Элемент.ВыборПоВладельцу) Тогда
Отбор.Вставить("Владелец", Элемент.ВыборПоВладельцу);
КонецЕсли;
КонецЕсли;
ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РезультатВыбора)), Отбор,, Элемент, Истина,, РезультатВыбора);
Иначе
// Тут надо делать выбор из диалога плоского списка типов
КонецЕсли;
Возврат РезультатВыбора;
КонецФункции
Функция ДобавитьМногострочнуюСтрокуВТекстЛкс(ТекстПриемник, СтрокаДляВставки, Смещение, СНовойСтроки = Ложь, ОбрезатьЛевыеПустые = Ложь) Экспорт
Если Не ЗначениеЗаполнено(ТекстПриемник) Тогда
ТекстПриемник = "";
КонецЕсли;
ЗаписьТекста = Новый ЗаписьXML;
ЗаписьТекста.УстановитьСтроку();
Если СНовойСтроки Тогда
ЗаписьТекста.ЗаписатьБезОбработки(Символы.ПС + Смещение);
КонецЕсли;
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(СтрокаДляВставки);
ЗаписьТекста.ЗаписатьБезОбработки(ТекстовыйДокумент.ПолучитьСтроку(1));
Для Счетчик = 2 По ТекстовыйДокумент.КоличествоСтрок() Цикл
ТекущаяСтрока = ТекстовыйДокумент.ПолучитьСтроку(Счетчик);
Если ОбрезатьЛевыеПустые Тогда
ТекущаяСтрока = СокрЛ(ТекущаяСтрока);
КонецЕсли;
ЗаписьТекста.ЗаписатьБезОбработки(Символы.ПС + Смещение + ТекущаяСтрока);
КонецЦикла;
ТекстПриемник = ТекстПриемник + ЗаписьТекста.Закрыть();
Возврат ТекстПриемник;
КонецФункции
Функция ПолучитьИндексКартинкиТипаЛкс(ОписаниеТипов) Экспорт
Если ОписаниеТипов = Неопределено Тогда
Возврат 14;
КонецЕсли;
Типы = ОписаниеТипов.Типы();
Если Типы.Количество() = 1 Тогда
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(Типы[0]);
Если Типы[0] = Тип("Число") Тогда
ИндексКартинки = 0;
ИначеЕсли Типы[0] = Тип("Строка") Тогда
ИндексКартинки = 1;
ИначеЕсли Типы[0] = Тип("Дата") Тогда
ИндексКартинки = 2;
ИначеЕсли Типы[0] = Тип("Булево") Тогда
ИндексКартинки = 3;
ИначеЕсли Типы[0] = Тип("ТаблицаЗначений") Тогда
ИндексКартинки = 19;
ИначеЕсли Типы[0] = Тип("Тип") Тогда
ИндексКартинки = 20;
ИначеЕсли Типы[0] = Тип("УникальныйИдентификатор") Тогда
ИндексКартинки = 21;
ИначеЕсли Типы[0] = Тип("ХранилищеЗначения") Тогда
ИндексКартинки = 22;
ИначеЕсли КорневойТип = "Справочник" Тогда
ИндексКартинки = 7;
ИначеЕсли КорневойТип = "Документ" Тогда
ИндексКартинки = 8;
ИначеЕсли КорневойТип = "Перечисление" Тогда
ИндексКартинки = 9;
ИначеЕсли КорневойТип = "ПланВидовХарактеристик" Тогда
ИндексКартинки = 10;
ИначеЕсли КорневойТип = "ПланСчетов" Тогда
ИндексКартинки = 11;
ИначеЕсли КорневойТип = "ПланВидовРасчета" Тогда
ИндексКартинки = 12;
ИначеЕсли КорневойТип = "БизнесПроцесс" Тогда
ИндексКартинки = 13;
ИначеЕсли КорневойТип = "ТочкаМаршрута" Тогда
ИндексКартинки = 14;
ИначеЕсли КорневойТип = "Задача" Тогда
ИндексКартинки = 13;
ИначеЕсли КорневойТип = "ПланОбмена" Тогда
ИндексКартинки = 15;
Иначе
ИндексКартинки = 16;
КонецЕсли;
Иначе
ИндексКартинки = 16;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции
Функция ПроверитьПодпискиЛкс() Экспорт
Результат = Истина;
// Проверка компиляции общих модулей с обработчиками событий
СписокМодулей = Новый Структура;
СписокМодулейВызоваСервера = Новый Структура;
ОбщиеМодули = Метаданные.ОбщиеМодули;
#Если ТолстыйКлиентУправляемоеПриложение Тогда
ИмяКлиента = "Управляемое";
#Иначе
ИмяКлиента = "Обычное";
#КонецЕсли
ИмяСвойства = "Клиент" + ИмяКлиента + "Приложение";
Для Каждого Подписка Из Метаданные.ПодпискиНаСобытия Цикл
#Если Сервер И Не Сервер Тогда
Подписка = Метаданные.ПодпискиНаСобытия.ВерсионированиеОбъектов_ПриЗаписиОбъекта;
#КонецЕсли
МетаМодуль = ОбщиеМодули.Найти(ирОбщий.ПервыйФрагментЛкс(Подписка.Обработчик));
Если МетаМодуль = Неопределено Тогда
// Некорректная подписка
Продолжить;
КонецЕсли;
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
// Проверяем только подписки менеджеров
Если Не МетаМодуль[ИмяСвойства] И Не МетаМодуль.ВызовСервера Тогда
ТипыИсточников = Подписка.Источник.Типы(); // Долго!
Если ТипыИсточников.Количество() > 0 И Не ирОбщий.ЛиТипОбъектаБДЛкс(ТипыИсточников[0]) Тогда // Это подписка менеджера
СписокМодулей.Вставить(МетаМодуль.Имя);
КонецЕсли;
КонецЕсли;
Иначе
// Проверяем все подписки в портативном режиме обычном приложении
Если Не МетаМодуль[ИмяСвойства] Тогда
СписокМодулей.Вставить(МетаМодуль.Имя);
КонецЕсли;
КонецЕсли;
Если Подписка.Событие = "ОбработкаПолученияПредставления" И МетаМодуль.ВызовСервера Тогда
СписокМодулейВызоваСервера.Вставить(МетаМодуль.Имя);
КонецЕсли;
КонецЦикла;
Если СписокМодулей.Количество() > 0 Тогда
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ТипыОбъектовПодписок = "";
Иначе
ТипыОбъектовПодписок = " менеджеров";
КонецЕсли;
СообщитьЛкс("В конфигурации обнаружены недоступные на клиенте (" + ИмяКлиента + " приложение) общие модули с обработчиками подписок на события" + ТипыОбъектовПодписок + ".", СтатусСообщения.Внимание);
СообщитьЛкс("Поэтому в работе некоторых инструментов возможны ошибки ""При подписке * на событие * произошла ошибка. Обработчик события не найден.""");
Если ИмяКлиента = "Обычное" Тогда
СообщитьЛкс("Необходимо в конфигураторе установить ""Сервис""/""Параметры""/""Редактирование конфигурации для режимов запуска""=""Управляемое приложение и обычное приложение"".");
КонецЕсли;
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
ТекстСообщения = "Рекомендуется установить флажок ""Вызова сервера"" или ""Клиент (" + ИмяКлиента + " приложение)"" и обеспечить компиляцию у этих общих модулей:";
Иначе
ТекстСообщения = "Рекомендуется установить флажок ""Клиент (" + ИмяКлиента + " приложение)"" и обеспечить компиляцию у этих общих модулей:";
КонецЕсли;
Для Каждого КлючИЗначение Из СписокМодулей Цикл
ТекстСообщения = ТекстСообщения + " " + КлючИЗначение.Ключ + ",";
КонецЦикла;
СообщитьЛкс(ТекстСообщения);
Результат = Ложь;
КонецЕсли;
Если СписокМодулейВызоваСервера.Количество() > 0 Тогда
СообщитьЛкс("В конфигурации обнаружены недоступные на клиенте (" + ИмяКлиента + " приложение) общие модули с обработчиками подписок на событие ""ОбработкаПолученияПредставления"".", СтатусСообщения.Внимание);
СообщитьЛкс("Это может приводить к сильному замеделению получения представлений таких ссылок. Поэтому перенесите эти обработчики в модуль, компилируемый на толстых клиентах");
Для Каждого КлючИЗначение Из СписокМодулей Цикл
ТекстСообщения = ТекстСообщения + " " + КлючИЗначение.Ключ + ",";
КонецЦикла;
СообщитьЛкс(ТекстСообщения);
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
// Тяжелый метод. Попытка-Исключение в 5-10 раз быстрее.
Функция ЕстьСвойствоОбъектаЛкс(Объект, Свойство) Экспорт
УникальноеЗначение = "м86ыщшру5аа7шлв9823454";
Структура = Новый Структура(Свойство, УникальноеЗначение);
ЗаполнитьЗначенияСвойств(Структура, Объект);
Результат = Структура[Свойство] <> УникальноеЗначение;
Возврат Результат;
КонецФункции
////////////////////////////////
// ФОРМЫ
Процедура ИнициализироватьФормуЛкс(ЭтаФорма, ПолноеИмяФормы, РазрешитьОткрытиеДополнительныхФорм = Истина) Экспорт
// Проверяем режим модальности
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ОткрыватьФормуПерезапуска = Ложь;
ЛиМодальностьЗапрещена = ирКэш.ЛиМодальностьЗапрещенаЛкс();
Если Ложь
Или ирКэш.НомерИзданияПлатформыЛкс() = "82"
Или мПлатформа.мВопросОтключенияПроверкиМодальностиЗадавался = Истина
Или Метаданные.РежимИспользованияМодальности = Метаданные.СвойстваОбъектов.РежимИспользованияМодальности.Использовать
Тогда
//
ИначеЕсли РазрешитьОткрытиеДополнительныхФорм Тогда
ИдентификаторПроцессаОС = мПлатформа.ИдентификаторПроцессаОС();
ТекущийПроцесс = ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2:Win32_Process.Handle='" + XMLСтрока(ИдентификаторПроцессаОС) + "'");
КоманднаяСтрокаПроцесса = ТекущийПроцесс.CommandLine;
мПлатформа.мВопросОтключенияПроверкиМодальностиЗадавался = Истина;
Если Ложь
Или Найти(КоманднаяСтрокаПроцесса, "/EnableCheckModal") > 0
//Или Найти(КоманднаяСтрокаПроцесса, "/EnableCheckExtensionsAndAddInsSyncCalls") > 0
Тогда
СообщитьЛкс("При запуске сеанса из конфигуратора с текущим свойством конфигурации ""Режим использования модальности"" включается контроль модальности. Для его отключения рекомендуется перезапустить сеанс через открывшуюся форму.",
СтатусСообщения.Внимание);
ОткрыватьФормуПерезапуска = Истина;
КонецЕсли;
КонецЕсли;
// Проверяем защиту от опасных действий
// Здесь это делать мало полезно, т.к. она срабатывает раньше
Если Истина
И РазрешитьОткрытиеДополнительныхФорм
И ирКэш.ЛиПортативныйРежимЛкс()
И мПлатформа.мПроверкаЗащитыОтОпасныхДействийВыполнялась <> Истина
//И ирКэш.НомерВерсииПлатформыЛкс() < 803010 // Когда в платформе исправят проблему, тогда и отключим
Тогда
ТекущийПользовательБазы = ПользователиИнформационнойБазы.ТекущийПользователь();
Попытка
ЗащитаОтОпасныхДействий = ТекущийПользовательБазы.ЗащитаОтОпасныхДействий;
Исключение
ЗащитаОтОпасныхДействий = Неопределено;
КонецПопытки;
Если Истина
И ЗначениеЗаполнено(ТекущийПользовательБазы.Имя)
И ЗащитаОтОпасныхДействий <> Неопределено
И ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Истина
Тогда
СообщитьЛкс("У текущего пользователя базы включена защита от опасных действий. Для корректной работы инструментов ее рекомендуется отключить перезапуском сеанса через открывшуюся форму.", СтатусСообщения.Внимание);
ОткрыватьФормуПерезапуска = Истина;
КонецЕсли;
мПлатформа.мПроверкаЗащитыОтОпасныхДействийВыполнялась = Истина;
КонецЕсли;
Если ОткрыватьФормуПерезапуска Тогда
#Если ТолстыйКлиентОбычноеПриложение Тогда
ОткрытьФормуЛкс("Обработка.ирПортативный.Форма.ПерезапускСеансаОбычная");
#Иначе
ОткрытьФормуЛкс("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#КонецЕсли
КонецЕсли;
Если ЛиМодальностьЗапрещена Тогда
ВызватьИсключение "При запуске сеанса из конфигуратора с текущим свойством конфигурации ""Режим использования модальности"" включается контроль модальности.
|Рекомендуется изменить это свойство конфигурации либо запустить сеанс другим способом.";
КонецЕсли;
мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
мСвойстваФормы.Вставить("МенеджерСохраненияНастроек");
мСвойстваФормы.Вставить("ИмяФормы", ПолноеИмяФормы);
мСвойстваФормы.Вставить("НеготовыеСтраницы", Новый СписокЗначений);
мСвойстваФормы.Вставить("Задания", Новый Структура);
НастроитьЭлементыФормыЛкс(ЭтаФорма);
Форма_ВставитьСкрытуюКоманднуюПанельГлобальныхКомандЛкс(ЭтаФорма);
ПерехватКлавиатуры = мПлатформа.ПодключитьПерехватКлавиатуры();
СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
СлужебныеДанныеФормы.Вставить("ПерехватКлавиатуры", ПерехватКлавиатуры);
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
Контейнер = Новый Структура();
ирОбщий.ОповеститьФормыПодсистемыЛкс("ирПолучитьБазовуюФорму", Контейнер); // Скорость https://www.hostedredmine.com/issues/891484
Если Не Контейнер.Свойство("ирПортативный") Тогда
БазоваяФорма = ирПортативный.ПолучитьФорму();
БазоваяФорма.Открыть();
КонецЕсли;
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтрокаВызова = "ирПортативный.ИнициализироватьФорму_" + мПлатформа.ИдентификаторИзПредставленияЛкс(ПолноеИмяФормы) + "(ЭтаФорма)";
Выполнить(СтрокаВызова);
Иначе
МетаФорма = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяФормы);
Если МетаФорма = Неопределено Тогда
СообщитьЛкс("Метаформа не найдена по полному имени """ + ПолноеИмяФормы + """", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
ФлажокОбъектыНаСервере = ЭтаФорма.ЭлементыФормы.Найти("ОбъектыНаСервере");
Если ФлажокОбъектыНаСервере <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ирПортативный = Обработки.ирПортативный.Создать();
#КонецЕсли
ФлажокОбъектыНаСервере.Доступность = Не ирКэш.ЛиПортативныйРежимЛкс() Или ирПортативный.ЛиСерверныйМодульДоступенЛкс();
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ФлажокОбъектыНаСервере.Подсказка = "Запись и удаление объектов данных выполнять на сервере. Это снижает скорость, но повышает совместимость с конфигурациями под управляемое приложение.";
Иначе
ФлажокОбъектыНаСервере.Подсказка = "При выполнении кода на клиенте работать с объектами данных на сервере. Это снижает скорость, но повышает совместимость с конфигурациями под управляемое приложение. При выполнении кода на сервере этот параметр не используется.";
КонецЕсли;
КонецЕсли;
Если мПлатформа.мПроверкаСовместимостиКонфигурацииВыполнялась <> Истина Тогда
// Однократно выполняемые в сеансе действия
Если Метаданные.ХранилищеОбщихНастроек <> Неопределено Тогда
ИмяПроверочнойНастройки = "Тест";
СохранитьЗначениеЛкс(ИмяПроверочнойНастройки, 1);
Если ВосстановитьЗначениеЛкс(ИмяПроверочнойНастройки) = Неопределено Тогда
СообщитьЛкс("В конфигурации переопределено хранилище общих настроек и оно не восстанавливает сохраненные значения. Корректная работа подсистемы ""Инструменты разработчика"" невозможна", СтатусСообщения.Важное);
КонецЕсли;
КонецЕсли;
мПлатформа.мПроверкаСовместимостиКонфигурацииВыполнялась = Истина;
#Если Сервер И Не Сервер Тогда
ВыполнитьПроверкуСовместимостиКонфигурацииЛкс();
#КонецЕсли
ПодключитьГлобальныйОбработчикОжиданияЛкс("ВыполнитьПроверкуСовместимостиКонфигурацииЛкс", 1, Истина);
Если Не ирКэш.ЭтоФайловаяБазаЛкс() Тогда
ПроверитьСоединениеADOЭтойБДЛкс(,,,,, Ложь, Истина);
КонецЕсли;
КонецЕсли;
ирКэш.СостояниеПодготовкиТаблицыВсехТаблицБДЛкс();
КонецПроцедуры
Процедура НастроитьЭлементыФормыЛкс(ЭтаФорма) Экспорт
СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
//ОбработчикиПриВыводеСтроки = Новый Соответствие;
//СлужебныеДанныеФормы.Вставить("ОбработчикиПриВыводеСтроки", ОбработчикиПриВыводеСтроки);
КнопкиВсехДействийКомандныхПанелей = Новый Соответствие;
КомандныеПанелиКнопок = Новый Соответствие;
ИмяКнопки = "СтруктураКоманднойПанели";
ВозможныеИменаРеквизита = Новый Массив;
ВозможныеИменаРеквизита.Добавить("ОбработкаОбъект");
ВозможныеИменаРеквизита.Добавить("ОсновнойОбъект");
ОсновнойРеквизит = Неопределено;
ЕстьОбщийОбработчикПриПолученииДанных = Неопределено;
Для Каждого ИмяОсновногоРеквизита Из ВозможныеИменаРеквизита Цикл
Если ЕстьСвойствоОбъектаЛкс(ЭтаФорма, ИмяОсновногоРеквизита) Тогда
ОсновнойРеквизит = ЭтаФорма[ИмяОсновногоРеквизита];
Прервать;
КонецЕсли;
КонецЦикла;
Для Каждого ЭлементФормы Из ЭтаФорма.ЭлементыФормы Цикл
Если ОсновнойРеквизит <> Неопределено Тогда
Попытка
Данные = ЭлементФормы.Данные;
Подсказка = ЭлементФормы.Подсказка; // У ActiveX этого свойства нет
Исключение
Данные = "";
КонецПопытки;
Если Не ПустаяСтрока(Данные) И Найти(Данные, ".") = 0 Тогда
Если Не ЗначениеЗаполнено(ЭлементФормы.Подсказка) Тогда
РеквизитОбъекта = ОсновнойРеквизит.Метаданные().Реквизиты.Найти(Данные);
Если РеквизитОбъекта <> Неопределено Тогда
ЭлементФормы.Подсказка = РеквизитОбъекта.Подсказка;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Встраиваем кнопки структуры командной панели
КоманднаяПанель = Неопределено;
ВстроитьВНачало = Истина;
Если ТипЗнч(ЭлементФормы) = Тип("КоманднаяПанель") Тогда
КоманднаяПанель = ЭлементФормы;
ВсеКнопки = ВсеКнопкиКоманднойПанелиЛкс(КоманднаяПанель);
Для Каждого Кнопка Из ВсеКнопки Цикл
КомандныеПанелиКнопок[Кнопка] = КоманднаяПанель;
КонецЦикла;
Если Не КоманднаяПанель.Видимость Тогда
Продолжить;
КонецЕсли;
ВстроитьВНачало = КоманднаяПанель.Ширина > 100;
//ИначеЕсли ТипЗнч(ЭлементФормы) = Тип("ТабличноеПоле") Тогда
// КоманднаяПанель = ЭлементФормы.КонтекстноеМеню;
Иначе
Попытка
// В контекстных меню функция мало востребована, т.к. они имеют обычно более простую структуру и там сразу виден текст всех кнопок
КоманднаяПанель = ЭлементФормы.КонтекстноеМеню;
ВстроитьВНачало = Ложь;
Исключение
КонецПопытки;
КонецЕсли;
Если Истина
И КоманднаяПанель <> Неопределено
И КоманднаяПанель.Кнопки.Найти(ИмяКнопки) = Неопределено
Тогда
НужноВстроить = Ложь;
КоличествоКнопок = 0;
Для Каждого Кнопка Из КоманднаяПанель.Кнопки Цикл
Если Кнопка.ТипКнопки <> ТипКнопкиКоманднойПанели.Разделитель Тогда
КоличествоКнопок = КоличествоКнопок + 1;
Если КоличествоКнопок > 4 Тогда
НужноВстроить = Истина;
Прервать;
КонецЕсли;
КонецЕсли;
Если Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда
НужноВстроить = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НужноВстроить Тогда
Если ВстроитьВНачало Тогда
КнопкаСтруктураКоманднойПанели = КоманднаяПанель.Кнопки.Вставить(0);
Иначе
КнопкаСтруктураКоманднойПанели = КоманднаяПанель.Кнопки.Добавить();
КонецЕсли;
КнопкаСтруктураКоманднойПанели.Имя = ИмяКнопки;
КнопкаСтруктураКоманднойПанели.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
КнопкаСтруктураКоманднойПанели.Картинка = ирКэш.КартинкаПоИмениЛкс("ирКоманднаяПанель");
КнопкаСтруктураКоманднойПанели.Отображение = ОтображениеКнопкиКоманднойПанели.Авто;
КнопкаСтруктураКоманднойПанели.Текст = "Структура командной панели";
КнопкаСтруктураКоманднойПанели.Подсказка = "Открыть структуру командной панели";
Попытка
КнопкаСтруктураКоманднойПанели.Действие = Новый Действие("СтруктураКоманднойПанелиНажатие");
Исключение
// В этой форме нет обработчика
КоманднаяПанель.Кнопки.Удалить(КнопкаСтруктураКоманднойПанели);
КонецПопытки;
КнопкиВсехДействийКомандныхПанелей.Вставить(КнопкаСтруктураКоманднойПанели, КоманднаяПанель);
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ЭлементФормы) = Тип("ТабличноеПоле") Тогда
//ОбработчикПриВыводеСтроки = ЭлементФормы.ПолучитьДействие("ПриВыводеСтроки");
//Если ОбработчикПриВыводеСтроки <> Неопределено Тогда
// Если ЭлементФормы.ПолучитьДействие("ПриПолученииДанных") = Неопределено Тогда
// ОбработчикиПриВыводеСтроки[ЭлементФормы.Имя] = ОбработчикПриВыводеСтроки;
// ЭлементФормы.УстановитьДействие("ПриВыводеСтроки", Неопределено);
// ЭлементФормы.УстановитьДействие("ПриПолученииДанных", Новый Действие("ТабличноеПолеПриПолученииДанных"));
// Иначе
// СообщитьЛкс("Табличному полю " + ЭлементФормы.Имя + " назначены одновременно обработчики ПриВыводеСтроки и ПриПолученииДанных");
// КонецЕсли;
//КонецЕсли;
НастроитьТабличноеПолеПослеСозданияКолонокЛкс(ЭлементФормы);
КонецЕсли;
КонецЦикла;
СлужебныеДанныеФормы.Вставить("КнопкиВсехДействийКомандныхПанелей", КнопкиВсехДействийКомандныхПанелей);
СлужебныеДанныеФормы.Вставить("КомандныеПанелиКнопок", КомандныеПанелиКнопок);
КонецПроцедуры
Процедура Форма_ВставитьСкрытуюКоманднуюПанельГлобальныхКомандЛкс(ЭтаФорма) Экспорт
ЭлементыФормы = ЭтаФорма.ЭлементыФормы;
//ИмяКоманднойПанели = "КП_ПолеВвода";
//КонтекстноеМенюФормы = ЭлементыФормы.Найти(ИмяКоманднойПанели);
//Если КонтекстноеМенюФормы = Неопределено Тогда
// КонтекстноеМенюФормы = ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), ИмяКоманднойПанели);
// КонтекстноеМенюФормы.Видимость = Ложь;
//КонецЕсли;
////лПлатформа = ирКэш.Получить();
////МакетФормы = лПлатформа.ПолучитьФорму("УниверсальныеКоманды");
////КонтекстноеМенюМакета = МакетФормы.ЭлементыФормы.КоманднаяПанель.Кнопки.ПолеВвода;
////ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(МакетФормы, КонтекстноеМенюМакета.Кнопки, КонтекстноеМенюФормы);
//КоманднаяПанельВставитьКнопкиГлобальныхКомандЛкс(КонтекстноеМенюФормы);
//Для Каждого ЭлементФормы Из ЭлементыФормы Цикл
// Если ТипЗнч(ЭлементФормы) = Тип("ПолеВвода") Тогда
// Попытка
// КонтекстноеМеню = ЭлементФормы.КонтекстноеМеню;
// Исключение
// // Поле ввода принадлежит не панели, поэтому у него нет свойства
// Продолжить;
// КонецПопытки;
// Если КонтекстноеМеню = Неопределено Тогда
// //ЭлементФормы.АвтоКонтекстноеМеню = Ложь;
// ЭлементФормы.КонтекстноеМеню = КонтекстноеМенюФормы;
// КонецЕсли;
// КонецЕсли;
//КонецЦикла;
ДействияФормы = ЭлементыФормы.Найти("ДействияФормы");
Если ТипЗнч(ДействияФормы) <> Тип("КоманднаяПанель") Тогда
ПанельФормы = ЭтаФорма.Панель;
Если ПанельФормы.КонтекстноеМеню = Неопределено Тогда
ДействияФормы = ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), "ДействияФормыАвто", Ложь);
ДействияФормы.ИсточникДействий = ЭтаФорма;
ПанельФормы.КонтекстноеМеню = ДействияФормы;
Иначе
ДействияФормы = ПанельФормы.КонтекстноеМеню;
КонецЕсли;
КоманднаяПанельВставитьКнопкиГлобальныхКомандЛкс(ДействияФормы);
КонецЕсли;
КонецПроцедуры
Функция ВсеКнопкиКоманднойПанелиЛкс(КоманднаяПанель, РезультатРекурсия = Неопределено)
#Если Сервер И Не Сервер Тогда
КоманднаяПанель = Новый КоманднаяПанель;
#КонецЕсли
Если РезультатРекурсия = Неопределено Тогда
РезультатРекурсия = Новый Массив;
КонецЕсли;
Для Каждого Кнопка Из КоманднаяПанель.Кнопки Цикл
Если Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда
ВсеКнопкиКоманднойПанелиЛкс(Кнопка, РезультатРекурсия);
ИначеЕсли Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Действие Тогда
Если Найти(Кнопка.Действие, "КлсКомандаНажатие") = 1 Тогда
РезультатРекурсия.Добавить(Кнопка);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат РезультатРекурсия;
КонецФункции
// Только для кнопок с обработчиком "КлсКомандаНажатие"
Функция КоманднаяПанельКнопкиЛкс(ЭтаФорма, Кнопка)
мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
КоманднаяПанель = мСвойстваФормы.КомандныеПанелиКнопок[Кнопка];
Возврат КоманднаяПанель;
КонецФункции
Процедура НастроитьТабличноеПолеПослеСозданияКолонокЛкс(Знач ЭлементФормы) Экспорт
// Возвращаем старый стиль шапок колонок, при котором видна текущая колонка
Если ЭлементФормы.Колонки.Количество() > 0 Тогда
// Антифича платформы 8.2 http://partners.v8.1c.ru/forum/thread.jsp?id=898034
Если ЭлементФормы.Колонки[0].ЦветФонаШапки <> ЦветаСтиля.ЦветФонаКнопки Тогда
ЭлементФормы.Колонки[0].ЦветФонаШапки = ЦветаСтиля.ЦветФонаКнопки;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьСтруктуруКоманднойПанелиЛкс(ЭтаФорма, Знач Кнопка = Неопределено) Экспорт
Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда
мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
КоманднаяПанель = мСвойстваФормы.КнопкиВсехДействийКомандныхПанелей[Кнопка];
Если Кнопка <> Неопределено Тогда
Если КоманднаяПанель.Кнопки.Индекс(Кнопка) = -1 Тогда
// Для контекстных меню
КоманднаяПанель = КоманднаяПанель.Кнопки[0];
КонецЕсли;
КонецЕсли;
Иначе
КоманднаяПанель = РодительЭлементаУправляемойФормыЛкс(Кнопка, Тип("ГруппаФормы"));
КонецЕсли;
ФормаСтруктуры = ирКэш.Получить().ПолучитьФорму("СтруктураФормы");
ФормаСтруктуры.ПараметрЭлементФормы = КоманднаяПанель;
ФормаСтруктуры.Форма = ЭтаФорма;
ФормаСтруктуры.ОткрытьМодально();
КонецПроцедуры
Процедура ОткрытьСтруктуруФормыЛкс(ЭтаФорма, КлючУникальности = Неопределено) Экспорт
ФормаСтруктуры = ирКэш.Получить().ПолучитьФорму("СтруктураФормы",, КлючУникальности);
ФормаСтруктуры.Форма = ЭтаФорма;
ФормаСтруктуры.ОткрытьМодально();
КонецПроцедуры
Функция ОткрытьФормуСоединенияСУБДЛкс(Автоподключение = Ложь) Экспорт
мПлатформа = ирКэш.Получить();
ПроверкаСоединенияADOЭтойБДВыполнялась = мПлатформа.мПроверкаСоединенияADOЭтойБДВыполнялась = Истина;
ФормаПодключения = ирКэш.Получить().ПолучитьФорму("ПараметрыСоединенияСУБД");
ФормаПодключения.Автоподключение = Автоподключение И ПроверкаСоединенияADOЭтойБДВыполнялась;
Если (Не ПроверкаСоединенияADOЭтойБДВыполнялась Или Не Автоподключение) И Не ирКэш.ЭтоФайловаяБазаЛкс() Тогда
Если ФормаПодключения.ОткрытьМодально() <> Истина Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Возврат ФормаПодключения;
КонецФункции
Функция ОткрытьОбщиеПараметрыЗаписиЛкс(ТолькоОбъектыНаСервере = Ложь) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Форма = мПлатформа.ПолучитьФорму("ПараметрыЗаписиОбъектов");
Форма.ПараметрТолькоОбъектыНаСервере = ТолькоОбъектыНаСервере;
Форма.ОткрытьМодально();
КонецФункции
Функция ОткрытьСсылкуИТСЛкс(СтрокаЗапуска) Экспорт
Маркер = "v?doc";
Если Найти(СтрокаЗапуска, Маркер) > 0 Тогда
ФрагментыМаркера = ирОбщий.СтрРазделитьЛкс(Маркер, "?");
СисИнфо = Новый СистемнаяИнформация;
ФрагментыВерсии = ирОбщий.СтрРазделитьЛкс(СисИнфо.ВерсияПриложения);
ТекущаяВерсия = ФрагментыВерсии[0] + "." + ФрагментыВерсии[1] + "." + ФрагментыВерсии[2];
ВыбраннаяВерсия = СтрЗаменить(ТекущаяВерсия, ".", "");
СтрокаЗапуска = ирОбщий.СтрЗаменитьЛкс(СтрокаЗапуска, Маркер, ФрагментыМаркера[0] + ВыбраннаяВерсия + ФрагментыМаркера[1]);
КонецЕсли;
ЗапуститьПриложение(СтрокаЗапуска);
КонецФункции
Процедура УстановитьДоступностьВыполненияНаСервереЛкс(ЭтаФорма) Экспорт
ДоступностьРежима = Не ирКэш.ЛиПортативныйРежимЛкс();
Если ЭтаФорма.ЭлементыФормы.Найти("ВыполнятьНаСервере") <> Неопределено Тогда
ЭтаФорма.ЭлементыФормы.ВыполнятьНаСервере.Доступность = ДоступностьРежима;
ЭтаФорма.ЭлементыФормы.ВыполнятьНаСервере.Заголовок = "Выполнять на сервере";
ЭтаФорма.ЭлементыФормы.ВыполнятьНаСервере.Подсказка = "Недоступно в портативном варианте. " + ЭтаФорма.ЭлементыФормы.ВыполнятьНаСервере.Подсказка;
КонецЕсли;
Если Не ДоступностьРежима Тогда
ЭтаФорма.ЭтотОбъект.ВыполнятьНаСервере = Ложь;
КонецЕсли;
КонецПроцедуры
#КонецЕсли
Функция ПредставлениеСочетанияКлавишЛкс(СочетаниеКлавиш) Экспорт
Представление = "";
Если СочетаниеКлавиш.Alt Тогда
Представление = Представление + "Alt+";
КонецЕсли;
Если СочетаниеКлавиш.Ctrl Тогда
Представление = Представление + "Ctrl+";
КонецЕсли;
Если СочетаниеКлавиш.Shift Тогда
Представление = Представление + "Shift+";
КонецЕсли;
Если Не ЗначениеЗаполнено("" + СочетаниеКлавиш.Клавиша) Тогда
Строка = ирОбщий.СохранитьОбъектВВидеСтрокиXMLЛкс(СочетаниеКлавиш, Истина);
ОбъектXDTO = ирОбщий.ОбъектXDTOИзСтрокиXMLЛкс(Строка);
ПредставлениеКлавиши = ОбъектXDTO.Key;
Иначе
ПредставлениеКлавиши = "" + СочетаниеКлавиш.Клавиша;
КонецЕсли;
Представление = Представление + ПредставлениеКлавиши;
Возврат Представление;
КонецФункции
Функция ЦветФонаЯчеекПустыхЗначенийЛкс() Экспорт
ЦветПустых = Новый Цвет(245, 255, 245);
Возврат ЦветПустых;
КонецФункции
Функция ВосстановитьЗначениеЛкс(КлючНастроек, ДляВсехПользователей = Ложь) Экспорт
#Если ТонкийКлиент Или ВебКлиент Или МобильныйКлиент Тогда
Возврат ВосстановитьЗначениеЛкс(КлючНастроек);
#Иначе
Если Истина
И ДляВсехПользователей
И (Ложь
Или ирКэш.НомерВерсииПлатформыЛкс() < 803001
Или ПравоДоступа("АдминистрированиеДанных", Метаданные))
Тогда
ИмяПользователя = ирКэш.ИмяПродукта();
Иначе
//ИмяПользователя = Неопределено; // Такое значение вызывает ошибки у нестандартных хранилищ
ИмяПользователя = ИмяПользователя();
КонецЕсли;
Результат = ХранилищеОбщихНастроек.Загрузить(ирКэш.ИмяПродукта(), КлючНастроек,, ИмяПользователя);
#Если Клиент Тогда
Если Результат = Неопределено Тогда
// Импорт из старого хранилища настроек
Результат = ВосстановитьЗначение(КлючНастроек);
Если Результат <> Неопределено Тогда
СохранитьЗначениеЛкс(КлючНастроек, Результат);
СохранитьЗначение(КлючНастроек, Неопределено);
КонецЕсли;
КонецЕсли;
#КонецЕсли
Возврат Результат;
#КонецЕсли
КонецФункции
Функция СохранитьЗначениеЛкс(КлючНастроек, Значение, ДляВсехПользователей = Ложь) Экспорт
#Если ТонкийКлиент Или ВебКлиент Или МобильныйКлиент Тогда
ирСервер.СохранитьЗначениеЛкс(КлючНастроек, Значение);
#Иначе
Если ДляВсехПользователей И ПравоДоступа("АдминистрированиеДанных", Метаданные) Тогда
ИмяПользователя = ирКэш.ИмяПродукта();
Иначе
//ИмяПользователя = Неопределено; // Такое значение вызывает ошибки у нестандартных хранилищ
ИмяПользователя = ИмяПользователя();
КонецЕсли;
ХранилищеОбщихНастроек.Сохранить(ирКэш.ИмяПродукта(), КлючНастроек, Значение,, ИмяПользователя);
#КонецЕсли
КонецФункции
Функция УдалитьХранимуюНастройкуЛкс(КлючНастроек, ДляВсехПользователей = Ложь) Экспорт
#Если ТонкийКлиент Или ВебКлиент Или МобильныйКлиент Тогда
ирСервер.УдалитьХранимуюНастройкуЛкс(КлючНастроек);
#Иначе
Если ДляВсехПользователей И ПравоДоступа("АдминистрированиеДанных", Метаданные) Тогда
ИмяПользователя = ирКэш.ИмяПродукта();
Иначе
//ИмяПользователя = Неопределено; // Такое значение вызывает ошибки у нестандартных хранилищ
ИмяПользователя = ИмяПользователя();
КонецЕсли;
ХранилищеОбщихНастроек.Удалить(ирКэш.ИмяПродукта(), КлючНастроек, ИмяПользователя);
#КонецЕсли
КонецФункции
Процедура ДобавитьИндексВТаблицуЛкс(ТаблицаЗначений, Знач СтрокаИндекса) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
ИндексНайден = Ложь;
Для Каждого Индекс Из ТаблицаЗначений.Индексы Цикл
Если СтрокиРавныЛкс("" + Индекс, СтрокаИндекса) Тогда
ИндексНайден = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ИндексНайден Тогда
ТаблицаЗначений.Индексы.Добавить(СтрокаИндекса);
КонецЕсли;
КонецПроцедуры
// Можно ради скорости отказываться от использования этой функции
Функция ЛиПустаяПодгруппаRegExpЛкс(Подгруппа) Экспорт
Результат = Ложь
Или Подгруппа = Неопределено // наш случай
Или Подгруппа = ""; // RegExV8
Возврат Результат;
КонецФункции
Процедура ОбновитьКопиюСвойстваВНижнемРегистреЛкс(Объект, ИмяСвойства = "Имя") Экспорт
Объект["Н" + ИмяСвойства] = НРег(Объект[ИмяСвойства]);
КонецПроцедуры
Функция ПолучитьСхемуКолонокМакетаКомпоновкиДанныхЛкс(МакетКомпоновки) Экспорт
#Если Сервер И Не Сервер Тогда
МакетКомпоновки = Новый МакетКомпоновкиДанных;
#КонецЕсли
СхемаКолонок = Новый Структура;
// Схема колонок строится негарантировано, т.к. платформа не предоставляет нужных данных
ОписанияМакетовОбластей = МакетКомпоновки.Макеты;
Если ОписанияМакетовОбластей.Количество() > 0 Тогда
ЯчейкиЗаголовка = ОписанияМакетовОбластей[0].Макет.Ячейки;
Если ЯчейкиЗаголовка <> Неопределено Тогда
КоличествоЯчеекЗаголовка = ЯчейкиЗаголовка.Количество();
Для Индекс = 0 По КоличествоЯчеекЗаголовка - 1 Цикл
Для Каждого ОписаниеМакетаОбласти Из ОписанияМакетовОбластей Цикл
// Здесь подсказка криво работает из-за кривого синтакс-помощника 8.2.13.205
// http://partners.v8.1c.ru/forum/thread.jsp?id=898023#898023
ЯчейкаМакетаОбласти = ОписаниеМакетаОбласти.Макет.Ячейки[Индекс];
Если ТипЗнч(ЯчейкаМакетаОбласти) <> Тип("ЯчейкаМакетаКоллекцииЗначенийОбластиКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
ПараметрЯчейки = ЯчейкаМакетаОбласти.Значение;
Если ПараметрЯчейки = Неопределено Тогда
Продолжить;
КонецЕсли;
Выражение = ОписаниеМакетаОбласти.Параметры["" + ПараметрЯчейки].Выражение;
ПозицияТочки = Найти(Выражение, ".");
Если Ложь
Или ПозицияТочки = 0
Или Найти(Выражение, " ") > 0
Или Найти(Выражение, "(") > 0
Тогда
//ИмяПоля = "";
Продолжить;
Иначе
ИмяПоля = Сред(Выражение, ПозицияТочки + 1);
КонецЕсли;
СхемаКолонок.Вставить(ЯчейкиЗаголовка[Индекс].Имя, ИмяПоля);
Прервать;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат СхемаКолонок;
КонецФункции
Функция ПолучитьТекущуюДатуЛкс(НаСервере = Ложь) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ПолучитьТекущуюДатуЛкс();
Иначе
Результат = ТекущаяДата();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СтрокиРавныЛкс(Знач Строка1, Знач Строка2, СУчетомРегистра = Ложь, БезПравыхНепечатныхСимволов = Ложь) Экспорт
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Если Не СУчетомРегистра Тогда
Строка1 = НРег(Строка1);
Строка2 = НРег(Строка2);
КонецЕсли;
Если БезПравыхНепечатныхСимволов Тогда
Строка1 = СокрП(Строка1);
Строка2 = СокрП(Строка2);
КонецЕсли;
Результат = Строка1 = Строка2;
Возврат Результат;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Если Не СУчетомРегистра Тогда Строка1 = НРег(Строка1); Строка2 = НРег(Строка2); КонецЕсли; Если БезПравыхНепечатныхСимволов Тогда Строка1 = СокрП(Строка1); Строка2 = СокрП(Строка2); КонецЕсли; Результат = Строка1 = Строка2; Возврат Результат;
КонецФункции
// Вставляет параметры в строку, учитывая, что в параметрах могут использоваться подстановочные слова %1, %2 и т.д.
Функция ПодставитьПараметрыСПроцентомЛкс(Знач СтрокаПодстановки,
Знач Параметр1, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено,
Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено,
Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено)
Результат = "";
Позиция = СтрНайтиЛкс(СтрокаПодстановки, "%");
Пока Позиция > 0 Цикл
Результат = Результат + Лев(СтрокаПодстановки, Позиция - 1);
СимволПослеПроцента = Сред(СтрокаПодстановки, Позиция + 1, 1);
ПодставляемыйПараметр = Неопределено;
Если СимволПослеПроцента = "1" Тогда
ПодставляемыйПараметр = Параметр1;
ИначеЕсли СимволПослеПроцента = "2" Тогда
ПодставляемыйПараметр = Параметр2;
ИначеЕсли СимволПослеПроцента = "3" Тогда
ПодставляемыйПараметр = Параметр3;
ИначеЕсли СимволПослеПроцента = "4" Тогда
ПодставляемыйПараметр = Параметр4;
ИначеЕсли СимволПослеПроцента = "5" Тогда
ПодставляемыйПараметр = Параметр5;
ИначеЕсли СимволПослеПроцента = "6" Тогда
ПодставляемыйПараметр = Параметр6;
ИначеЕсли СимволПослеПроцента = "7" Тогда
ПодставляемыйПараметр = Параметр7
ИначеЕсли СимволПослеПроцента = "8" Тогда
ПодставляемыйПараметр = Параметр8;
ИначеЕсли СимволПослеПроцента = "9" Тогда
ПодставляемыйПараметр = Параметр9;
КонецЕсли;
Если ПодставляемыйПараметр = Неопределено Тогда
Результат = Результат + "%";
СтрокаПодстановки = Сред(СтрокаПодстановки, Позиция + 1);
Иначе
Результат = Результат + ПодставляемыйПараметр;
СтрокаПодстановки = Сред(СтрокаПодстановки, Позиция + 2);
КонецЕсли;
Позиция = СтрНайтиЛкс(СтрокаПодстановки, "%");
КонецЦикла;
Результат = Результат + СтрокаПодстановки;
Возврат Результат;
КонецФункции
// Подставляет параметры в строку. Максимально возможное число параметров - 9.
// Параметры в строке задаются как %<номер параметра>. Нумерация параметров начинается с единицы.
//
// Параметры:
// ШаблонСтроки - Строка - шаблон строки с параметрами (вхождениями вида "%<номер параметра>",
// например "%1 пошел в %2");
// Параметр - Строка - значение подставляемого параметра.
//
// Возвращаемое значение:
// Строка - текстовая строка с подставленными параметрами.
//
// Пример:
// СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru='%1 пошел в %2'"), "Вася", "Зоопарк") = "Вася пошел
// в Зоопарк".
//
Функция СтрШаблонЛкс(Знач ШаблонСтроки,
Знач Параметр1, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено,
Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено,
Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) Экспорт
ЕстьПараметрыСПроцентом = СтрНайтиЛкс(Параметр1, "%")
Или СтрНайтиЛкс(Параметр2, "%")
Или СтрНайтиЛкс(Параметр3, "%")
Или СтрНайтиЛкс(Параметр4, "%")
Или СтрНайтиЛкс(Параметр5, "%")
Или СтрНайтиЛкс(Параметр6, "%")
Или СтрНайтиЛкс(Параметр7, "%")
Или СтрНайтиЛкс(Параметр8, "%")
Или СтрНайтиЛкс(Параметр9, "%");
Если ЕстьПараметрыСПроцентом Тогда
Возврат ПодставитьПараметрыСПроцентомЛкс(ШаблонСтроки, Параметр1,
Параметр2, Параметр3, Параметр4, Параметр5, Параметр6, Параметр7, Параметр8, Параметр9);
КонецЕсли;
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%1", Параметр1);
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%2", Параметр2);
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%3", Параметр3);
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%4", Параметр4);
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%5", Параметр5);
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%6", Параметр6);
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%7", Параметр7);
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%8", Параметр8);
ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%9", Параметр9);
Возврат ШаблонСтроки;
КонецФункции
// Функция собирает строку из элементов массива с разделителем.
//
// Параметры:
// пМассив - Массив - из которого формируем строку;
// *пРазделитель - Строка - символ-разделитель.
//
// Возвращаемое значение:
// Строка.
//
Функция СтрСоединитьЛкс(пМассив, пРазделитель = ", ") Экспорт
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
Пустая = Истина;
Для Каждого Элемент Из пМассив Цикл
Если Не Пустая Тогда
ЗаписьXML.ЗаписатьБезОбработки(пРазделитель);
Иначе
Пустая = Ложь;
КонецЕсли;
ЗаписьXML.ЗаписатьБезОбработки(Строка(Элемент));
КонецЦикла;
Результат = ЗаписьXML.Закрыть();
Возврат Результат;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); Пустая = Истина; Для Каждого Элемент Из пМассив Цикл Если Не Пустая Тогда ЗаписьXML.ЗаписатьБезОбработки(пРазделитель); Иначе Пустая = Ложь; КонецЕсли; ЗаписьXML.ЗаписатьБезОбработки(Строка(Элемент)); КонецЦикла; Результат = ЗаписьXML.Закрыть(); Возврат Результат;
КонецФункции
Функция СтрокаИзВыраженияВстроенногоЯзыкаЛкс(Знач Текст) Экспорт
Текст = СтрЗаменить(Текст, """""", """");
Если Лев(Текст, 1) = """" Тогда
Текст = Сред(Текст, 2);
КонецЕсли;
Если Прав(Текст, 1) = """" Тогда
Текст = Лев(Текст, СтрДлина(Текст) - 1);
КонецЕсли;
Возврат Текст;
КонецФункции
// Преобразует исходную строку в число без вызова исключений.
//
// Параметры:
// Значение - Строка - строка, которую необходимо привести к числу.
// Например, "10", "+10", "010", вернет 10;
// "(10)", "-10",вернет -10;
// "10,2", "10.2",вернет 10.2;
// "000", " ", "",вернет 0;
// "10текст", вернет Неопределено.
//
// Возвращаемое значение:
// Число, Неопределено - полученное число, либо Неопределено, если строка не является числом.
//
Функция СтрокаВЧислоЛкс(Знач Значение) Экспорт
Значение = СтрЗаменить(Значение, " ", "");
Если Лев(Значение, 1) = "(" Тогда
Значение = СтрЗаменить(Значение, "(", "-");
Значение = СтрЗаменить(Значение, ")", "");
КонецЕсли;
СтрокаБезНулей = СтрЗаменить(Значение, "0", "");
Если ПустаяСтрока(СтрокаБезНулей) Или СтрокаБезНулей = "-" Тогда
Возврат 0;
КонецЕсли;
ТипЧисло = Новый ОписаниеТипов("Число");
Результат = ТипЧисло.ПривестиЗначение(Значение);
Возврат ?(Результат <> 0 И Не ПустаяСтрока(СтрокаБезНулей), Результат, Неопределено);
КонецФункции
// Разделяет URL по составным частям: протокол, сервер, путь к ресурсу.
//
// Параметры:
// URL - Строка - ссылка на ресурс в сети Интернет
//
// Возвращаемое значение:
// Структура:
// Протокол - Строка - протокол доступа к ресурсу
// ИмяСервера - Строка - сервер, на котором располагается ресурс
// ПутьКФайлуНаСервере - Строка - путь к ресурсу на сервере
//
Функция РазделитьURLЛкс(Знач URL) Экспорт
СтруктураURL = СтруктураURIЛкс(URL);
Результат = Новый Структура;
Результат.Вставить("Протокол", ?(ПустаяСтрока(СтруктураURL.Схема), "http", СтруктураURL.Схема));
Результат.Вставить("ИмяСервера", СтруктураURL.ИмяСервера);
Результат.Вставить("ПутьКФайлуНаСервере", СтруктураURL.ПутьНаСервере);
Возврат Результат;
КонецФункции
// Разбирает строку URI на составные части и возвращает в виде структуры.
// На основе RFC 3986.
//
// Параметры:
// СтрокаURI - Строка - ссылка на ресурс в формате: <схема>://<логин>:<пароль>@<хост>:<порт>/<путь>?<параметры>#<якорь>
//
// Возвращаемое значение:
// Структура - составные части URI согласно формату:
// * Схема - Строка
// * Логин - Строка
// * Пароль - Строка
// * ИмяСервера - Строка - часть <хост>:<порт> входного параметра
// * Хост - Строка
// * Порт - Строка
// * ПутьНаСервере - Строка - часть <путь>?<параметры>#<якорь> входного параметра
//
Функция СтруктураURIЛкс(Знач СтрокаURI) Экспорт
СтрокаURI = СокрЛП(СтрокаURI);
// схема
Схема = "";
Позиция = Найти(СтрокаURI, "://");
Если Позиция > 0 Тогда
Схема = НРег(Лев(СтрокаURI, Позиция - 1));
СтрокаURI = Сред(СтрокаURI, Позиция + 3);
КонецЕсли;
// строка соединения и путь на сервере
СтрокаСоединения = СтрокаURI;
ПутьНаСервере = "";
Позиция = Найти(СтрокаСоединения, "/");
Если Позиция > 0 Тогда
ПутьНаСервере = Сред(СтрокаСоединения, Позиция + 1);
СтрокаСоединения = Лев(СтрокаСоединения, Позиция - 1);
КонецЕсли;
// информация пользователя и имя сервера
СтрокаАвторизации = "";
ИмяСервера = СтрокаСоединения;
Позиция = Найти(СтрокаСоединения, "@");
Если Позиция > 0 Тогда
СтрокаАвторизации = Лев(СтрокаСоединения, Позиция - 1);
ИмяСервера = Сред(СтрокаСоединения, Позиция + 1);
КонецЕсли;
// логин и пароль
Логин = СтрокаАвторизации;
Пароль = "";
Позиция = Найти(СтрокаАвторизации, ":");
Если Позиция > 0 Тогда
Логин = Лев(СтрокаАвторизации, Позиция - 1);
Пароль = Сред(СтрокаАвторизации, Позиция + 1);
КонецЕсли;
// хост и порт
Хост = ИмяСервера;
Порт = "";
Позиция = Найти(ИмяСервера, ":");
Если Позиция > 0 Тогда
Хост = Лев(ИмяСервера, Позиция - 1);
Порт = Сред(ИмяСервера, Позиция + 1);
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("Схема", Схема);
Результат.Вставить("ИспользоватьHTTPS", ирОбщий.СтрокиРавныЛкс(Схема, "HTTPS"));
Результат.Вставить("Логин", Логин);
Результат.Вставить("Пароль", Пароль);
Результат.Вставить("ИмяСервера", ИмяСервера);
Результат.Вставить("Хост", Хост);
Результат.Вставить("Порт", ?(ПустаяСтрока(Порт), Неопределено, Число(Порт)));
Результат.Вставить("ПортHTTP", ?(ПустаяСтрока(Порт), ?(Результат.ИспользоватьHTTPS, 443, 80), Результат.Порт));
Результат.Вставить("ПутьНаСервере", ПутьНаСервере);
Возврат Результат;
КонецФункции
// Поиск числа в строке
//
// Параметры:
// ИсходнаяСтрока - Строка, строка в которой ищется число
// ПозицияЧисла - Число, позиция начала числа
// КоличествоСимволов - Число, количество символов числа
//
// Возвращаемое значение:
// Булево - Истина, число найдено
//
Функция НайтиЧислоВСтрокеЛкс(ИсходнаяСтрока, выхПозицияЧисла = 0, выхКоличествоСимволов = 0) Экспорт
выхПозицияЧисла = 0;
выхКоличествоСимволов = 0;
ДлинаСтроки = СтрДлина(ИсходнаяСтрока);
// 300000 повторов при заполнении общей таблицы полей в структуре хранения БД
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Для Сч = 1 По ДлинаСтроки Цикл
ТекущийСимвол = КодСимвола(Сред(ИсходнаяСтрока, Сч, 1));
Если 48 <= ТекущийСимвол И ТекущийСимвол <= 57 Тогда
Если выхПозицияЧисла = 0 Тогда
выхПозицияЧисла = Сч;
выхКоличествоСимволов = 1;
Иначе
выхКоличествоСимволов = выхКоличествоСимволов + 1;
КонецЕсли;
Иначе
Если выхПозицияЧисла <> 0 Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Сч = 1 По ДлинаСтроки Цикл ТекущийСимвол = КодСимвола(Сред(ИсходнаяСтрока, Сч, 1)); Если 48 <= ТекущийСимвол И ТекущийСимвол <= 57 Тогда Если выхПозицияЧисла = 0 Тогда выхПозицияЧисла = Сч; выхКоличествоСимволов = 1; Иначе выхКоличествоСимволов = выхКоличествоСимволов + 1; КонецЕсли; Иначе Если выхПозицияЧисла <> 0 Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла;
Возврат выхПозицияЧисла > 0;
КонецФункции
Функция ЭтоКорректныйСимволИмениПеременнойЛкс(Символ, Вычислитель = Неопределено) Экспорт
Если Вычислитель = Неопределено Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Вычислитель = ирКэш.ВычислительРегулярныхВыраженийЛкс();
Вычислитель.Pattern = "[" + мПлатформа.шБуква + "\d]";
КонецЕсли;
Результат = Вычислитель.Test(Символ);
//Код = КодСимвола(Символ, 1);
//Результат = (Код <= 57 И Код >= 48) ИЛИ (Код <= 90 И Код >= 65) ИЛИ (Код <= 122 И Код >= 97) ИЛИ (Код <= 1103 И Код >= 1040) ИЛИ Код = 95;
Возврат Результат;
КонецФункции
Функция ОписаниеОСЛкс() Экспорт
ПространствоИмен = ирКэш.ПолучитьCOMОбъектWMIЛкс();
ВыборкаОС = ПространствоИмен.ExecQuery("Select * from Win32_OperatingSystem");
Для Каждого ОперационнаяСистема Из ВыборкаОС Цикл
Прервать;
КонецЦикла;
Результат = ОперационнаяСистема.Caption;
Результат = Результат + " " + ОперационнаяСистема.OSArchitecture;
Если ОперационнаяСистема.Locale = "0419" Тогда
ОписаниеЯзыка = "Русский";
Иначе
ОписаниеЯзыка = "НеРусский-" + ОперационнаяСистема.Locale;
КонецЕсли;
Результат = Результат + " " + ОписаниеЯзыка;
Возврат Результат;
КонецФункции
Функция ПроверитьКодЯзыкаОСЛкс() Экспорт
ПространствоИмен1 = ирКэш.ПолучитьCOMОбъектWMIЛкс();
ВыборкаОС = ПространствоИмен1.ExecQuery("Select * from Win32_OperatingSystem");
Для Каждого ОперационнаяСистема Из ВыборкаОС Цикл
Прервать;
КонецЦикла;
Если ОперационнаяСистема.Locale <> "0419" Тогда
ВызватьИсключение "Russian system locale (0419) in OS required for this function";
КонецЕсли;
КонецФункции
Процедура ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, НаСервере = Ложь, ВыводитьПредупрежденияИСообщения = Истина) Экспорт
#Если Клиент Тогда
Если ВыводитьПредупрежденияИСообщения Тогда
Ответ = КодВозвратаДиалога.ОК;
Если НаСервере Тогда
ОбщийРазмер = ирСервер.ВычислитьРазмерКаталогаЛкс(КаталогЖурнала);
Иначе
ОбщийРазмер = ВычислитьРазмерКаталогаЛкс(КаталогЖурнала);
КонецЕсли;
Если ОбщийРазмер > 0 Тогда
Ответ = Вопрос("Действительно удалить рекурсивно все файлы (" + Формат(Цел(ОбщийРазмер/1000000), "ЧН=") + "МБ) в каталоге журнала?", РежимДиалогаВопрос.ОКОтмена);
КонецЕсли;
Если Ответ <> КодВозвратаДиалога.ОК Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Если НаСервере Тогда
ирСервер.ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, ВыводитьПредупрежденияИСообщения);
Возврат;
КонецЕсли;
#КонецЕсли
ФайлыЖурнала = НайтиФайлы(КаталогЖурнала, "*.*", Истина);
Если ФайлыЖурнала.Количество() > 0 Тогда
СчетчикНеудаленных = 0;
Для Каждого ФайлЖурнала Из ФайлыЖурнала Цикл
Попытка
УдалитьФайлы(ФайлЖурнала.ПолноеИмя);
Исключение
СчетчикНеудаленных = СчетчикНеудаленных + 1;
КонецПопытки;
КонецЦикла;
Если ВыводитьПредупрежденияИСообщения Тогда
Если СчетчикНеудаленных > 0 Тогда
СообщитьЛкс("" + СчетчикНеудаленных + " файлов техножурнала удалить не удалось");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры // ОчиститьКаталогТехножурналаЛкс()
Функция ВычислитьРазмерКаталогаЛкс(Каталог, ВключаяПодкаталоги = Истина) Экспорт
Файлы = НайтиФайлы(Каталог, "*.*", ВключаяПодкаталоги);
ОбщийРазмер = 0;
Для Каждого Файл Из Файлы Цикл
Если Файл.ЭтоКаталог() Тогда
Продолжить;
КонецЕсли;
ОбщийРазмер = ОбщийРазмер + Файл.Размер();
КонецЦикла;
Возврат ОбщийРазмер;
КонецФункции
// Выполняет копирование файлов рекурсивно
Процедура СкопироватьФайлыЛкс(КаталогИсточник, КаталогПриемник) Экспорт
Файлы = НайтиФайлы(КаталогИсточник, "*.*");
Для Каждого Файл Из Файлы Цикл
ФайлПриемник = Новый Файл(КаталогПриемник + "\" + Файл.Имя);
Если Файл.ЭтоКаталог() Тогда
СоздатьКаталог(ФайлПриемник.ПолноеИмя);
СкопироватьФайлыЛкс(Файл.ПолноеИмя, ФайлПриемник.ПолноеИмя);
Продолжить;
КонецЕсли;
КопироватьФайл(Файл.ПолноеИмя, ФайлПриемник.ПолноеИмя);
КонецЦикла;
КонецПроцедуры
Процедура УстановитьПометкиРодителейЛкс(Знач Родитель, Знач ИмяДанныхФлажка = "Пометка", НезависимыйРодитель = Ложь) Экспорт
Если Родитель = Неопределено Тогда
Возврат;
КонецЕсли;
ТекСостояние = Родитель[ИмяДанныхФлажка];
НайденыВключенные = Ложь;
НайденыВыключенные = Ложь;
Для каждого Строка из Родитель.Строки Цикл
ЗначениеФлажка = Строка[ИмяДанныхФлажка];
Если ЗначениеФлажка = 0 Тогда
НайденыВыключенные = Истина;
ИначеЕсли ЗначениеФлажка = 1 Тогда
НайденыВключенные = Истина;
ИначеЕсли ЗначениеФлажка = 2 Тогда
НайденыВключенные = Истина;
НайденыВыключенные = Истина;
Прервать;
КонецЕсли;
Если НайденыВключенные И НайденыВыключенные Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если НезависимыйРодитель Тогда
Если НайденыВключенные Тогда
Включить = 2;
КонецЕсли;
Иначе
Если НайденыВключенные И НайденыВыключенные Тогда
Включить = 2;
ИначеЕсли НайденыВключенные И Не НайденыВыключенные Тогда
Включить = 1;
ИначеЕсли Не НайденыВключенные И НайденыВыключенные Тогда
Включить = 0;
ИначеЕсли Не НайденыВключенные И Не НайденыВыключенные Тогда
Включить = 2;
КонецЕсли;
КонецЕсли;
Если Включить = ТекСостояние Тогда
Возврат;
Иначе
Если Родитель[ИмяДанныхФлажка] <> 1 Или Не НезависимыйРодитель Тогда
Родитель[ИмяДанныхФлажка] = Включить;
УстановитьПометкиРодителейЛкс(Родитель.Родитель, ИмяДанныхФлажка);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура УстановитьПометкиПодчиненныхЛкс(Знач ТекСтрока, Знач ИмяДанныхФлажка = "Пометка") Экспорт
ТекСостояние = ТекСтрока[ИмяДанныхФлажка];
Подчиненные = ТекСтрока.Строки;
Если ТекСостояние = 2 Тогда
ТекСтрока[ИмяДанныхФлажка] = 0;
КонецЕсли;
Если Подчиненные.Количество() > 0 Тогда
Для каждого Строка из Подчиненные Цикл
Строка[ИмяДанныхФлажка] = ТекСостояние;
УстановитьПометкиПодчиненныхЛкс(Строка, ИмяДанныхФлажка);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция ЛиСпискиПодсистемПересекаютсяЛкс(ФильтрПодсистем, СписокПодсистем) Экспорт
Если ТипЗнч(ФильтрПодсистем) = Тип("Строка") Тогда
СписокФильтра = Новый СписокЗначений;
СписокФильтра.Добавить(ФильтрПодсистем);
КонецЕсли;
Если Ложь
Или СписокФильтра.Количество() = 0
Или СписокФильтра[0] = ""
Тогда
Возврат Истина;
КонецЕсли;
Для Каждого Подсистема Из СписокПодсистем Цикл
Если ТипЗнч(Подсистема) = Тип("ОбъектМетаданных") Тогда
ИмяПодсистемы = Подсистема.ПолноеИмя();
Иначе
ИмяПодсистемы = Подсистема.Значение;
КонецЕсли;
Если СписокФильтра.НайтиПоЗначению(ИмяПодсистемы) <> Неопределено Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
// Разбирает строку на две части: до подстроки разделителя и после
//
// Параметры:
// Стр - разбираемая строка
// Разделитель - подстрока-разделитель
// Режим - 0 - разделитель в возвращаемые подстроки не включается
// 1 - разделитель включается в левую подстроку
// 2 - разделитель включается в правую подстроку
//
// Возвращаемое значение:
// Правая часть строки - до символа-разделителя
//
Функция ОтделитьРазделителемЛкс(Знач Стр, Знач Разделитель = ".", Режим = 0) Экспорт
ПраваяЧасть = "";
ПозРазделителя = Найти(Стр, Разделитель);
ДлинаРазделителя = СтрДлина(Разделитель);
Если ПозРазделителя > 0 Тогда
ПраваяЧасть = Сред(Стр, ПозРазделителя + ?(Режим=2, 0, ДлинаРазделителя));
Стр = СокрЛП(Лев(Стр, ПозРазделителя - ?(Режим=1, -ДлинаРазделителя+1, 1)));
КонецЕсли;
Возврат(ПраваяЧасть);
КонецФункции // вОтделитьРазделителем()
// Проверяет попадание даты внутрь интервала всключая границы
Функция ЛиДатаВИнтервалеСГраницамиЛкс(ПроверяемаяДата, НачалоПериода, КонецПериода) Экспорт
ЛиДатаВНеИнтервале = Ложь
Или (Истина
И ЗначениеЗаполнено(НачалоПериода)
И ПроверяемаяДата < НачалоПериода)
Или (Истина
И ЗначениеЗаполнено(КонецПериода)
И ПроверяемаяДата > КонецПериода);
Возврат Не ЛиДатаВНеИнтервале;
КонецФункции
// Проверяет попадание даты внутрь интервала исключая границы
Функция ЛиДатаВИнтервалеБезГраницЛкс(ПроверяемаяДата, НачалоПериода, КонецПериода) Экспорт
ПустаяДата = Дата("00010101");
ЛиДатаВНеИнтервале = Ложь
Или (Истина
И НачалоПериода <> ПустаяДата
И ПроверяемаяДата <= НачалоПериода)
Или (Истина
И КонецПериода <> ПустаяДата
И ПроверяемаяДата >= КонецПериода);
Возврат Не ЛиДатаВНеИнтервале;
КонецФункции
Функция ЛиСобытиеОшибкиФоновогоЗаданияЛкс(ИмяСобытияЖурнала) Экспорт
Результат = Ложь
Или ИмяСобытияЖурнала = "_$Job$_.Fail"
Или ИмяСобытияЖурнала = "_$Job$_.Error";
Возврат Результат;
КонецФункции
Функция ЛиСобытиеУспехаФоновогоЗаданияЛкс(ИмяСобытияЖурнала) Экспорт
Результат = Ложь
Или ИмяСобытияЖурнала = "_$Job$_.Finish"
Или ИмяСобытияЖурнала = "_$Job$_.Succeed";
Возврат Результат;
КонецФункции
Функция ЛиКаталогДоступенЛкс(Каталог, ВыводитьСообщения = Истина) Экспорт
ПроверочныйФайл = Новый Файл(Каталог);
Попытка
ЭтоКаталог = ПроверочныйФайл.ЭтоКаталог();
Исключение
Если ВыводитьСообщения Тогда
СообщитьЛкс("Указанный путь """ + Каталог + """ не доступен: " + ОписаниеОшибки());
КонецЕсли;
Возврат Ложь;
КонецПопытки;
Если Не ЭтоКаталог Тогда
Если ВыводитьСообщения Тогда
СообщитьЛкс("Указанный путь """ + Каталог + """ не является каталогом");
КонецЕсли;
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции
// http://www.hostedredmine.com/issues/882395
// Параметры:
// ПоказатьОповещениеВУП - Булево - показать оповещение в управляемом приложении - применяется при отказе от открытия формы
Процедура СообщитьЛкс(ТекстСообщения, Статус = Неопределено, ТолькоВоВременноеОкно = Ложь, ПоказатьОповещениеВУП = Ложь) Экспорт
Если Не ЗначениеЗаполнено(ТекстСообщения) Тогда
Возврат;
КонецЕсли;
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Форма = ирКэш.ВременноеОкноСообщенийЛкс();
Форма.ВывестиСообщение(ТекстСообщения);
Если ПоказатьОповещениеВУП Тогда
ПоказатьОповещениеПользователя(,, ТекстСообщения);
КонецЕсли;
#КонецЕсли
Если Не ТолькоВоВременноеОкно Тогда
Сообщить(ТекстСообщения, Статус);
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСтрокуФильтраДляВыбораФайлаЛкс(СтрокаРасширений, ОписаниеФормата = "", РазрешитьВсеФайлы = Истина) Экспорт
Расширения = СтрРазделитьЛкс(СтрокаРасширений, ",", Истина);
Результат = "";
Для Каждого Расширение Из Расширения Цикл
Если Результат <> "" Тогда
Результат = Результат + "|";
КонецЕсли;
ОписаниеРасширения = "(*." + Расширение + ")|*." + Расширение;
Если ЗначениеЗаполнено(ОписаниеФормата) Тогда
ОписаниеРасширения = ОписаниеФормата + " " + ОписаниеРасширения;
КонецЕсли;
Результат = Результат + ОписаниеРасширения;
КонецЦикла;
Если РазрешитьВсеФайлы Тогда
Результат = Результат + "|Все файлы (*.*)|*.*";
КонецЕсли;
Возврат Результат;
КонецФункции
// Копирует все элементы переданного массива, структуры, соответствия, списка значений или коллекции объектов метаданных
// в однотипную коллекцию приемник (для метаданных в массив). Если коллекция приемник не указана, она будет создана.
// Фиксированные коллекции превращаются в нефиксированные.
//
// Параметры:
// КоллекцияИсходная - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - исходная коллекция;
// КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных, *Неопределено - коллекция приемник.
//
// Возвращаемое значение:
// КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - коллекция приемник.
//
Функция СкопироватьУниверсальнуюКоллекциюЛкс(КоллекцияИсточник, КоллекцияПриемник = Неопределено) Экспорт
Если КоллекцияИсточник <> Неопределено И КоллекцияИсточник = КоллекцияПриемник Тогда
ВызватьИсключение "Нельзя загружать коллекцию в саму себя";
КонецЕсли;
ТипКоллекции = ТипЗнч(КоллекцияИсточник);
Если Ложь
Или ТипКоллекции = Тип("Массив")
Или ТипКоллекции = Тип("ФиксированныйМассив")
#Если Не ТонкийКлиент И Не ВебКлиент Тогда
Или ТипКоллекции = Тип("КоллекцияОбъектовМетаданных")
#КонецЕсли
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Массив;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Добавить(Элемент);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли Ложь
Или ТипКоллекции = Тип("Структура")
Или ТипКоллекции = Тип("ФиксированнаяСтруктура")
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Структура;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли Ложь
Или ТипКоллекции = Тип("Соответствие")
Или ТипКоллекции = Тип("ФиксированноеСоответствие")
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Соответствие;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли ТипКоллекции = Тип("СписокЗначений") Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый СписокЗначений;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
ЗаполнитьЗначенияСвойств(КоллекцияПриемник.Добавить(), Элемент);
КонецЦикла;
Возврат КоллекцияПриемник;
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
ИначеЕсли ТипКоллекции = Тип("ТаблицаЗначений") Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = КоллекцияИсточник.СкопироватьКолонки();
КонецЕсли;
ЗагрузитьВТаблицуЗначенийЛкс(КоллекцияИсточник, КоллекцияПриемник);
Возврат КоллекцияПриемник;
#КонецЕсли
Иначе
СообщитьЛкс("Неверный тип универсальной коллекции для копирования """ + ТипКоллекции + """");
Возврат Неопределено;
КонецЕсли;
КонецФункции
Функция ОтборУстановленЛкс(Отбор) Экспорт
Для Каждого ЭлементОтбора Из Отбор Цикл
Если ЭлементОтбора.Использование Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
////////////////////////////////////
// Задания форм
Функция НайтиПоСсылкамЛкс(СсылкиНа, АдресРезультата = Неопределено, ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = Неопределено, РазрешитьАсинхронно = Ложь,
Перезапустить = Ложь) Экспорт
Если Ложь
Или Кнопка = Неопределено
Или ЭтаФорма = Неопределено
Или РазрешитьАсинхронно = Ложь
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
СостояниеЛкс("Поиск ссылок...");
ТаблицаСсылок = ирПривилегированный.НайтиПоСсылкамЛкс(СсылкиНа);
ирОбщий.ПеревестиКолонкиНайтиПоСсылкамЛкс(ТаблицаСсылок);
СостояниеЛкс("");
Результат = Новый Структура;
Результат.Вставить("ТаблицаСсылок", ТаблицаСсылок);
Результат.Вставить("СсылкиНа", СсылкиНа);
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
Иначе
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(СсылкиНа);
ПараметрыЗадания.Добавить(АдресРезультата);
ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма
ПараметрыЗадания.Добавить(Неопределено); // Кнопка
ПараметрыЗадания.Добавить(Неопределено); // ОбработчикЗавершения
ПараметрыЗадания.Добавить(Неопределено); // РазрешитьАсинхронно
ПараметрыЗадания.Добавить(Неопределено); // Перезапустить
Представление = "Ссылки на " + РасширенноеПредставлениеЗначенияЛкс(СсылкиНа);
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс("СсылкиНа", "ирОбщий.НайтиПоСсылкамЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения, АдресРезультата);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания, Перезапустить);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьТекстЗапросаСтатистикиПоТаблицеЛкс(ПолноеИмяМДИлиТаблицы, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок", ЛиТаблицыИзменений = Ложь,
СтруктураОтбора = Неопределено, ТолькоРазрешенные = Ложь, ЭтоПолноеИмяТаблицы = Ложь) Экспорт
ТекстЧастиОбъединения = "
|ВЫБРАТЬ";
Если Не ЭтоПолноеИмяТаблицы Тогда
ИмяТаблицы = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМДИлиТаблицы, ЛиТаблицыИзменений, Ложь, ТолькоРазрешенные);
Если ИмяТаблицы = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| """ + ПолноеИмяМДИлиТаблицы + """ КАК " + ИмяКлючевойКолонки + ",";
Иначе
ИмяТаблицы = ПолноеИмяМДИлиТаблицы;
КонецЕсли;
//ОписаниеТаблицы = ОписаниеТаблицыБДЛкс(ИмяТаблицы);
//Если ОписаниеТаблицы.ЕстьДоступ = Ложь Тогда
// Возврат Неопределено;
//КонецЕсли;
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| """ + ИмяТаблицы + """ КАК ИмяТаблицы,
| Количество(*) КАК " + ИмяКолонкиКоличества + ",";
Если ЛиТаблицыИзменений Тогда
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| Узел,
| СУММА(ВЫБОР КОГДА Т.НомерСообщения ЕСТЬ NULL ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) КАК КоличествоНевыгруженных,
| СУММА(ВЫБОР КОГДА Т.НомерСообщения ЕСТЬ NULL ТОГДА 0 ИНАЧЕ 1 КОНЕЦ) КАК КоличествоВыгруженных,";
КонецЕсли;
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| 1
|ИЗ " + ИмяТаблицы + " КАК Т
|ГДЕ 1 = 1";
Если СтруктураОтбора <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
Если ирОбщий.СтрокиРавныЛкс("_ТипУзла_", КлючИЗначение.Ключ) Тогда
ОпределениеПоля = "ТИПЗНАЧЕНИЯ(Т.Узел)";
Иначе
ОпределениеПоля = "Т." + КлючИЗначение.Ключ;
КонецЕсли;
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| И " + ОпределениеПоля + " В (&" + КлючИЗначение.Ключ + ")";
КонецЦикла;
КонецЕсли;
Если ЛиТаблицыИзменений Тогда
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
|СГРУППИРОВАТЬ ПО Узел";
КонецЕсли;
Возврат ТекстЧастиОбъединения;
КонецФункции
// Параметры:
// ИмяКлючевойКолонки - Строка - содержит имя таблицы
//
Функция ВычислитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных = Неопределено, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок",
ЛиТаблицыИзменений = Ложь, СтруктураОтбора = Неопределено, ТолькоРазрешенные = Ложь, ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = "",
РазрешитьАсинхронно = Истина, Перезапустить = Ложь) Экспорт
МассивКлючей = Новый Массив;
Если ДеревоМетаданных <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ДеревоМетаданных = Новый ДеревоЗначений
#КонецЕсли
ЕстьКолонкаЕстьДоступ = ДеревоМетаданных.Колонки.Найти("ЕстьДоступ") <> Неопределено;
Для Каждого СтрокаДерева1 Из ДеревоМетаданных.Строки Цикл
Для Каждого СтрокаДерева2 Из СтрокаДерева1.Строки Цикл
КорневойТип = ПервыйФрагментЛкс(СтрокаДерева2[ИмяКлючевойКолонки]);
Если Ложь
Или КорневойТип = "ВнешнийИсточникДанных"
Или КорневойТип = "РегламентноеЗадание"
Или КорневойТип = "ОбщаяФорма"
Или КорневойТип = "Интерфейс"
Или КорневойТип = "Отчет"
Или КорневойТип = "Обработка"
Или (ЕстьКолонкаЕстьДоступ И СтрокаДерева2.ЕстьДоступ = Ложь)
Тогда
Продолжить;
КонецЕсли;
ИмяТаблицы = СтрокаДерева2[ИмяКлючевойКолонки];
Если Не ЗначениеЗаполнено(ИмяТаблицы) Тогда
// Например нет доступа к таблице
Продолжить;
КонецЕсли;
Если Не ЕстьКолонкаЕстьДоступ Тогда
ОписаниеТаблицы = ОписаниеТаблицыБДЛкс(ИмяТаблицы);
Если ОписаниеТаблицы.ЕстьДоступ = Ложь Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если ОбъектМДПоПолномуИмениТаблицыБДЛкс(ИмяТаблицы) = Неопределено Тогда
Продолжить;
КонецЕсли;
МассивКлючей.Добавить(ИмяТаблицы);
Для Каждого СтрокаДерева3 Из СтрокаДерева2.Строки Цикл
Если ЕстьКолонкаЕстьДоступ И СтрокаДерева3.ЕстьДоступ = Ложь Тогда
Продолжить;
КонецЕсли;
ИмяДочернейТаблицы = СтрокаДерева3[ИмяКлючевойКолонки];
Если Не ЕстьКолонкаЕстьДоступ Тогда
ОписаниеТаблицы = ОписаниеТаблицыБДЛкс(ИмяДочернейТаблицы);
Если ОписаниеТаблицы.ЕстьДоступ = Ложь Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
МассивКлючей.Добавить(ИмяДочернейТаблицы);
КонецЦикла;
КонецЦикла;
КонецЦикла;
КлючамиЗаданыИменаТаблиц = Ложь;
Иначе
ЛокальныеТаблицы = ирКэш.ТаблицаВсехТаблицБДЛкс().Скопировать(Новый Структура("Схема", ""), "ПолноеИмя, Тип, ЕстьДоступ");
НачальноеКоличество = ЛокальныеТаблицы.Количество();
Для СчетчикЛокальныеТаблицы = 1 По НачальноеКоличество Цикл
ОписаниеТаблицы = ЛокальныеТаблицы[НачальноеКоличество - СчетчикЛокальныеТаблицы];
Если Ложь
Или ОписаниеТаблицы.Тип = "ВиртуальнаяТаблица"
Или ОписаниеТаблицы.ЕстьДоступ = Ложь
Тогда
ЛокальныеТаблицы.Удалить(ОписаниеТаблицы);
КонецЕсли;
КонецЦикла;
МассивКлючей = ЛокальныеТаблицы.ВыгрузитьКолонку("ПолноеИмя");
КлючамиЗаданыИменаТаблиц = Истина;
КонецЕсли;
ТекстПакета = "";
ТекстЗапроса = "";
СчетчикТаблиц = 0;
Для Каждого ПолноеИмяМД Из МассивКлючей Цикл
ТекстЧастиОбъединения = ПолучитьТекстЗапросаСтатистикиПоТаблицеЛкс(ПолноеИмяМД, ИмяКлючевойКолонки, ИмяКолонкиКоличества, ЛиТаблицыИзменений, СтруктураОтбора, ТолькоРазрешенные,
КлючамиЗаданыИменаТаблиц);
Если ТекстЧастиОбъединения = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ТекстЗапроса <> "" Тогда
ТекстЗапроса = ТекстЗапроса + "
|ОБЪЕДИНИТЬ ВСЕ";
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + ТекстЧастиОбъединения;
СчетчикТаблиц = СчетчикТаблиц + 1;
Если СчетчикТаблиц = 255 Тогда
СчетчикТаблиц = 0;
Если ТекстПакета <> "" Тогда
ТекстПакета = ТекстПакета + "
|;";
КонецЕсли;
ТекстПакета = ТекстПакета + ТекстЗапроса;
ТекстЗапроса = "";
КонецЕсли;
КонецЦикла;
Если ТекстПакета <> "" Тогда
ТекстПакета = ТекстПакета + "
|;";
КонецЕсли;
ТекстПакета = ТекстПакета + ТекстЗапроса;
Если ЗначениеЗаполнено(ТекстПакета) Тогда
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ТекстПакета);
ПараметрыЗадания.Добавить(СтруктураОтбора);
ПараметрыЗадания.Добавить(ИмяКолонкиКоличества);
Если Ложь
Или РазрешитьАсинхронно = Ложь
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
Результат = ВыполнитьЗапросСтатистикиПоТаблицамЛкс(ТекстПакета, СтруктураОтбора, ИмяКолонкиКоличества);
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
КонецЕсли;
Иначе
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания.Добавить(АдресРезультата);
Представление = "Сбор статистики таблиц";
#Если Сервер И Не Сервер Тогда
ирСервер.ВыполнитьЗапросСтатистикиПоТаблицамЛкс();
#КонецЕсли
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс("Выгрузка", "ирСервер.ВыполнитьЗапросСтатистикиПоТаблицамЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения,
АдресРезультата);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания, Перезапустить);
КонецЕсли;
Иначе
Результат = Новый Массив();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ВыполнитьЗапросСтатистикиПоТаблицамЛкс(Знач ТекстПакета, СтруктураОтбора = Неопределено, ИмяКолонкиКоличества = "КоличествоСтрок") Экспорт
#Если Клиент Тогда
СостояниеЛкс("Сбор статистики таблиц...");
#КонецЕсли
Запрос = Новый Запрос;
Если СтруктураОтбора <> Неопределено Тогда
СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураОтбора, Запрос.Параметры);
КонецЕсли;
Запрос.Текст = ТекстПакета;
РезультатПакета = Запрос.ВыполнитьПакет();
Результат = Новый Массив();
Для Каждого РезультатЗапроса Из РезультатПакета Цикл
Результат.Добавить(РезультатЗапроса.Выгрузить());
КонецЦикла;
Если Не ирКэш.ЭтоФоновоеЗаданиеЛкс() И СтруктураОтбора = Неопределено Тогда
ЗаполнитьКоличестваСтрокВТаблицеВсехТаблицЛкс(Результат, ИмяКолонкиКоличества);
КонецЕсли;
#Если Клиент Тогда
СостояниеЛкс("");
#КонецЕсли
Возврат Результат;
КонецФункции
Процедура ЗаполнитьКоличестваСтрокВТаблицеВсехТаблицЛкс(РезультатыЗапросов, Знач ИмяКолонкиКоличества = "КоличествоСтрок") Экспорт
СписокТаблиц = ирКэш.ТаблицаВсехТаблицБДЛкс();
Для Каждого ТаблицаРезультата Из РезультатыЗапросов Цикл
Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл
ОписаниеТаблицы = СписокТаблиц.Найти(НРег(СтрокаРезультата.ИмяТаблицы), "НПолноеИмя");
ОписаниеТаблицы.КоличествоСтрок = СтрокаРезультата[ИмяКолонкиКоличества];
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура ОбновитьИндексПолнотекстовогоПоискаЛкс(ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = Неопределено, Перезапустить = Ложь) Экспорт
Представление = "Обновление индекса полнотекстового поиска";
ПараметрыЗадания = Новый Массив;
Если Ложь
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
СостояниеЛкс(Представление + "...");
ПолнотекстовыйПоиск.ОбновитьИндекс(Истина,Ложь);
СостояниеЛкс("");
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "()");
КонецЕсли;
Иначе
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс("Выгрузка", "ирОбщий.ОбновитьИндексПолнотекстовогоПоискаЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания, Перезапустить);
КонецЕсли;
КонецПроцедуры
Процедура ОбновитьИсториюДанныхЛкс(ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = Неопределено, Перезапустить = Ложь) Экспорт
Представление = "Обновление истории данных";
ПараметрыЗадания = Новый Массив;
Если Ложь
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
СостояниеЛкс(Представление + "...");
ИсторияДанныхМоя = Вычислить("ИсторияДанных");
#Если Сервер И Не Сервер Тогда
ИсторияДанныхМоя = ИсторияДанных;
#КонецЕсли
ИсторияДанныхМоя.ОбновитьИсторию();
СостояниеЛкс("");
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "()");
КонецЕсли;
Иначе
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс("Выгрузка", "ирОбщий.ОбновитьИсториюДанныхЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания, Перезапустить);
КонецЕсли;
КонецПроцедуры
// Параметры:
// ТаблицаЗаданий - ? -
// ДляСбораСтатистики - ? -
// КонечныйОтбор - ? -
// ОтборФоновыхЗаданий - ? -
// ОтображатьИндикатор - ? -
// ПолучатьОшибкиИзЖурнала - ? -
// ПолучатьСообщенияПользователю - ? -
// ФоновыеЗаданияСоответствие - ? -
Функция ФоновыеЗаданияПодробноЛкс(ТаблицаЗаданий, ДляСбораСтатистики, КонечныйОтбор, ОтборФоновыхЗаданий, ОтображатьИндикатор, ВызовВнутриОбновленияРегламентныхЗаданий,
АвтообновлениеСпискаМетодов = Ложь, ПолучатьОшибкиИзЖурнала = Ложь, ПолучатьСообщенияПользователю = Ложь, ФоновыеЗаданияСоответствие = Неопределено,
ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = "", РазрешитьАсинхронно = Истина, Перезапустить = Ложь) Экспорт
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ТаблицаЗаданий);
ПараметрыЗадания.Добавить(ДляСбораСтатистики);
ПараметрыЗадания.Добавить(КонечныйОтбор);
ПараметрыЗадания.Добавить(ОтборФоновыхЗаданий);
ПараметрыЗадания.Добавить(ОтображатьИндикатор);
ПараметрыЗадания.Добавить(ВызовВнутриОбновленияРегламентныхЗаданий);
Если Ложь
Или РазрешитьАсинхронно = Ложь
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
Если ЭтаФорма <> Неопределено Тогда
КонсольЗаданий = ЭтаФорма.ЭтотОбъект;
Иначе
КонсольЗаданий = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗаданий");
КонецЕсли;
#Если Сервер И Не Сервер Тогда
КонсольЗаданий = Обработки.ирКонсольЗаданий.Создать();
#КонецЕсли
Фоновые = КонсольЗаданий.ПолучитьФоновыеЗадания(КонечныйОтбор);
Если ОтборФоновыхЗаданий.Свойство("Начало") Тогда
КонечныйОтбор.Удалить("Начало");
КонечныйОтбор.Вставить("Состояние", СостояниеФоновогоЗадания.Активно);
АктивныеФоновыеЗадания = КонсольЗаданий.ПолучитьФоновыеЗадания(КонечныйОтбор);
Для Каждого АктивноеФоновоеЗадание Из АктивныеФоновыеЗадания Цикл
Если АктивноеФоновоеЗадание.Начало < ОтборФоновыхЗаданий.Начало Тогда
Фоновые.Добавить(АктивноеФоновоеЗадание);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ОтображатьИндикатор Тогда
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Фоновые.Количество(), "Чтение фоновых заданий");
КонецЕсли;
МоментНачалаОбновления = ТекущаяДата();
Для Каждого Фоновое из Фоновые Цикл
#Если Сервер И Не Сервер Тогда
Фоновое = ФоновыеЗадания.НайтиПоУникальномуИдентификатору();
#КонецЕсли
Если Индикатор <> Неопределено Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
Длительность = КонсольЗаданий.ДлительностьФоновогоЗадания(Фоновое);
Если Не ДляСбораСтатистики Тогда
// https://www.hostedredmine.com/issues/905460
//Если ОтборПоПустомуРегламентномуЗаданию Тогда
// Если ТекущаяДата() - МоментНачалаОбновления > 5 Тогда
// Сообщить("Заполнение списка запущенных из кода фоновых заданий прервано из-за большой длительности. При необходимости снимите отбор по текущему регламентному заданию.");
// Прервать;
// КонецЕсли;
// // Очень тяжелая (бывает 0.3 секунды) операция в некоторых случаях http://www.hostedredmine.com/issues/850228
// Если Фоновое.РегламентноеЗадание <> Неопределено Тогда
// Продолжить;
// КонецЕсли;
//КонецЕсли;
Если Истина
И КонечныйОтбор.Свойство("ДлительностьМин")
Тогда
Если Ложь
Или КонечныйОтбор.ДлительностьМин > Длительность
Или (Истина
И КонечныйОтбор.ДлительностьМакс > 0
И КонечныйОтбор.ДлительностьМакс < Длительность)
Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
КонецЕсли;
НоваяСтрока = ТаблицаЗаданий.Добавить();
КонсольЗаданий.ОбновитьСтрокуФоновогоЗадания(НоваяСтрока, Фоновое, Длительность);
Если Не ДляСбораСтатистики Тогда
ФоновыеЗаданияСоответствие[Строка(Фоновое.УникальныйИдентификатор)] = Фоновое;
Если ПолучатьСообщенияПользователю Тогда
МассивСообщений = ирОбщий.СообщенияПользователюОтФоновогоЗаданияЛкс(Фоновое);
НоваяСтрока.СообщенияПользователю = МассивСообщений.Количество();
КонецЕсли;
Если ПолучатьОшибкиИзЖурнала Тогда
СтруктураОтбора = КонсольЗаданий.ОтборДляЖурналаПоФоновымЗаданиям(НоваяСтрока);
СтруктураОтбора.Вставить("Уровень", "Ошибка"); // Передаем в виде строки, т.к. кэширование не допускает родной тип
НоваяСтрока.ОшибкиЖР = КонсольЗаданий.КоличествоОшибокВЖурнале(Фоновое.Начало, Фоновое.Конец, СтруктураОтбора);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Индикатор <> Неопределено Тогда
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("ТаблицаЗаданий", ТаблицаЗаданий);
Результат.Вставить("ДляСбораСтатистики", ДляСбораСтатистики);
Результат.Вставить("ВызовВнутриОбновленияРегламентныхЗаданий", ВызовВнутриОбновленияРегламентныхЗаданий);
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
КонецЕсли;
Иначе
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания.Добавить(АдресРезультата);
Представление = "Чтение всех фоновых заданий";
#Если Сервер И Не Сервер Тогда
ирСервер.ФоновыеЗаданияПодробноЛкс();
#КонецЕсли
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс("ЧтениеФоновыхЗаданий", "ирСервер.ФоновыеЗаданияПодробноЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения, АдресРезультата,
Не АвтообновлениеСпискаМетодов);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания, Перезапустить);
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ИсторияДанных_ОбновитьИтогиПоТипамЛкс(ОбщиеПараметрыОбработки, ОтборВерсий, Знач АдресРезультата = Неопределено,
ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = "", РазрешитьАсинхронно = Истина, Перезапустить = Ложь) Экспорт
Если Ложь
Или РазрешитьАсинхронно = Ложь
//Или Кнопка = Неопределено
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
Если ЭтаФорма <> Неопределено Тогда
Обработка = ЭтаФорма.ЭтотОбъект;
Иначе
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = Обработки.ирИсторияДанных.Создать();
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
КонецЕсли;
Обработка.РассчитатьИтогиИсторииПоТипам(ОтборВерсий);
Результат = Новый Структура;
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
Иначе
Результат.Вставить("Типы", Обработка.Типы.Выгрузить());
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
Представление = "Итоги истории данных";
ИмяЗадания = "ИтогиИсторииДанных";
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки);
ПараметрыЗадания.Добавить(ОтборВерсий);
ПараметрыЗадания.Добавить(АдресРезультата);
ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма
ПараметрыЗадания.Добавить(Неопределено); // Кнопка
ПараметрыЗадания.Добавить(Неопределено); // ОбработчикЗавершения
ПараметрыЗадания.Добавить(Неопределено); // РазрешитьАсинхронно
ПараметрыЗадания.Добавить(Неопределено); // Перезапустить
ДобавитьПереданныйКэшВСтруктуруЛкс(ОбщиеПараметрыОбработки);
#Если Сервер И Не Сервер Тогда
ирСервер.ИсторияДанных_ОбновитьИтогиПоТипамЛкс();
#КонецЕсли
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс(ИмяЗадания, "ирОбщий.ИсторияДанных_ОбновитьИтогиПоТипамЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения, АдресРезультата);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания, Перезапустить);
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ИсторияДанных_ОбновитьВерсииЛкс(ОбщиеПараметрыОбработки, ПолноеИмяМД, ОтборВерсий, Знач АдресРезультата = Неопределено,
ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = "", РазрешитьАсинхронно = Истина, Перезапустить = Ложь) Экспорт
Если Ложь
Или РазрешитьАсинхронно = Ложь
//Или Кнопка = Неопределено
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
Если ЭтаФорма <> Неопределено Тогда
Обработка = ЭтаФорма.ЭтотОбъект;
Иначе
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = Обработки.ирИсторияДанных.Создать();
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
КонецЕсли;
ТаблицаВерсий = Обработка.ВыбратьВерсииПоОбъектуМД(ПолноеИмяМД, ОтборВерсий);
Результат = Новый Структура;
Результат.Вставить("ТаблицаВерсий", ТаблицаВерсий);
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
Иначе
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
Представление = "Выборка версий";
ИмяЗадания = "ВыборкаВерсий";
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки);
ПараметрыЗадания.Добавить(ПолноеИмяМД);
ПараметрыЗадания.Добавить(ОтборВерсий);
ПараметрыЗадания.Добавить(АдресРезультата);
//ДобавитьПереданныйКэшВСтруктуруЛкс(ОбщиеПараметрыОбработки);
#Если Сервер И Не Сервер Тогда
ирСервер.ИсторияДанных_ОбновитьВерсииЛкс();
#КонецЕсли
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс(ИмяЗадания, "ирОбщий.ИсторияДанных_ОбновитьВерсииЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения, АдресРезультата);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания, Перезапустить);
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СравнениеТаблиц_СравнитьЛкс(ОбщиеПараметрыОбработки, МоментНачала, Знач АдресРезультата = Неопределено,
ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = "") Экспорт
Если Ложь
Или Кнопка = Неопределено
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
Если ЭтаФорма <> Неопределено Тогда
Обработка = ЭтаФорма.ЭтотОбъект;
Иначе
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = Обработки.ирСравнениеТаблиц.Создать();
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
Обработка.КолонкиТаблица1.Загрузить(ОбщиеПараметрыОбработки.КолонкиТаблица1);
Обработка.КолонкиТаблица2.Загрузить(ОбщиеПараметрыОбработки.КолонкиТаблица2);
КонецЕсли;
ЛиТаблицыРавны = Обработка.ВыполнитьСравнение();
Результат = Новый Структура(Обработка.мИменаВозвращаемыхСвойств);
ЗаполнитьЗначенияСвойств(Результат, Обработка);
Результат.Вставить("МоментНачала", МоментНачала);
Результат.Вставить("ЛиТаблицыРавны", ЛиТаблицыРавны);
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
Иначе
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
Представление = "Сравнение таблиц";
ИмяЗадания = "СравнениеТаблиц";
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки);
ПараметрыЗадания.Добавить(МоментНачала);
ПараметрыЗадания.Добавить(АдресРезультата);
ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма
ПараметрыЗадания.Добавить(Неопределено); // Кнопка
ПараметрыЗадания.Добавить(Неопределено); // ОбработчикЗавершения
ДобавитьПереданныйКэшВСтруктуруЛкс(ОбщиеПараметрыОбработки);
#Если Сервер И Не Сервер Тогда
ирСервер.СравнениеТаблиц_СравнитьЛкс();
#КонецЕсли
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс(ИмяЗадания, "ирОбщий.СравнениеТаблиц_СравнитьЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения, АдресРезультата);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания);
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ВычислятьФункциональныеОпции - Булево -
// ИменаРолей - Массив -
// ИспользоватьНаборПолей - Булево -
// НаборПолейТаблица - ТаблицаЗначений - Обработка.ирАнализПравДоступа.ТабличнаяЧасть.НаборПолейТаблица
// ОбъектМетаданных - Строка -
// ПолеОбъекта - Строка -
// Возвращаемое значение:
// Структура - ("ТаблицаРолей, ФункциональныеОпции, ФункциональныеОпцииПолей")
Функция ВычислитьПраваДоступаЛкс(ОбщиеПараметрыОбработки, ИменаРолей, АдресРезультата = Неопределено, ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = "") Экспорт
Если Ложь
Или Кнопка = Неопределено
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
Если ЭтаФорма <> Неопределено Тогда
Обработка = ЭтаФорма.ЭтотОбъект;
Иначе
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = Отчеты.ирАнализПравДоступа.Создать();
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
КонецЕсли;
Обработка.ВычислитьПрава(ИменаРолей);
Результат = Новый Структура;
Результат.Вставить("ТаблицаПрав", Обработка.ТаблицаПрав);
Результат.Вставить("ФункциональныеОпцииПолей", Обработка.ФункциональныеОпцииПолей.Выгрузить());
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
Иначе
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки);
ПараметрыЗадания.Добавить(ИменаРолей);
ПараметрыЗадания.Добавить(АдресРезультата);
ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма
ПараметрыЗадания.Добавить(Неопределено); // Кнопка
ПараметрыЗадания.Добавить(Неопределено); // ОбработчикЗавершения
Представление = "Вычисление прав доступа";
#Если Сервер И Не Сервер Тогда
ирОбщий.ВычислитьПраваДоступаЛкс();
#КонецЕсли
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс("Сформировать", "ирОбщий.ВычислитьПраваДоступаЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения, АдресРезультата);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания);
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СобратьОбъектыМДОдногоТипаЛкс(ОбщиеПараметрыОбработки, АдресРезультата = Неопределено,
ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = "") Экспорт
Если Ложь
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
Если ЭтаФорма <> Неопределено Тогда
Обработка = ЭтаФорма.ЭтотОбъект;
Иначе
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = Отчеты.ирАнализМетаданных.Создать();
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
КонецЕсли;
Обработка.СобратьОбъектыМетаданных();
Результат = Новый Структура;
Результат.Вставить("мОбъекты", ирОбщий.ТаблицаСМинимальнымиТипамиКолонокЛкс(Обработка.мОбъекты));
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
Иначе
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки);
ПараметрыЗадания.Добавить(АдресРезультата);
ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма
ПараметрыЗадания.Добавить(Неопределено); // Кнопка
ПараметрыЗадания.Добавить(Неопределено); // ОбработчикЗавершения
Представление = "Сбор объектов метаданных";
#Если Сервер И Не Сервер Тогда
ирОбщий.СобратьОбъектыМДОдногоТипаЛкс();
#КонецЕсли
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс("Сформировать", "ирОбщий.СобратьОбъектыМДОдногоТипаЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения, АдресРезультата);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания);
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ВыполнитьЗапросЛкс(ТекстЗапроса, Параметры = Неопределено, ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = Неопределено, Перезапустить = Ложь) Экспорт
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ТекстЗапроса);
ПараметрыЗадания.Добавить(Параметры);
Если Ложь
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Тогда
#Если Клиент Тогда
СостояниеЛкс("Выполнение запроса...");
#КонецЕсли
Запрос = Новый Запрос(ТекстЗапроса);
Если Параметры <> Неопределено Тогда
ирОбщий.СкопироватьУниверсальнуюКоллекциюЛкс(Параметры, Запрос.Параметры);
КонецЕсли;
РезультатПакета = Запрос.ВыполнитьПакет();
#Если Клиент Тогда
СостояниеЛкс("");
#КонецЕсли
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, РезультатПакета)");
РезультатПакета = Неопределено;
КонецЕсли;
Иначе
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания.Добавить(АдресРезультата);
Представление = "Выполнение запроса";
#Если Сервер И Не Сервер Тогда
ирСервер.ВыполнитьЗапросЛкс();
#КонецЕсли
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс("ВыполнениеЗапроса", "ирСервер.ВыполнитьЗапросЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения, АдресРезультата);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания, Перезапустить);
КонецЕсли;
Возврат РезультатПакета;
КонецФункции
Функция ПрочитатьТехножурналЛкс(МоментНачалаЗагрузки, ОбщиеПараметрыОбработки, ФильтрЗагрузки, ЭтаФорма = Неопределено, Кнопка = Неопределено, ОбработчикЗавершения = Неопределено, Перезапустить = Ложь) Экспорт
Если Ложь
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Или Не ОбщиеПараметрыОбработки.ВыполнятьНаСервере
Тогда
Если ЭтаФорма <> Неопределено Тогда
Обработка = ЭтаФорма.ЭтотОбъект;
Иначе
Обработка = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирАнализТехножурнала");
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирАнализТехножурнала.Создать();
#КонецЕсли
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
КонецЕсли;
Успех = Обработка.ПрочитатьЖурнал(ФильтрЗагрузки);
Результат = Новый Структура(Обработка.мИменаВозвращаемыхСвойств);
ЗаполнитьЗначенияСвойств(Результат, Обработка);
Результат.Вставить("Успех", Успех);
Результат.Вставить("МоментНачалаЗагрузки", МоментНачалаЗагрузки);
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
Иначе
Результат.Вставить("ТаблицаЖурнала", Обработка.ТаблицаЖурнала.Выгрузить());
КонецЕсли;
Иначе
ОбщиеПараметрыОбработки.ТаблицаЖурнала = ОбщиеПараметрыОбработки.ТаблицаЖурнала.Выгрузить();
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(МоментНачалаЗагрузки);
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки);
ПараметрыЗадания.Добавить(ФильтрЗагрузки);
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания.Добавить(АдресРезультата);
Представление = "Загрузка техножурнала";
#Если Сервер И Не Сервер Тогда
ирСервер.ПрочитатьТехножурналЛкс();
#КонецЕсли
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс("ЗагрузкаТехножурнала", "ирСервер.ПрочитатьТехножурналЛкс", ПараметрыЗадания, Представление, Кнопка, ОбработчикЗавершения, АдресРезультата);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания, Перезапустить);
КонецЕсли;
Возврат Результат;
КонецФункции
/////////////////////////////////////
// Параметры:
// ИсключаяБезымянные - Булево, *Истина - механизм перетаскивания зачем то добавляет свою колонку в таблицу-копию перетаскиваемых строк, а этот параметр включает их игнорирование
//
// Результат - Булево
Функция ЛиКолонкиТаблицСовпадаютЛкс(Таблица1, Таблица2, ИсключаяБезымянные = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
Таблица1 = новый ТаблицаЗначений;
Таблица2 = новый ТаблицаЗначений;
#КонецЕсли
Колонки1 = Новый СписокЗначений;
Для Каждого Колонка Из Таблица1.Колонки Цикл
Если ИсключаяБезымянные И Не ЗначениеЗаполнено(Колонка.Имя) Тогда
Продолжить;
КонецЕсли;
Колонки1.Добавить(Колонка.ТипЗначения, Колонка.Имя);
КонецЦикла;
Колонки1.СортироватьПоПредставлению();
Колонки2 = Новый СписокЗначений;
Для Каждого Колонка Из Таблица2.Колонки Цикл
Если ИсключаяБезымянные И Не ЗначениеЗаполнено(Колонка.Имя) Тогда
Продолжить;
КонецЕсли;
Колонки2.Добавить(Колонка.ТипЗначения, Колонка.Имя);
КонецЦикла;
Колонки2.СортироватьПоПредставлению();
Результат = СохранитьОбъектВВидеСтрокиXMLЛкс(Колонки1) = СохранитьОбъектВВидеСтрокиXMLЛкс(Колонки2);
Возврат Результат;
КонецФункции
Процедура ВычислитьВыраженияПараметровЛкс(Знач ТаблицаВычисляемыхПараметров, СтруктураПараметров, Знач МодальныйРежим = Ложь, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
СтруктураПараметровXML = ирОбщий.СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров);
ирСервер.ВычислитьВыраженияПараметровЛкс(ТаблицаВычисляемыхПараметров, СтруктураПараметровXML);
СтруктураПараметров = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(СтруктураПараметровXML);
Иначе
Для каждого СтрокаПараметра Из ТаблицаВычисляемыхПараметров Цикл
Значение = Неопределено;
Если ЗначениеЗаполнено(СтрокаПараметра.Выражение) Тогда
ТекстАлгоритма = "
|Параметры = _П0;
|лПараметры = _П0; // Устаревшее
|Результат = " + СтрокаПараметра.Выражение;
Попытка
Значение = ВыполнитьАлгоритм(ТекстАлгоритма,,, СтруктураПараметров);
Исключение
СообщитьСУчетомМодальностиЛкс("Ошибка при вычислении параметра """ + СтрокаПараметра.ИмяПараметра + """"
+ Символы.ПС + ОписаниеОшибки(), МодальныйРежим, СтатусСообщения.Важное);
КонецПопытки;
КонецЕсли;
СтруктураПараметров.Вставить(СтрокаПараметра.ИмяПараметра, Значение);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьГрубоКоличествоСтрокВРезультатеЗапросаЛкс(ЗапросИлиПостроитель, ЛиЗамерВремени = Ложь, МодальныйРежим = Ложь, ИмяЗапроса = "") Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если ТипЗнч(ЗапросИлиПостроитель) = Тип("ПостроительЗапроса") Тогда
Запрос = ЗапросИлиПостроитель.ПолучитьЗапрос();
Иначе
Запрос = ЗапросИлиПостроитель;
КонецЕсли;
ОригинальныйТекстЗапроса = Запрос.Текст;
// Исключаем тяжелые типы из финальной выборки
МассивИменВременныхТаблиц = Новый Массив();
ТекстПостроителя = мПлатформа.ЗамаскироватьВременныеТаблицы(Запрос, , МассивИменВременныхТаблиц);
ПостроительЗапроса = Новый ПостроительЗапроса;
Попытка
ПостроительЗапроса.Текст = ТекстПостроителя;
Исключение
ОписаниеОшибки = ОписаниеОшибки();
Возврат ОписаниеОшибки;
КонецПопытки;
ПостроительЗапроса.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
ПостроительЗапроса.ЗаполнитьНастройки();
УдаляемыеВыбранныеПоля = Новый Массив;
Для Каждого ВыбранноеПоле Из ПостроительЗапроса.ВыбранныеПоля Цикл
ДоступноеПоле = ПостроительЗапроса.ДоступныеПоля.Найти(ВыбранноеПоле.Имя);
ТипЗначенияПоля = ДоступноеПоле.ТипЗначения;
Если Ложь
Или (Истина
И ТипЗначенияПоля.СодержитТип(Тип("Строка"))
И ТипЗначенияПоля.КвалификаторыСтроки.Длина = 0)
Или ТипЗначенияПоля.СодержитТип(Тип("ХранилищеЗначения"))
Тогда
УдаляемыеВыбранныеПоля.Добавить(ВыбранноеПоле);
КонецЕсли;
КонецЦикла;
Для Каждого ВыбранноеПоле Из УдаляемыеВыбранныеПоля Цикл
ПостроительЗапроса.ВыбранныеПоля.Удалить(ВыбранноеПоле);
КонецЦикла;
ПромежуточныйТекстЗапроса = ПостроительЗапроса.ПолучитьЗапрос().Текст;
ПромежуточныйТекстЗапроса = мПлатформа.РазмаскироватьВременныеТаблицы(ПромежуточныйТекстЗапроса, МассивИменВременныхТаблиц);
МассивТекстовЗапросов = мПлатформа.РазбитьГрубоТекстПакетногоЗапросаНаТекстыЗапросов(ПромежуточныйТекстЗапроса); // разбивка производится второй раз. можно оптимизировать
ТекстПоследнегоЗапроса = МассивТекстовЗапросов[МассивТекстовЗапросов.ВГраница()];
ТекстДоПоследнегоЗапроса = "";
Для Индекс = 0 По МассивТекстовЗапросов.ВГраница() - 1 Цикл
ТекстДоПоследнегоЗапроса = ТекстДоПоследнегоЗапроса + МассивТекстовЗапросов[Индекс];
КонецЦикла;
ТекстПоследнегоЗапроса = мПлатформа.ПреобразоватьЗапросВПодзапрос(ТекстПоследнегоЗапроса, "КОЛИЧЕСТВО(1) КАК КоличествоСтрок",, Истина);
Запрос.Текст = ТекстДоПоследнегоЗапроса + ТекстПоследнегоЗапроса;
#Если Клиент Тогда
НачалоПредварительногоВыполнения = мПлатформа.ПолучитьТекущееВремяВМиллисекундах();
#КонецЕсли
Попытка
РезультатПредварительногоЗапроса = Запрос.Выполнить();
ПредварительныйЗапросБылиОшибки = Ложь;
Исключение
ПредварительныйЗапросБылиОшибки = Истина;
КоличествоСтрок = ОписаниеОшибки();
КонецПопытки;
#Если Клиент Тогда
Если Истина
И ЛиЗамерВремени
И Не ПредварительныйЗапросБылиОшибки
Тогда
ирОбщий.СообщитьСУчетомМодальностиЛкс("Время формирования предварительного результата """ + ИмяЗапроса + """ - "
+ Строка(мПлатформа.ПолучитьТекущееВремяВМиллисекундах() - НачалоПредварительногоВыполнения) + " мс", МодальныйРежим);
КонецЕсли;
#КонецЕсли
Если Не ПредварительныйЗапросБылиОшибки Тогда
КоличествоСтрок = РезультатПредварительногоЗапроса.Выгрузить()[0].КоличествоСтрок;
КонецЕсли;
Запрос.Текст = ОригинальныйТекстЗапроса;
Возврат КоличествоСтрок;
КонецФункции
Функция ПолучитьГрубоКоличествоСтрокВРезультатеКомпоновкиЛкс(МакетКомпоновкиДанныхВКоллекциюЗначений, БылиОшибки = Ложь, ЛиЗамерВремени = Ложь,
МодальныйРежим = Ложь) Экспорт
КоличествоСтрокВсего = 0;
Запрос = Новый Запрос;
Для Каждого ЗначениеПараметра Из МакетКомпоновкиДанныхВКоллекциюЗначений.ЗначенияПараметров Цикл
Запрос.Параметры.Вставить(ЗначениеПараметра.Имя, ЗначениеПараметра.Значение);
КонецЦикла;
Для Каждого НаборДанных Из МакетКомпоновкиДанныхВКоллекциюЗначений.НаборыДанных Цикл
Если ТипЗнч(НаборДанных) <> Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
Запрос.Текст = НаборДанных.Запрос;
КоличествоСтрок = ПолучитьГрубоКоличествоСтрокВРезультатеЗапросаЛкс(Запрос, ЛиЗамерВремени, МодальныйРежим, НаборДанных.Имя);
Если ТипЗнч(КоличествоСтрок) = Тип("Число") Тогда
КоличествоСтрокВсего = КоличествоСтрокВсего + КоличествоСтрок;
Иначе
БылиОшибки = Истина;
КонецЕсли;
КонецЦикла;
Возврат КоличествоСтрокВсего;
КонецФункции // ПолучитьГрубоКоличествоСтрокВРезультатеКомпоновки()
Функция СкомпоноватьОтчетВКонсолиЛкс(КоллекцияВывода, Знач МакетКомпоновкиДанных, ВнешниеНаборыДанных = Неопределено, Автофиксация = Истина, МодальныйРежим = Ложь, ЛиОтладка = Ложь,
АдресДанныхРасшифровки = Неопределено, НаСервере = Ложь, МаркироватьНачалоИКонецВТехножурнале = Истина, выхЭлементыРезультата = Неопределено) Экспорт
Если НаСервере Тогда
АдресКоллекцииВывода = ПоместитьВоВременноеХранилище(КоллекцияВывода);
АдресМакетаКомпоновки = ПоместитьВоВременноеХранилище(МакетКомпоновкиДанных);
Результат = ирСервер.СкомпоноватьОтчетВКонсолиЛкс(АдресКоллекцииВывода, АдресМакетаКомпоновки, ВнешниеНаборыДанных, Автофиксация, МодальныйРежим, ЛиОтладка, АдресДанныхРасшифровки);
КоллекцияВывода = ПолучитьИзВременногоХранилища(АдресКоллекцииВывода);
Возврат Результат;
КонецЕсли;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
МакетКомпоновкиДанных = Новый МакетКомпоновкиДанных;
#КонецЕсли
// Осторожная выборка
ВыполнятьПредварительныйЗапрос = ВосстановитьЗначениеЛкс("ир_ВыполнятьПредварительныйЗапрос");
БезопасныйПорогКоличестваСтрок = ВосстановитьЗначениеЛкс("ир_БезопасныйПорогКоличестваСтрок");
Если ВыполнятьПредварительныйЗапрос = Истина Тогда
//Если ТипЗнч(КоллекцияВывода) = Тип("ТабличныйДокумент") Тогда
МакетКомпоновкиДанныхВКоллекциюЗначений = МакетКомпоновкиДанных;
//Иначе
// МакетКомпоновкиДанныхВКоллекциюЗначений = ПолучитьМакетКомпоновки("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений");
//КонецЕсли;
БылиОшибки = Ложь;
КоличествоСтрокВсего = ПолучитьГрубоКоличествоСтрокВРезультатеКомпоновкиЛкс(МакетКомпоновкиДанныхВКоллекциюЗначений, БылиОшибки, ЛиОтладка, МодальныйРежим);
ТекстВопроса = "Оценка общего размера результатов запросов макета составляет " + КоличествоСтрокВсего + " строк.";
Если БылиОшибки Тогда
ТекстВопроса = ТекстВопроса + "
|При расчете некоторые запросы не удалось проанализировать."
КонецЕсли;
Если Ложь
Или БезопасныйПорогКоличестваСтрок * 1000 < КоличествоСтрокВсего
Или БылиОшибки
Тогда
#Если Клиент Тогда
Ответ = Вопрос(ТекстВопроса + " Продолжить?", РежимДиалогаВопрос.ОКОтмена);
Отменить = Ответ <> КодВозвратаДиалога.ОК;
#Иначе
СообщитьЛкс(ТекстВопроса + " Отмена.");
Отменить = Истина;
#КонецЕсли
Если Отменить Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЛиОтладка Тогда
Запрос = Новый Запрос;
Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл
ЗначениеПараметра = Параметр.Значение;
Если ТипЗнч(ЗначениеПараметра) = Тип("ВыражениеКомпоновкиДанных") Тогда
Попытка
ЗначениеПараметра = Вычислить(ЗначениеПараметра);
Исключение
ЗначениеПараметра = Неопределено;
ирОбщий.СообщитьСУчетомМодальностиЛкс("Ошибка вычисления значения параметра """ + Параметр.Имя + """: " + ОписаниеОшибки(), МодальныйРежим, СтатусСообщения.Внимание);
КонецПопытки;
КонецЕсли;
Запрос.УстановитьПараметр(Параметр.Имя, ЗначениеПараметра);
КонецЦикла;
СтруктураНаборовДанныхЗапросовМакета = ВсеНаборыДанныхЗапросовКомпоновкиЛкс(МакетКомпоновкиДанных.НаборыДанных);
Для Каждого ЭлементНаборДанныхМакета Из СтруктураНаборовДанныхЗапросовМакета Цикл
НаборДанных = ЭлементНаборДанныхМакета.Значение.НаборДанных;
Если Не ЗначениеЗаполнено(НаборДанных.Имя) Тогда
// Служебные наборы данных пропускаем
Продолжить;
КонецЕсли;
Запрос.Текст = НаборДанных.Запрос;
ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Запрос - " + НаборДанных.Имя)
КонецЦикла;
КонецЕсли;
Если ЛиОтладка Тогда
НачалоВывода = мПлатформа.ПолучитьТекущееВремяВМиллисекундах();
КонецЕсли;
Если МаркироватьНачалоИКонецВТехножурнале Тогда
мАнализТехножурнала = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирАнализТехножурнала");
#Если Сервер И Не Сервер Тогда
мАнализТехножурнала = Обработки.ирАнализТехножурнала.Создать();
#КонецЕсли
мАнализТехножурнала.НачатьТрассу("КонсольКомпоновки");
КонецЕсли;
Если АдресДанныхРасшифровки <> Неопределено Тогда
ДанныеРасшифровки = ПолучитьИзВременногоХранилища(АдресДанныхРасшифровки);
КонецЕсли;
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина);
Если Ложь
Или ТипЗнч(КоллекцияВывода) = Тип("ТабличныйДокумент")
#Если Клиент Тогда
Или ТипЗнч(КоллекцияВывода) = Тип("ПолеТабличногоДокумента")
#КонецЕсли
Тогда
выхЭлементыРезультата = Новый Массив;
ЭлементыРасшифровки = Неопределено;
Если ДанныеРасшифровки <> Неопределено Тогда
ЭлементыРасшифровки = ДанныеРасшифровки.Элементы;
КонецЕсли;
ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(КоллекцияВывода, ПроцессорКомпоновкиДанных, ЭлементыРасшифровки, , , Автофиксация, выхЭлементыРезультата);
Иначе
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
КоллекцияВывода.Колонки.Очистить();
ПроцессорВывода.УстановитьОбъект(КоллекцияВывода);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных, Истина);
КонецЕсли;
Если АдресДанныхРасшифровки <> Неопределено Тогда
АдресДанныхРасшифровки = ПоместитьВоВременноеХранилище(ДанныеРасшифровки);
КонецЕсли;
Если МаркироватьНачалоИКонецВТехножурнале Тогда
мАнализТехножурнала.КончитьТрассу();
КонецЕсли;
Если ЛиОтладка Тогда
СообщитьСУчетомМодальностиЛкс("Формирование результата - " + Строка(мПлатформа.ПолучитьТекущееВремяВМиллисекундах() - НачалоВывода)
+ " мс", МодальныйРежим);
КонецЕсли;
Возврат Истина;
КонецФункции
// Получает линейную структуру наборов данных запросов компоновки. Работает и со схемой и с макетом.
// Содержит рекурсивный вызов.
//
// Параметры:
// НаборыДанных – НаборыДанныхСхемыКомпоновкиДанных, НаборыДанныхМакетаКомпоновкиДанных;
// *СтруктураНаборовДанных – Структура, *Неопределено - Структура("Имя", Структура("КоллекцияВладелец, НаборДанных"))
//
// Возвращаемое значение:
// Структура.
//
Функция ВсеНаборыДанныхЗапросовКомпоновкиЛкс(Знач НаборыДанных, СтруктураНаборовДанных = Неопределено) Экспорт
Если СтруктураНаборовДанных = Неопределено Тогда
СтруктураНаборовДанных = Новый Структура;
КонецЕсли;
Для каждого НаборДанных Из НаборыДанных Цикл
Если Ложь
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных")
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросСхемыКомпоновкиДанных")
Тогда
Если Не ЗначениеЗаполнено(НаборДанных.Имя) Тогда
// Платформа генерит такие наборы для служебных целей
ИмяНабора = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", "");
Иначе
ИмяНабора = НаборДанных.Имя;
КонецЕсли;
СтруктураНаборовДанных.Вставить(ИмяНабора, Новый Структура("КоллекцияВладелец, НаборДанных", НаборыДанных, НаборДанных));
ИначеЕсли Ложь
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеМакетаКомпоновкиДанных")
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеСхемыКомпоновкиДанных")
Тогда
ВсеНаборыДанныхЗапросовКомпоновкиЛкс(НаборДанных.Элементы, СтруктураНаборовДанных);
КонецЕсли;
КонецЦикла;
Возврат СтруктураНаборовДанных;
КонецФункции
// Выводит результат СКД с установкой вертикальной автофиксации.
// Параметры:
// Таб - ТабличныеДокумент, ПолеТабличногоДокумента - куда выводим отчет;
// ПроцессорКомпоновкиДанных - ПроцессорКомпоновкиДанных;
// ЭлементыРасшировки - ЭлементыРасшифровкиКомпоновкиДанных;
// МассивИгнорируемыхПолей - Массив, *Неопределено - массив имен игнорируемых полей;
// РазрешитьПрерывание - Булево, *Истина.
//
Процедура ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(Таб, ПроцессорКомпоновкиДанных, ЭлементыРасшировки = Неопределено,
Знач МассивИгнорируемыхПолей = Неопределено, РазрешитьПрерывание = Истина, Автофиксация = Истина, выхЭлементыРезультата = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
#КонецЕсли
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.ОтображатьПроцентВывода = Ложь;
ПроцессорВывода.УстановитьДокумент(Таб);
ПроцессорВывода.НачатьВывод();
ФиксацияВыполнена = Ложь;
Если МассивИгнорируемыхПолей = Неопределено Тогда
МассивИгнорируемыхПолей = Новый Массив;
КонецЕсли;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(100, "Компоновка",,, РазрешитьПрерывание);
Пока Истина Цикл
Если РазрешитьПрерывание Тогда
#Если Клиент Тогда
ОбработкаПрерыванияПользователя();
#КонецЕсли
КонецЕсли;
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
ЭлементРезультатаКомпоновкиДанных = ПроцессорКомпоновкиДанных.Следующий();
Если ЭлементРезультатаКомпоновкиДанных = Неопределено Тогда
Прервать;
КонецЕсли;
Если Индикатор.Счетчик <> ЭлементРезультатаКомпоновкиДанных.ПроцентВывода Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор, ЭлементРезультатаКомпоновкиДанных.ПроцентВывода);
КонецЕсли;
// Автофиксация
Если Истина
И Автофиксация
И Не ФиксацияВыполнена
И ЭлементыРасшировки <> Неопределено
Тогда
Для Каждого ЗначениеПараметра Из ЭлементРезультатаКомпоновкиДанных.ЗначенияПараметров Цикл
Если ТипЗнч(ЗначениеПараметра.Значение) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
ЗначенияПолейРасшифровки = ЭлементыРасшировки[ЗначениеПараметра.Значение].ПолучитьПоля();
Для Каждого ЗначениеПоляРасшифровки Из ЗначенияПолейРасшифровки Цикл
Если МассивИгнорируемыхПолей.Найти(ЗначениеПоляРасшифровки.Поле) = Неопределено Тогда
Таб.ФиксацияСверху = Таб.ВысотаТаблицы;
ФиксацияВыполнена = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ФиксацияВыполнена Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпоновкиДанных);
Если Истина
И выхЭлементыРезультата <> Неопределено
И выхЭлементыРезультата.Количество() < 10000
Тогда
выхЭлементыРезультата.Добавить(ЭлементРезультатаКомпоновкиДанных);
КонецЕсли;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
ЭлементРезультатаКомпоновкиДанных = ПроцессорКомпоновкиДанных.Следующий(); Если ЭлементРезультатаКомпоновкиДанных = Неопределено Тогда Прервать; КонецЕсли; Если Индикатор.Счетчик <> ЭлементРезультатаКомпоновкиДанных.ПроцентВывода Тогда ирОбщий.ОбработатьИндикаторЛкс(Индикатор, ЭлементРезультатаКомпоновкиДанных.ПроцентВывода); КонецЕсли; Если Истина И Автофиксация И Не ФиксацияВыполнена И ЭлементыРасшировки <> Неопределено Тогда Для Каждого ЗначениеПараметра Из ЭлементРезультатаКомпоновкиДанных.ЗначенияПараметров Цикл Если ТипЗнч(ЗначениеПараметра.Значение) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда ЗначенияПолейРасшифровки = ЭлементыРасшировки[ЗначениеПараметра.Значение].ПолучитьПоля(); Для Каждого ЗначениеПоляРасшифровки Из ЗначенияПолейРасшифровки Цикл Если МассивИгнорируемыхПолей.Найти(ЗначениеПоляРасшифровки.Поле) = Неопределено Тогда Таб.ФиксацияСверху = Таб.ВысотаТаблицы; ФиксацияВыполнена = Истина; Прервать; КонецЕсли; КонецЦикла; Если ФиксацияВыполнена Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпоновкиДанных); Если Истина И выхЭлементыРезультата <> Неопределено И выхЭлементыРезультата.Количество() < 10000 Тогда выхЭлементыРезультата.Добавить(ЭлементРезультатаКомпоновкиДанных); КонецЕсли;
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();
КонецПроцедуры // ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс
Функция ТабличноеПолеИлиТаблицаФормы_СколькоСтрокЛкс(ТабличноеПоле, Знач НастройкиСписка = Неопределено) Экспорт
ЗначениеЭУ = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
Если ЗначениеЭУ <> Неопределено Тогда
//ТипЗначенияТабличногоПоля = ТипЗнч(ИсточникДействий.Значение);
//ИмяОбщегоТипа = ПолучитьИмяОбщегоТипаИзКонкретногоТипа, ТипЗначенияТабличногоПоля);
Попытка
Количество = ЗначениеЭУ.Количество();
Попытка
Отбор = ТабличноеПоле.ОтборСтрок;
Исключение
КонецПопытки;
Если ТипЗнч(Отбор) = Тип("Отбор") И ОтборУстановленЛкс(Отбор) Тогда
#Если Клиент Тогда
Количество = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле,, Истина).Количество();
#КонецЕсли
КонецЕсли;
Исключение
Попытка
//Коллекция компоновки
Количество = ЗначениеЭУ.Элементы.Количество();
//Суффикс = "*";
Исключение
Попытка
//Или ИмяОбщегоТипа = "ДеревоЗначений"
Количество = ЗначениеЭУ.Строки.Количество();
Суффикс = "*";
Исключение
// ДинамическийСписок
ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле);
ИмяСлужебногоПоля = "СлужебноеПоле123213м34";
ТекстЗапроса = "ВЫБРАТЬ Т.*, 0 КАК " + ИмяСлужебногоПоля + " ИЗ " + ПолноеИмяТаблицы + " КАК Т";
СхемаКомпоновки = ирОбщий.СоздатьСхемуКомпоновкиПоЗапросу(ТекстЗапроса);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
Если НастройкиСписка = Неопределено Тогда
НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ЗначениеЭУ);
КонецЕсли;
ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, НастройкиСписка.Отбор);
//ирОбщий.СкопироватьПорядокЛюбойЛкс(НастройкаКомпоновки.Порядок, НастройкиСписка.Порядок);
ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ИмяСлужебногоПоля);
Запрос = ПолучитьЗапросИзКомпоновкиЛкс(СхемаКомпоновки, НастройкаКомпоновки,,,,, Ложь);
#Если Сервер И Не Сервер Тогда
Запрос = Новый Запрос;
#КонецЕсли
Запрос.Текст = СтрЗаменить(Запрос.Текст, "0 КАК " + ИмяСлужебногоПоля, "РАЗРЕШЕННЫЕ КОЛИЧЕСТВО(*) КАК КоличествоСтрок");
Количество = Запрос.Выполнить().Выгрузить()[0][0];
Отбор = НастройкиСписка.Отбор;
КонецПопытки;
КонецПопытки;
КонецПопытки;
КонецЕсли;
Текст = "Количество строк ";
Если Отбор <> Неопределено Тогда
Текст = Текст + "отобрано ";
КонецЕсли;
Текст = Текст + "- " + Формат(Количество, "ЧН=; ЧГ=") + Суффикс;
Если ТабличноеПоле.ВыделенныеСтроки.Количество() > 1 Тогда
Текст = Текст + ", выделено - " + Формат(ТабличноеПоле.ВыделенныеСтроки.Количество(), "ЧН=; ЧГ=");
КонецЕсли;
Если Отбор <> Неопределено Тогда
Текст = Текст + ". Отбор - """ + Отбор + """ ";
КонецЕсли;
СообщитьЛкс(Текст);
// Тексты подвала
Результат = Количество;
МассивПодвалов = Новый Массив;
#Если Клиент Тогда
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
Для Каждого КолонкаТП Из ТабличноеПоле.Колонки Цикл
ТекстПодвала = ПоследнийФрагментЛкс(КолонкаТП.ТекстПодвала, "Σ");
Если ЗначениеЗаполнено(ТекстПодвала) Тогда
МассивПодвалов.Добавить(КолонкаТП.ТекстШапки + " = " + ТекстПодвала);
КонецЕсли;
КонецЦикла;
КонецЕсли;
#КонецЕсли
Если МассивПодвалов.Количество() > 0 Тогда
СообщитьЛкс(СтрСоединитьЛкс(МассивПодвалов, "; "));
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле, выхПолноеИмяМД = "") Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
//выхПолноеИмяМД = ДинамическийСписок.ОсновнаяТаблица; // На клиенте недоступно
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле);
ПутьКДаннымСписка = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТабличноеПоле,, ЭтаФорма);
СлужебныеДанные = СлужебныеДанныеФормыЛкс(ЭтаФорма);
Если СлужебныеДанные <> Неопределено Тогда
ДинамическийСписок = СлужебныеДанные.ДинамическиеСписки[ПутьКДаннымСписка];
ПолноеИмяТаблицы = ДинамическийСписок.ОсновнаяТаблица;
Иначе
ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
Если Ложь
Или ТекущаяСтрока = Неопределено
Или ТипЗнч(ТекущаяСтрока) = Тип("Число") // Основная таблица не указана
Тогда
Возврат Неопределено;
КонецЕсли;
ПолноеИмяТаблицы = Метаданные.НайтиПоТипу(ТипЗнч(ТекущаяСтрока)).ПолноеИмя();
КонецЕсли;
Если Не ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда
ПолноеИмяТаблицы = СокрЛП(ирОбщий.СтрокаМеждуМаркерамиЛкс(ДинамическийСписок.ТекстЗапроса, "ИЗ ", " КАК _Т", Ложь));
КонецЕсли;
ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы);
Иначе
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение));
КонецЕсли;
Если ОбъектМД <> Неопределено Тогда
выхПолноеИмяМД = ОбъектМД.ПолноеИмя();
КонецЕсли;
Если ЗначениеЗаполнено(выхПолноеИмяМД) Тогда
ПолноеИмяТаблицы = ирКэш.ИмяТаблицыИзМетаданныхЛкс(выхПолноеИмяМД);
КонецЕсли;
Возврат ПолноеИмяТаблицы;
КонецФункции
Функция ЗапросДинамическогоСпискаЛкс(ТабличноеПоле) Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
//выхПолноеИмяМД = ДинамическийСписок.ОсновнаяТаблица; // На клиенте недоступно
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле);
ПутьКДаннымСписка = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТабличноеПоле,, ЭтаФорма);
ДинамическийСписок = ЭтаФорма.мСлужебныеДанные.ДинамическиеСписки[ПутьКДаннымСписка];
ПолноеИмяТаблицы = ДинамическийСписок.ОсновнаяТаблица;
Если ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда
Запрос = "ВЫБРАТЬ * ИЗ " + ПолноеИмяТаблицы;
Иначе
Запрос = ДинамическийСписок.Запрос;
КонецЕсли;
Иначе
выхПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение)).ПолноеИмя();
ПолноеИмяТаблицы = ирКэш.ИмяТаблицыИзМетаданныхЛкс(выхПолноеИмяМД);
Запрос = "ВЫБРАТЬ * ИЗ " + ПолноеИмяТаблицы;
КонецЕсли;
Возврат Запрос;
КонецФункции
// Формирует макет компоновки и извлекает из него запрос
// Параметры:
// Схема - СхемаКомпоновкиДанных
// НастройкаКомпоновкиДанных - НастройкиКомпоновкиДанных
// ДобавлятьУпорядочивание - Булево
// ПрефиксИменПараметров - Строка, *"" - используется для переименования параметров, полезно при смешивании нескольких запросов из компоновки в один
// выхСхемаКолонок - Структура, *Неопределено - если не равно Неопределено, то возвращается структура,
// где ключи - имена колонок, а значения - полные имена полей
//
// Результат - Запрос
//
Функция ПолучитьЗапросИзКомпоновкиЛкс(Знач Схема, Знач НастройкаКомпоновкиДанных, Знач ДобавлятьУпорядочивание = Ложь, ПрефиксИменПараметров = "",
ДобавитьВыбранноеПоле = "", выхСхемаКолонок = Неопределено, Автоупорядочивание = Истина, ПроверятьДоступностьПолей = Ложь, СПредставлениямиСсылок = Ложь) Экспорт
НастройкаКомпоновкиДанных = КопияОбъектаЛкс(НастройкаКомпоновкиДанных, Истина);
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновкиДанных = Новый НастройкиКомпоновкиДанных
#КонецЕсли
Если НастройкаКомпоновкиДанных.Структура.Количество() = 0 Тогда
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновкиДанных.Структура);
КонецЕсли;
Если ЗначениеЗаполнено(ДобавитьВыбранноеПоле) Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновкиДанных.Выбор, ДобавитьВыбранноеПоле);
КонецЕсли;
Если Не СПредставлениямиСсылок Тогда
Для Каждого ВыбранноеПоле Из НастройкаКомпоновкиДанных.Выбор.Элементы Цикл
Если ТипЗнч(ВыбранноеПоле) <> Тип("ВыбранноеПолеКомпоновкиДанных") Тогда
ВызватьИсключение "Неподдерживаемый тип выбранного поля - " + ТипЗнч(ВыбранноеПоле);
КонецЕсли;
Если ВыбранноеПоле.Использование Тогда
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(НастройкаКомпоновкиДанных.Структура[0].Отбор, "" + ВыбранноеПоле.Поле); // Отбор здесь используется не для фильтрации
КонецЕсли;
КонецЦикла;
НастройкаКомпоновкиДанных.Выбор.Элементы.Очистить();
КонецЕсли;
КопияПорядка = Новый Массив;
Для Каждого ЭлементПорядка Из НастройкаКомпоновкиДанных.Порядок.Элементы Цикл
Если ЭлементПорядка.Использование Тогда
КопияПорядка.Добавить(ЭлементПорядка);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновкиДанных.Выбор, ЭлементПорядка.Поле);
КонецЕсли;
КонецЦикла;
НастройкаКомпоновкиДанных.Порядок.Элементы.Очистить();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
// ирОбщий.ОтЛкс(Схема, НастройкаКомпоновкиДанных)
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, НастройкаКомпоновкиДанных, ,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"), ПроверятьДоступностьПолей);
СтрокаПорядка = ВыражениеПорядкаКомпоновкиНаЯзыкеЛкс(КопияПорядка,,,, МакетКомпоновки.НаборыДанных[0].Поля);
Запрос = Новый Запрос;
Если МакетКомпоновки.НаборыДанных.Количество() > 2 Тогда
СообщитьЛкс("В макете компоновки обнаружено более одного запроса");
КонецЕсли;
ТекстЗапроса = МакетКомпоновки.НаборыДанных[0].Запрос;
Если ДобавлятьУпорядочивание Тогда
Если ЗначениеЗаполнено(СтрокаПорядка) Тогда
ТекстЗапроса = ТекстЗапроса + "
|//Секция_Упорядочить. Этот комментарий используется в коде
|УПОРЯДОЧИТЬ ПО
| " + СтрокаПорядка;
КонецЕсли;
Если Ложь
Или Автоупорядочивание
//Или ЗначениеЗаполнено(СтрокаПорядка)
Тогда
ТекстЗапроса = ТекстЗапроса + "
|//Секция_Упорядочить. Этот комментарий используется в коде
|АВТОУПОРЯДОЧИВАНИЕ";
КонецЕсли;
КонецЕсли;
Запрос.Текст = ТекстЗапроса;
Для Каждого ЗначениеПараметра Из МакетКомпоновки.ЗначенияПараметров Цикл
Запрос.Параметры.Вставить(ЗначениеПараметра.Имя, ЗначениеПараметра.Значение);
КонецЦикла;
Если ПрефиксИменПараметров <> "" Тогда
ДобавитьПрефиксВсемПараметрамЗапросаЛкс(Запрос, ПрефиксИменПараметров);
КонецЕсли;
Если выхСхемаКолонок <> Неопределено Тогда
//выхСхемаКолонок = ПолучитьСхемуКолонокМакетаКомпоновкиДанныхЛкс(МакетКомпоновки);
//
НаборДанныхМакета = МакетКомпоновки.НаборыДанных[0];
Для Каждого ПолеНабора Из НаборДанныхМакета.Поля Цикл
выхСхемаКолонок.Вставить(ПолеНабора.Имя, ПолеНабора.ПутьКДанным);
КонецЦикла;
Для Каждого ВложенныйНаборДанных Из НаборДанныхМакета.ВложенныеНаборыДанных Цикл
выхСхемаКолонок.Вставить(ВложенныйНаборДанных.Имя, ВложенныйНаборДанных.ПутьКДанным);
КонецЦикла;
КонецЕсли;
Возврат Запрос;
КонецФункции
// Получает строку для установки порядка компоновки.
//
// Параметры:
// ПорядокКомпоновки – ПорядокКомпоновкиДанных, ЭлементыПорядкаКомпоновкиДанных
// ИсключаемоеПоле - Строка
// СимволЗаменыТочки - Строка
// ДиалектSQL - Строка
// ПутиКДаннымПолей - ПоляНабораДанныхЗапросаМакетаКомпоновкиДанных
//
// Возвращаемое значение:
// Строка - для установки порядка.
//
Функция ВыражениеПорядкаКомпоновкиНаЯзыкеЛкс(Знач ПорядокКомпоновки, ИсключаемоеПоле = "", СимволЗаменыТочки = Неопределено, ДиалектSQL = "1C", ПутиКДаннымПолей = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый НастройкиКомпоновкиДанных;
ПорядокКомпоновки = Пустышка.Порядок;
#КонецЕсли
Если ТипЗнч(ПорядокКомпоновки) = Тип("ПорядокКомпоновкиДанных") Тогда
ПорядокКомпоновки = ПорядокКомпоновки.Элементы;
КонецЕсли;
Строка = "";
Если СтрокиРавныЛкс(ДиалектSQL, "1С") Тогда
СтрокаВозр = "Возр";
СтрокаУбыв = "Убыв";
Иначе
СтрокаВозр = "Asc";
СтрокаУбыв = "Desc";
КонецЕсли;
Для Каждого ЭлементПорядка Из ПорядокКомпоновки Цикл
Если Ложь
Или Не ЭлементПорядка.Использование
Или ТипЗнч(ЭлементПорядка) = Тип("АвтоЭлементПорядкаКомпоновкиДанных")
Или ИсключаемоеПоле = "" + ЭлементПорядка.Поле
Тогда
Продолжить;
КонецЕсли;
ИмяПоля = "" + ЭлементПорядка.Поле;
Если ПутиКДаннымПолей <> Неопределено Тогда
ПутьКДаннымПоля = НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(ПутиКДаннымПолей, "ПутьКДанным", ИмяПоля);
Если ПутьКДаннымПоля = Неопределено Тогда
// Например реквизит ТЧ
Продолжить;
КонецЕсли;
ИмяПоля = ПутьКДаннымПоля.Имя;
КонецЕсли;
Если СимволЗаменыТочки <> Неопределено Тогда
ИмяПоля = СтрЗаменить(ИмяПоля, ".", СимволЗаменыТочки);
КонецЕсли;
Строка = Строка + ", " + ИмяПоля + " ";
Если ЭлементПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда
Строка = Строка + СтрокаВозр;
Иначе
Строка = Строка + СтрокаУбыв;
КонецЕсли;
КонецЦикла;
Возврат Сред(Строка, 3);
КонецФункции
// ТипНастроек - Число
Функция НастройкиДинамическогоСпискаЛкс(Знач ДинамическийСписок, ТипНастроек = "Результирующие") Экспорт
Если ТипЗнч(ДинамическийСписок) = Тип("ДинамическийСписок") Тогда
Если ТипНастроек = "Результирующие" Тогда
НастройкиСписка = ДинамическийСписок.КомпоновщикНастроек.ПолучитьНастройки();
ИначеЕсли ТипНастроек = "Фиксированные" Тогда
НастройкиСписка = ДинамическийСписок.КомпоновщикНастроек.ФиксированныеНастройки;
ИначеЕсли ТипНастроек = "Пользовательские" Тогда
ПользовательскиеНастройки = ДинамическийСписок.КомпоновщикНастроек.ПользовательскиеНастройки;
#Если Сервер И Не Сервер Тогда
ПользовательскиеНастройки = Новый ПользовательскиеНастройкиКомпоновкиДанных;
#КонецЕсли
НастройкиСписка = Новый Структура("Отбор, Порядок, УсловноеОформление");
Для Каждого ЭлементПользовательскихНастроек Из ПользовательскиеНастройки.Элементы Цикл
Если ТипЗнч(ЭлементПользовательскихНастроек) = Тип("ОтборКомпоновкиДанных") Тогда
НастройкиСписка.Отбор = ЭлементПользовательскихНастроек;
ИначеЕсли ТипЗнч(ЭлементПользовательскихНастроек) = Тип("ПорядокКомпоновкиДанных") Тогда
НастройкиСписка.Порядок = ЭлементПользовательскихНастроек;
ИначеЕсли ТипЗнч(ЭлементПользовательскихНастроек) = Тип("УсловноеОформлениеКомпоновкиДанных") Тогда
НастройкиСписка.УсловноеОформление = ЭлементПользовательскихНастроек;
КонецЕсли;
КонецЦикла;
Иначе
НастройкиСписка = ДинамическийСписок;
КонецЕсли;
Иначе
НастройкиСписка = ДинамическийСписок;
КонецЕсли;
Возврат НастройкиСписка;
КонецФункции
// Параметры:
// СписокПодсистем - СписокЗначений
// Результат - Соответствие - ключи - объекты метаданных входящие в заданные подсистемы
Функция ОбъектыПодсистемЛкс(СписокПодсистем, СтрокаДереваПодсистем = Неопределено, ОбъектыВыбранныхПодсистем = Неопределено) Экспорт
Если ОбъектыВыбранныхПодсистем = Неопределено Тогда
ОбъектыВыбранныхПодсистем = Новый Соответствие;
КонецЕсли;
ПодсистемаПеревод = ПеревестиСтроку("Подсистема");
Для Каждого ЭлементСписка Из СписокПодсистем Цикл
//ПодсистемаМД = ирКэш.ОбъектМДПоПолномуИмениЛкс("Подсистема." + СтрЗаменить(ЭлементСписка.Значение, ".", ".Подсистема."));
ПодсистемаМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПодсистемаПеревод + "." + СтрЗаменить(ЭлементСписка.Значение, ".", "." + ПодсистемаПеревод + "."));
Для Каждого ЭлементСостава Из ПодсистемаМД.Состав Цикл
ОбъектыВыбранныхПодсистем.Вставить(ЭлементСостава, 1);
КонецЦикла;
КонецЦикла;
Возврат ОбъектыВыбранныхПодсистем;
КонецФункции
Функция НоваяТаблицаНастроекСтандартногоХранилищаЛкс() Экспорт
ТабОписаний = Новый ТаблицаЗначений;
ТабОписаний.Колонки.Добавить("ИмяХранилища");
ТабОписаний.Колонки.Добавить("ИмяОбъекта");
ТабОписаний.Колонки.Добавить("КлючНастроек");
ТабОписаний.Колонки.Добавить("Настройка");
ТабОписаний.Колонки.Добавить("ИмяПользователя");
ТабОписаний.Колонки.Добавить("Описание");
Возврат ТабОписаний;
КонецФункции
Функция ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(мдОбъекта, ВключаяПоследовательности = Ложь, ВключаяПерерасчеты = Ложь) Экспорт
ОбъектыМД = Новый Массив();
Для Каждого МетаРегистр из мдОбъекта.Движения Цикл
ОбъектыМД.Добавить(МетаРегистр);
Если ВключаяПерерасчеты Тогда
Если ЛиКорневойТипРегистраРасчетаЛкс(ПервыйФрагментЛкс(МетаРегистр.ПолноеИмя())) Тогда
Для Каждого ПерерасчетМД Из МетаРегистр.Перерасчеты Цикл
ОбъектыМД.Добавить(ПерерасчетМД);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ВключаяПоследовательности Тогда
Для Каждого МетаПоследовательность Из Метаданные.Последовательности Цикл
Если МетаПоследовательность.Документы.Содержит(мдОбъекта) Тогда
ОбъектыМД.Добавить(МетаПоследовательность);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ОбъектыМД;
КонецФункции
// Функция считывает в табличный документ данные из текстового файла
//
// Параметры:
// ТабличныйДокумент - ТабличныйДокумент, в который необходимо прочитать данные
// ИмяФайла - имя текстового файла, из которого необходимо прочитать данные
//
// Возвращаемое значение:
// Истина, если файл прочитан, Ложь - иначе
//
Функция ПрочитатьТабличныйДокументИзТекстаЛкс(ТабличныйДокумент, ИмяФайла, Разделитель = ",", ОбрезатьНепечатныеСимволы = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
ВыбФайл = Новый Файл(ИмяФайла);
Если НЕ ВыбФайл.Существует() Тогда
СообщитьЛкс("Файл не существует!");
Возврат Ложь;
КонецЕсли;
ТекстовыйДокумент = Новый ТекстовыйДокумент;
Попытка
ТекстовыйДокумент.Прочитать(ИмяФайла);
Исключение
СообщитьЛкс("Ошибка открытия файла!");
Возврат Ложь;
КонецПопытки;
ТабличныйДокумент.Очистить();
Текст = ТекстовыйДокумент.ПолучитьТекст();
#Если Клиент Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаРазбивки = мПлатформа.ПолучитьФорму("РазбивкаТекста");
ФормаРазбивки.Приемник = ТабличныйДокумент;
ФормаРазбивки.Текст = Текст;
Если ФормаРазбивки.ОткрытьМодально() = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
#Иначе
ирОбщий.ПолучитьТаблицуИзСтрокиСРазделителемЛкс(Текст, Разделитель, ОбрезатьНепечатныеСимволы, ТабличныйДокумент);
#КонецЕсли
Возврат Истина;
КонецФункции // ()
// Функция считывает в табличный документ данные из файла в формате dBase III (*.dbf)
//
// Параметры:
// ТабличныйДокумент - ТабличныйДокумент, в который необходимо прочитать данные
// ИмяФайла - имя файла в формате TXT, из которого необходимо прочитать данные
//
// Возвращаемое значение:
// Истина, если файл прочитан, Ложь - иначе
//
Функция ПрочитатьТабличныйДокументИзDBFЛкс(ТабличныйДокумент, ИмяФайла) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
ВыбФайл = Новый Файл(ИмяФайла);
Если НЕ ВыбФайл.Существует() Тогда
СообщитьЛкс("Файл не существует!");
Возврат Ложь;
КонецЕсли;
XBase = Новый XBase;
XBase.Кодировка = КодировкаXBase.OEM;
Попытка
XBase.ОткрытьФайл(ИмяФайла);
Исключение
СообщитьЛкс("Ошибка открытия файла!");
Возврат Ложь;
КонецПопытки;
ТабличныйДокумент.Очистить();
ТекущаяСтрока = 1;
ТекущаяКолонка = 0;
Для каждого Поле Из XBase.поля Цикл
ТекущаяКолонка = ТекущаяКолонка + 1;
ТабличныйДокумент.Область("R" + Формат(ТекущаяСтрока, "ЧГ=") +"C" + Формат(ТекущаяКолонка, "ЧГ=")).Текст = Поле.Имя;
КонецЦикла;
Рез = XBase.Первая();
Пока Не XBase.ВКонце() Цикл
ТекущаяСтрока = ТекущаяСтрока + 1;
ТекущаяКолонка = 0;
Для каждого Поле Из XBase.поля Цикл
ТекущаяКолонка = ТекущаяКолонка + 1;
Если Поле.Тип = "M" Тогда
Продолжить;
КонецЕсли;
ТабличныйДокумент.Область("R" + Формат(ТекущаяСтрока, "ЧГ=") +"C" + Формат(ТекущаяКолонка, "ЧГ=")).Текст = XBase.ПолучитьЗначениеПоля(ТекущаяКолонка - 1);
КонецЦикла;
XBase.Следующая();
КонецЦикла;
Возврат Истина;
КонецФункции // ()
// Параметры:
// ТаблицаПриемник - ТабличныйДокумент, ТаблицаЗначений, *Неопределено
//
Функция ПолучитьТаблицуИзСтрокиСРазделителемЛкс(Знач Текст, Разделитель = ".", ОбрезатьНепечатныеСимволы = Ложь, Знач ИменаКолонокИзПервойСтроки = Ложь, Знач ТаблицаПриемник = Неопределено) Экспорт
Если ТаблицаПриемник = Неопределено Тогда
ТаблицаПриемник = Новый ТаблицаЗначений;
КонецЕсли;
КоличествоКолонок = 0;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(Текст);
КоличествоСтрок = ТекстовыйДокумент.КоличествоСтрок();
Индикатор = ПолучитьИндикаторПроцессаЛкс(КоличествоСтрок, "Разбивка текста");
Для СчетчикСтроки = 1 По КоличествоСтрок Цикл
ОбработатьИндикаторЛкс(Индикатор);
СтрокаТекста = ТекстовыйДокумент.ПолучитьСтроку(СчетчикСтроки);
Массив = СтрРазделитьЛкс(СтрокаТекста, Разделитель, ОбрезатьНепечатныеСимволы, Истина);
Если КоличествоКолонок < Массив.Количество() Тогда
Если ТипЗнч(ТаблицаПриемник) = Тип("ТаблицаЗначений") Тогда
Для ИндексКолонки = КоличествоКолонок По Массив.Количество() - 1 Цикл
Если ИменаКолонокИзПервойСтроки И СчетчикСтроки = 1 Тогда
ИмяКолонки = мПлатформа.ИдентификаторИзПредставленияЛкс(Массив[ИндексКолонки]);
ЗаголовокКолонки = ИмяКолонки;
Иначе
ИмяКолонки = "Колонка" + XMLСтрока(ИндексКолонки);
ЗаголовокКолонки = "";
КонецЕсли;
ТаблицаПриемник.Колонки.Добавить(ИмяКолонки,, ЗаголовокКолонки);
КонецЦикла;
КонецЕсли;
КоличествоКолонок = Массив.Количество();
//ИначеЕсли КоличествоКолонок > Массив.Количество() Тогда
// СообщитьЛкс("В строке текст №" + XMLСтрока(СчетчикСтроки) + " указаны значения не для всех колонок");
КонецЕсли;
Если ТипЗнч(ТаблицаПриемник) = Тип("ТаблицаЗначений") Тогда
Если ИменаКолонокИзПервойСтроки И СчетчикСтроки = 1 Тогда
Продолжить;
КонецЕсли;
СтрокаТаблицы = ТаблицаПриемник.Добавить();
Для ИндексКолонки = 0 По Массив.ВГраница() Цикл
СтрокаТаблицы[ИндексКолонки] = Массив[ИндексКолонки];
КонецЦикла;
Иначе //Если ТипЗнч(ТаблицаПриемник) = Тип("ТабличныйДокумент") Тогда
#Если Сервер И Не Сервер Тогда
ТаблицаПриемник = Новый ТабличныйДокумент;
#КонецЕсли
АдресЯчейки = "R" + Формат(СчетчикСтроки, "ЧГ=") + "C";
Для ИндексКолонки = 0 По Массив.ВГраница() Цикл
ТаблицаПриемник.Область(АдресЯчейки + Формат(ИндексКолонки + 1, "ЧГ=")).Текст = Массив[ИндексКолонки];
КонецЦикла;
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
Возврат ТаблицаПриемник;
КонецФункции // СтрРазделитьЛкс()
Функция ОбщийТипДанныхТабличногоПоляЛкс(Знач ТабличноеПоле, ПреобразоватьТипДанныхФормы = Ложь, выхСтруктураТипаМетаданных = Неопределено, выхПолноеИмяТаблицыБД = "",
выхДанныеТабличногоПоля = Неопределено) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
выхДанныеТабличногоПоля = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
Если ПреобразоватьТипДанныхФормы Тогда
ТипЗначенияТабличногоПоля = ирОбщий.ПолучитьТипЗначенияЭлементаФормыЛкс(ТабличноеПоле).Типы()[0];
Иначе
ТипЗначенияТабличногоПоля = ТипЗнч(выхДанныеТабличногоПоля);
КонецЕсли;
Если ТипЗначенияТабличногоПоля = Тип("ТаблицаЗначений") Тогда
ТипИсточника = "ТаблицаЗначений";
ИначеЕсли ТипЗначенияТабличногоПоля = Тип("ДеревоЗначений") Тогда
ТипИсточника = "ДеревоЗначений";
ИначеЕсли ЛиДанныеФормыСВозможностьюПоискаЛкс(ТипЗначенияТабличногоПоля) Тогда
ТипИсточника = "ТаблицаЗначений";
ИначеЕсли ТипЗначенияТабличногоПоля = Тип("ДанныеФормыДерево") Тогда
ТипИсточника = "ДеревоЗначений";
Иначе
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
СтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзКонкретногоТипа(ТипЗначенияТабличногоПоля);
Если Ложь
Или Найти(СтруктураТипа.ИмяОбщегоТипа, "<Имя табличной части>") > 0
Или Найти(СтруктураТипа.ИмяОбщегоТипа, "ВидыСубконто") > 0
Или Найти(СтруктураТипа.ИмяОбщегоТипа, "БазовыеВидыРасчета") > 0
Или Найти(СтруктураТипа.ИмяОбщегоТипа, "ВедущиеВидыРасчета") > 0
Или Найти(СтруктураТипа.ИмяОбщегоТипа, "ВытесняющиеВидыРасчета") > 0
Тогда
ТипИсточника = "ТабличнаяЧасть";
ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "НаборЗаписей.") > 0 Тогда
ТипИсточника = "НаборЗаписей";
ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "Список.") > 0 Тогда
ТипИсточника = "Список";
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ДинамическийСписок" Тогда
ТипИсточника = "Список";
КонецЕсли;
Если СтруктураТипа.ИмяОбщегоТипа <> "Неопределено" Тогда
выхСтруктураТипаМетаданных = СтруктураТипа;
КонецЕсли;
выхПолноеИмяТаблицыБД = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле);
Если Истина
И Не ЗначениеЗаполнено(ТипИсточника)
И ЗначениеЗаполнено(выхПолноеИмяТаблицыБД)
Тогда
ТипИсточника = "Список";
КонецЕсли;
КонецЕсли;
Возврат ТипИсточника;
КонецФункции // ИнтерактивноУстановитьЗначениеВКолонкеТабличногоПоляТЧИлиТЗ()
Функция ЛиДанныеФормыСВозможностьюПоискаЛкс(Знач ДанныеИлиТипТаблицы) Экспорт
Если ТипЗнч(ДанныеИлиТипТаблицы) <> Тип("Тип") Тогда
Тип = ТипЗнч(ДанныеИлиТипТаблицы);
Иначе
Тип = ДанныеИлиТипТаблицы;
КонецЕсли;
Возврат Ложь
Или Тип = Тип("ДанныеФормыКоллекция")
Или Тип = Тип("ДанныеФормыСтруктураСКоллекцией");
КонецФункции
// Параметры:
// ЭтаФорма - Форма
// ТабличноеПоле - ТабличноеПоле
// КлючевоеПоле - Строка
// ЗначениеКлюча -
// СообщатьОбУспехе - Булево
//
Функция УстановитьТекущуюСтрокуСКонтролемУспешностиЛкс(Знач ЭтаФорма, Знач ТабличноеПоле, Знач КлючевоеПоле = "Ссылка", Знач ЗначениеКлюча = Неопределено, Знач СообщатьОбУспехе = Ложь,
АктивизироватьТабличноеПолеПриУспехе = Ложь) Экспорт
ПолноеИмяТаблицыБД = "";
ДанныеТабличногоПоля = Неопределено;
ТипИсточника = ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле,,, ПолноеИмяТаблицыБД, ДанныеТабличногоПоля);
Если Ложь
Или ТипИсточника = "ТаблицаЗначений"
Или ТипИсточника = "ТабличнаяЧасть"
Или ТипИсточника = "НаборЗаписей"
Тогда
ДанныеТабличногоПоля = ирОбщий.ДанныеЭлементаФормыЛкс(ТабличноеПоле);
#Если Сервер И Не Сервер Тогда
ДанныеТабличногоПоля = Новый ТаблицаЗначений;
#КонецЕсли
Если КлючевоеПоле <> Неопределено Тогда
НайденныеСтроки = ДанныеТабличногоПоля.НайтиСтроки(Новый Структура(КлючевоеПоле, ЗначениеКлюча));
Иначе
НайденныеСтроки = ДанныеТабличногоПоля;
КонецЕсли;
Если НайденныеСтроки.Количество() > 0 Тогда
НайденнаяСтрока = НайденныеСтроки[0];
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
НайденнаяСтрока = НайденнаяСтрока.ПолучитьИдентификатор();
КонецЕсли;
КонецЕсли;
ЭтоКлиентскийИсточникДанных = Истина;
ИначеЕсли ТипИсточника = "ДеревоЗначений" Тогда
НайденнаяСтрока = ТабличноеПоле.Значение.Строки.Найти(ЗначениеКлюча, КлючевоеПоле, Истина);
ЭтоКлиентскийИсточникДанных = Истина;
Иначе
НайденнаяСтрока = ЗначениеКлюча;
Если ДанныеТабличногоПоля <> Неопределено Тогда
Отбор = ДанныеТабличногоПоля.Отбор;
ЭтоКлиентскийИсточникДанных = Ложь;
ПостроительЗапроса = Новый ПостроительЗапроса;
ПостроительЗапроса.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ " + ПолноеИмяТаблицыБД;
ПостроительЗапроса.ЗаполнитьНастройки();
СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицыБД,,, Ложь);
ЗаполнитьЗначенияСвойств(СтруктураКлюча, ЗначениеКлюча);
УстановитьОтборПоСтруктуреЛкс(ПостроительЗапроса.Отбор, СтруктураКлюча);
СтрокаЕстьВИсточникеДанных = Не ПостроительЗапроса.Результат.Пустой();
Иначе
СтрокаЕстьВИсточникеДанных = Истина; // Немного криво
КонецЕсли;
КонецЕсли;
Если ЭтоКлиентскийИсточникДанных Тогда
СтрокаЕстьВИсточникеДанных = НайденнаяСтрока <> Неопределено;
КонецЕсли;
Если СтрокаЕстьВИсточникеДанных Тогда
ТабличноеПоле.ТекущаяСтрока = НайденнаяСтрока;
Иначе
СообщитьЛкс("Строка не найдена в источнике данных");
КонецЕсли;
Если ТабличноеПоле.ТекущаяСтрока = НайденнаяСтрока Тогда
Если АктивизироватьТабличноеПолеПриУспехе Тогда
ЭтаФорма.ТекущийЭлемент = ТабличноеПоле;
КонецЕсли;
Результат = Истина;
Иначе
Если СтрокаЕстьВИсточникеДанных Тогда
ТекстСообщения = "Строка найдена в источнике данных, но не найдена в табличном поле";
Если Отбор <> Неопределено Тогда
ТекстСообщения = ТекстСообщения + " с учетом отбора " + Отбор;
КонецЕсли;
СообщитьЛкс(ТекстСообщения, СтатусСообщения.Внимание);
КонецЕсли;
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры
// МетаданныеКолонок - КоллекцияОбъектовМетаданных, ТаблицаЗначений - для таблицы значений используются колонки Имя и Метаданные
Процедура НастроитьДобавленныеКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, ОписанияТиповКолонок = Неопределено, МетаданныеКолонок = Неопределено, ДоступныеПоляВыбора = Неопределено,
ТолькоПросмотр = Ложь) Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
Если ОписанияТиповКолонок = Неопределено Тогда
ОписанияТиповКолонок = ирСервер.ПолучитьТаблицуДочернихРеквизитовЛкс(ТабличноеПоле);
КонецЕсли;
Иначе
#Если Клиент Тогда
ТабличноеПолеВключитьСтаруюЦветовуюСхемуЛкс(ТабличноеПоле);
#КонецЕсли
Если ОписанияТиповКолонок = Неопределено Тогда
ОписанияТиповКолонок = ТабличноеПоле.Значение.Колонки;
КонецЕсли;
КонецЕсли;
Для Каждого КолонкаТаблицы Из ОписанияТиповКолонок Цикл
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
КолонкаТабличногоПоля = ТабличноеПоле.ПодчиненныеЭлементы.Найти(ТабличноеПоле.Имя + КолонкаТаблицы.Имя);
Иначе
КолонкаТабличногоПоля = ТабличноеПоле.Колонки.Найти(КолонкаТаблицы.Имя);
КонецЕсли;
Если КолонкаТабличногоПоля = Неопределено Тогда
Продолжить;
КонецЕсли;
Если КолонкаТабличногоПоля.Видимость Тогда
УстановитьТекущуюКолонкуТаблицыФормыЛкс(ТабличноеПоле, КолонкаТабличногоПоля, Истина);
КонецЕсли;
Если ТолькоПросмотр Тогда
КолонкаТабличногоПоля.ТолькоПросмотр = Истина;
КонецЕсли;
Если Ложь
#Если Клиент Тогда
Или ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле")
#КонецЕсли
Тогда
ТипыРеквизита = КолонкаТаблицы.ТипЗначения.Типы();
Если ТипыРеквизита.Количество() = 1 И ТипыРеквизита[0] = Тип("Булево") Тогда
//КолонкаТабличногоПоля.Данные = "";
//КолонкаТабличногоПоля.ДанныеФлажка = КолонкаТаблицы.Имя;
//КолонкаТабличногоПоля.РежимРедактирования = РежимРедактированияКолонки.Непосредственно;
КолонкаТабличногоПоля.Ширина = 4;
Иначе
Если КолонкаТаблицы.Ширина > 0 Тогда
КолонкаТабличногоПоля.Ширина = Мин(КолонкаТаблицы.Ширина, 50); // Почему то в редакторе таблицы значений не работала автоширина (-1)
КонецЕсли;
Если КолонкаТабличногоПоля.Ширина = 0 Тогда
КолонкаТабличногоПоля.Ширина = 4; // Для 8.2 необходимо, иначе колонки будут не видны
КонецЕсли;
КонецЕсли;
Если МетаданныеКолонок <> Неопределено Тогда
Если ТипЗнч(МетаданныеКолонок) = Тип("КоллекцияОбъектовМетаданных") Тогда
Метареквизит = МетаданныеКолонок.Найти(КолонкаТаблицы.Имя);
Иначе
СтрокаПоля = МетаданныеКолонок.Найти(КолонкаТаблицы.Имя, "Имя");
Если СтрокаПоля <> Неопределено Тогда
Метареквизит = СтрокаПоля.Метаданные;
Иначе
Метареквизит = Неопределено;
КонецЕсли;
КонецЕсли;
Если Метареквизит <> Неопределено Тогда
Попытка
Подсказка = Метареквизит.Подсказка;
Исключение
// У графы журнала нет подсказки
Подсказка = Неопределено;
КонецПопытки;
Если Подсказка <> Неопределено Тогда
КолонкаТабличногоПоля.ПодсказкаВШапке = Подсказка;
Если Метареквизит.МногострочныйРежим Тогда
КолонкаТабличногоПоля.ЭлементУправления.МногострочныйРежим = Метареквизит.МногострочныйРежим;
КолонкаТабличногоПоля.ЭлементУправления.РасширенноеРедактирование = Метареквизит.РасширенноеРедактирование;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ДоступныеПоляВыбора <> Неопределено Тогда
ДоступноеПоле = ДоступныеПоляВыбора.НайтиПоле(Новый ПолеКомпоновкиДанных(КолонкаТаблицы.Имя));
Если ДоступноеПоле <> Неопределено Тогда
ТекстШапки = ДоступноеПоле.Заголовок;
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
КолонкаТабличногоПоля.Заголовок = ТекстШапки;
Иначе
КолонкаТабличногоПоля.ТекстШапки = ТекстШапки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура УстановитьТекущуюКолонкуТаблицыФормыЛкс(Знач ТабличноеПоле, Знач Колонка, Знач ТолькоЕслиНеопределена = Ложь) Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
Если Не ТолькоЕслиНеопределена Или ТабличноеПоле.ТекущийЭлемент = Неопределено Тогда
ТабличноеПоле.ТекущийЭлемент = Колонка;
КонецЕсли;
Иначе
Если Не ТолькоЕслиНеопределена Или ТабличноеПоле.ТекущаяКолонка = Неопределено Тогда
ТабличноеПоле.ТекущаяКолонка = Колонка;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс() Экспорт
МассивСостояний = Новый Массив;
МассивСостояний.Добавить("Не отображать");
МассивСостояний.Добавить("Отображать пустые");
МассивСостояний.Добавить("Отображать пустые и идентификаторы");
Возврат МассивСостояний;
КонецФункции
Функция КлючХраненияНастроекФормыЛкс(Знач ЭтаФорма) Экспорт
Результат = ирОбщий.ИмяФормыИзФормыЛкс(ЭтаФорма);
// Сделать потом новый режим формирования ключа хранения и флажок в общих настройках чтобы пользователь сам его включал для использования нового ключа.
//Фрагменты = СтрРазделитьЛкс(Результат);
//Фрагменты.Удалить(2);
//Фрагменты.Удалить(0);
//Результат = СтрСоединитьЛкс(Фрагменты);
Возврат Результат;
КонецФункции
Функция КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма, ТабличноеПоле = Неопределено) Экспорт
Если ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма") Тогда
КлючУникальности = ЭтаФорма.мКлючУникальности;
Иначе
КлючУникальности = ЭтаФорма.КлючУникальности;
КонецЕсли;
Результат = КлючХраненияНастроекФормыЛкс(ЭтаФорма) + ".";
Если Не ЭтаФорма.РежимВыбора Тогда
Если ТабличноеПоле <> Неопределено Тогда
Результат = Результат + ТабличноеПоле.Имя + ".";
Иначе
ирОбщий.СообщитьЛкс("При формировании ключа списка последних выбранных значений нужно указывать табличное поле");
КонецЕсли;
КонецЕсли;
Результат = Результат + Лев(КлючУникальности, 50) + ".ПоследниеВыбранные";
Возврат Результат;
КонецФункции
// Параметры:
// ЭтаФорма - Форма
// КнопкаПодменю - Кнопка - подменю, в которое будут добавлены кнопки
//
Процедура ПоследниеВыбранныеЗаполнитьПодменюЛкс(Знач ЭтаФорма, КнопкаПодменю, Знач ТабличноеПоле = Неопределено, Знач ОбработчикКнопки = Неопределено) Экспорт
КлючЗначения = КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма, ТабличноеПоле);
ПоследниеВыбранные = ВосстановитьЗначениеЛкс(КлючЗначения);
Если ТипЗнч(КнопкаПодменю) = Тип("ГруппаФормы") Тогда
ОчиститьПодчиненныеЭлементыФормыЛкс(КнопкаПодменю, 0);
Иначе
КнопкаПодменю.Кнопки.Очистить();
КонецЕсли;
Если ТипЗнч(ПоследниеВыбранные) <> Тип("СписокЗначений") Тогда
Возврат;
КонецЕсли;
ЗапоминатьПоследниеВыбранные = КоличествоЗапоминаемыхПоследнихВыбранныхЛкс();
Для Счетчик = ЗапоминатьПоследниеВыбранные По ПоследниеВыбранные.Количество() - 1 Цикл
ПоследниеВыбранные.Удалить(ЗапоминатьПоследниеВыбранные);
КонецЦикла;
ПодсказкаКнопки = "Активировать выбранный элемент в списке";
Для каждого ЭлементСписка Из ПоследниеВыбранные Цикл
ИмяКнопки = НачалоИмениКнопкиПодменюПоследнихВыбранных() + ПоследниеВыбранные.Индекс(ЭлементСписка);
Если ТипЗнч(КнопкаПодменю) = Тип("ГруппаФормы") Тогда
Кнопка = ЭтаФорма.Элементы.Добавить(КнопкаПодменю.Имя + ИмяКнопки, Тип("КнопкаФормы"), КнопкаПодменю);
//Кнопка.Отображение = ОтображениеКнопкиКоманднойПанели.Авто;
Кнопка.Заголовок = ЭлементСписка.Представление;
Попытка
Кнопка.ИмяКоманды = ИмяКнопки;
Исключение
Прервать;
КонецПопытки;
Иначе
#Если Клиент Тогда
Кнопка = КнопкаПодменю.Кнопки.Добавить();
Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
Кнопка.Имя = ИмяКнопки;
//Кнопка.Отображение = ОтображениеКнопкиКоманднойПанели.Авто;
Кнопка.Текст = ЭлементСписка.Представление;
Кнопка.Подсказка = ПодсказкаКнопки;
Кнопка.Пояснение = Кнопка.Подсказка;
Если ОбработчикКнопки = Неопределено Тогда
ОбработчикКнопки = Новый Действие("ПоследниеВыбранныеНажатие");
КонецЕсли;
Попытка
Кнопка.Действие = ОбработчикКнопки;
Исключение
Прервать;
КонецПопытки;
#КонецЕсли
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция КоличествоЗапоминаемыхПоследнихВыбранныхЛкс()
Возврат 10;
КонецФункции
Функция НачалоИмениКнопкиПодменюПоследнихВыбранных()
Возврат "ПоследниеВыбранные";
КонецФункции
Функция ПолучитьИспользованиеДинамическогоСпискаВместоОсновнойФормыЛкс(ПолноеИмяМД) Экспорт
Возврат ирОбщий.ВосстановитьЗначениеЛкс("ирДинамическийСписок.ВместоОсновной." + ПолноеИмяМД) <> Ложь;
КонецФункции // УстановитьОбъектМетаданных()
Функция КлючИсторииВыбораПоляВводаЛкс(Знач ПолеВвода, Знач КлючИстории, Знач ДополнительныйКлючИстории)
Если ТипЗнч(КлючИстории) <> Тип("Строка") Тогда
КлючИстории = КлючХраненияНастроекФормыЛкс(КлючИстории);
КлючИстории = КлючИстории + ДополнительныйКлючИстории;
КлючИстории = КлючИстории + "." + ПолеВвода.Имя;
КонецЕсли;
КлючИстории = КлючИстории + ".ПоследниеЗначения";
Возврат КлючИстории;
КонецФункции
// Процедура - Поле ввода с историей выбора при изменении
//
// Параметры:
// ПолеВвода - -
// КлючИстории - Строка, Форма -
// ЗапоминатьПоследние - -
// НеЗапоминатьПустыеТипизированные - -
// ДополнительныйКлючИстории - Строка - используется только если КлючИстории не ялвяется строкой
//
Процедура ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(ПолеВвода, Знач КлючИстории, Знач ЗапоминатьПоследние = 20, Знач НеЗапоминатьПустыеТипизированные = Истина, ДополнительныйКлючИстории = "",
Знач ЗначениеПоля = Неопределено) Экспорт
Если ЗначениеПоля = Неопределено Тогда
ЗначениеПоля = ДанныеЭлементаФормыЛкс(ПолеВвода);
КонецЕсли;
Если Ложь
Или (Истина
И Не НеЗапоминатьПустыеТипизированные
И ЗначениеПоля <> ПолеВвода.ТипЗначения.ПривестиЗначение(Неопределено))
Или ЗначениеЗаполнено(ЗначениеПоля)
Тогда
НовоеЗначениеXML = СохранитьОбъектВВидеСтрокиXMLЛкс(ЗначениеПоля);
Если СтрДлина(НовоеЗначениеXML) > 1000 Тогда
Возврат;
КонецЕсли;
КлючИстории = КлючИсторииВыбораПоляВводаЛкс(ПолеВвода, КлючИстории, ДополнительныйКлючИстории);
ПоследниеЗначения = ВосстановитьЗначениеЛкс(КлючИстории);
Если ТипЗнч(ПоследниеЗначения) <> Тип("Массив") Тогда
ПоследниеЗначения = Новый Массив;
КонецЕсли;
ПоследниеЗначенияXML = Новый Массив;
Для Каждого Значение Из ПоследниеЗначения Цикл
ПоследниеЗначенияXML.Добавить(СохранитьОбъектВВидеСтрокиXMLЛкс(Значение));
КонецЦикла;
Индекс = ПоследниеЗначенияXML.Найти(НовоеЗначениеXML);
Если Индекс <> Неопределено Тогда
ПоследниеЗначения.Удалить(Индекс);
КонецЕсли;
ПоследниеЗначения.Вставить(0, ЗначениеПоля);
Для Счетчик = ЗапоминатьПоследние По ПоследниеЗначения.ВГраница() Цикл
ПоследниеЗначения.Удалить(ЗапоминатьПоследние);
КонецЦикла;
СохранитьЗначениеЛкс(КлючИстории, ПоследниеЗначения);
ПолеВвода.СписокВыбора.Очистить();
Для Каждого Значение Из ПоследниеЗначения Цикл
НовыйЭлемент = ПолеВвода.СписокВыбора.Добавить(Значение);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ПолеВводаСИсториейВыбора_НачалоВыбораИзСпискаЛкс(ПолеВвода, Знач КлючИстории, ДополнительныйКлючИстории = "") Экспорт
// Запоминать последние
КлючИстории = КлючИсторииВыбораПоляВводаЛкс(ПолеВвода, КлючИстории, ДополнительныйКлючИстории);
ПоследниеЗначения = ВосстановитьЗначениеЛкс(КлючИстории);
ПолеВвода.СписокВыбора.Очистить();
Если ТипЗнч(ПоследниеЗначения) = Тип("Массив") Тогда
Для Каждого Значение Из ПоследниеЗначения Цикл
ПолеВвода.СписокВыбора.Добавить(Значение);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьИндексКартинкиСловаПодсказкиЛкс(ДанныеСтроки) Экспорт
Попытка
ТипЗначения = ДанныеСтроки.ТипЗначения;
Исключение
ТипЗначения = Неопределено;
КонецПопытки;
ИндексКартинки = -1;
Если Ложь
Или ДанныеСтроки.ТипСлова = "Ключевое слово"
Или ДанныеСтроки.ТипСлова = "Конструкция"
Тогда
ИндексКартинки = 13;
ИначеЕсли ТипЗначения = "Имя типа" Тогда
ИндексКартинки = 12;
ИначеЕсли ДанныеСтроки.ТипСлова = "Метод" Тогда
Попытка
Пустышка = ДанныеСтроки.Успех;
ЕстьУспех = Истина;
Исключение
ЕстьУспех = Ложь;
КонецПопытки;
Если Ложь
Или (Истина
И ЕстьУспех
И (Ложь
Или ДанныеСтроки.ТаблицаСтруктурТипов = Неопределено
Или ДанныеСтроки.ТаблицаСтруктурТипов.Количество() = 0
Или ДанныеСтроки.ТаблицаСтруктурТипов[0].ИмяОбщегоТипа = ""))
Или (Истина
И Не ЕстьУспех
И ДанныеСтроки.ТипЗначения = "")
Тогда
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 0;
ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда
ИндексКартинки = 6;
//ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда
// ИндексКартинки = 9;
Иначе
ИндексКартинки = 3;
КонецЕсли;
Иначе
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 1;
ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда
ИндексКартинки = 7;
//ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда
// ИндексКартинки = 10;
Иначе
ИндексКартинки = 4;
КонецЕсли;
КонецЕсли;
ИначеЕсли ДанныеСтроки.ТипСлова = "Свойство" Тогда
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 2;
ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда
ИндексКартинки = 8;
//ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда
// ИндексКартинки = 11;
Иначе
ИндексКартинки = 5;
КонецЕсли;
ИначеЕсли ДанныеСтроки.ТипСлова = "Таблица" Тогда
ИндексКартинки = 14;
ИначеЕсли ДанныеСтроки.ТипСлова = "Поле" Тогда
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 15;
Иначе
ИндексКартинки = 16;
КонецЕсли;
ИначеЕсли ДанныеСтроки.ТипСлова = "Группа" Тогда
ИндексКартинки = 18;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции
Функция СтроковыйИдентификаторСсылкиЛкс(Ссылка, ВместеСТипом = Ложь) Экспорт
ИдентификаторСсылки = Неопределено;
XMLТип = XMLТипЗнч(Ссылка);
Если XMLТип <> Неопределено Тогда
Если Найти(XMLТип.ИмяТипа, "Ref.") > 0 Тогда
Если Найти(XMLТип.ИмяТипа, "ExternalDataSourceTableRef.") > 0 Тогда
ИдентификаторСсылки = "{" + ирОбщий.СтрокаМеждуМаркерамиЛкс(ЗначениеВСтрокуВнутр(Ссылка), "," + Символы.ПС + "{", "}" + Символы.ПС + "}") + "}";
ИдентификаторСсылки = СтрЗаменить(ИдентификаторСсылки, Символы.ПС, "");
Иначе
ИдентификаторСсылки = XMLСтрока(Ссылка);
КонецЕсли;
ИначеЕсли XMLТип.ИмяТипа = "Type" Тогда
XMLТипТипа = XMLТип(Ссылка);
Если XMLТипТипа <> Неопределено Тогда
ИдентификаторСсылки = XMLТипТипа.ИмяТипа;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ВместеСТипом И ИдентификаторСсылки <> Неопределено Тогда
ИдентификаторСсылки = ИдентификаторСсылки + "." + XMLТип.ИмяТипа;
КонецЕсли;
Возврат ИдентификаторСсылки;
КонецФункции
Функция ИменаИспользуемыхВЗапросеВременныхТаблицЛкс(Знач ЗапросИлиМенеджерВременныхТаблиц, Знач ОбязательныеДляПроверкиИмена = """") Экспорт
Платформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
Платформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
МассивИмен = СтрРазделитьЛкс(ОбязательныеДляПроверкиИмена, ",", Истина, Ложь);
Если ТипЗнч(ЗапросИлиМенеджерВременныхТаблиц) = Тип("Запрос") Тогда
#Если Сервер И Не Сервер Тогда
ЗапросИлиМенеджерВременныхТаблиц = Новый Запрос;
#КонецЕсли
ИменаИспользуемыхВременныхТаблиц = Платформа.НайтиВозможныеИменаВременныхТаблиц(ЗапросИлиМенеджерВременныхТаблиц.Текст);
Для Каждого ИмяИспользуемойВременнойТаблицы Из ИменаИспользуемыхВременныхТаблиц Цикл
МассивИмен.Добавить(ИмяИспользуемойВременнойТаблицы);
КонецЦикла;
МенеджерВременныхТаблиц = ЗапросИлиМенеджерВременныхТаблиц.МенеджерВременныхТаблиц;
Иначе
Если Не ирКэш.ДоступныТаблицыМенеджераВременныхТаблицЛкс() И Не ЗначениеЗаполнено(ОбязательныеДляПроверкиИмена) Тогда
ВызватьИсключение "Необходимо указать имена временных таблиц";
КонецЕсли;
МенеджерВременныхТаблиц = ЗапросИлиМенеджерВременныхТаблиц;
КонецЕсли;
Если Истина
И ирКэш.ДоступныТаблицыМенеджераВременныхТаблицЛкс()
И МенеджерВременныхТаблиц <> Неопределено
Тогда
#Если Сервер И Не Сервер Тогда
МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
#КонецЕсли
Для Каждого ТаблицаМенеджера Из МенеджерВременныхТаблиц.Таблицы Цикл
МассивИмен.Добавить(ТаблицаМенеджера.ПолноеИмя);
КонецЦикла;
КонецЕсли;
Возврат МассивИмен;
КонецФункции // ПолВТ()
Процедура СкопироватьДеревоЛкс(ИсходноеДерево, НовоеДерево, ОчиститьПередЗагрузкой = Истина, ЗначенияПоУмолчанию = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ЗначенияПоУмолчанию = Новый Структура;
#КонецЕсли
Если ОчиститьПередЗагрузкой Тогда
НовоеДерево.Строки.Очистить();
КонецЕсли;
Если ИсходноеДерево.Строки.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Если ЗначенияПоУмолчанию <> Неопределено Тогда
ИменаСвойствПоУмолчанию = ИменаСвойствСтруктурыЛкс(ЗначенияПоУмолчанию);
КонецЕсли;
Для каждого СтрокаДерева из ИсходноеДерево.Строки Цикл
НоваяСтрока = НовоеДерево.Строки.Добавить();
Если ЗначенияПоУмолчанию <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(НоваяСтрока, ЗначенияПоУмолчанию, ИменаСвойствПоУмолчанию);
КонецЕсли;
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаДерева);
СкопироватьДеревоЛкс(СтрокаДерева, НоваяСтрока, ОчиститьПередЗагрузкой = Истина);
КонецЦикла;
КонецПроцедуры
Функция СоздатьСамоудаляющийсяКомандныйФайлЛкс(Знач ТекстКомандногоФайла = "", Знач КраткоеИмяФайла = "") Экспорт
Если ЗначениеЗаполнено(КраткоеИмяФайла) Тогда
ПолноеИмяФайла = КаталогВременныхФайлов() + КраткоеИмяФайла + ".bat";
Иначе
ПолноеИмяФайла = ПолучитьИмяВременногоФайла("bat");
КонецЕсли;
ТекстКомандногоФайла = ТекстКомандногоФайла + "
|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);
Для Каждого ПроцессОС Из ВыборкаПроцессовОС Цикл
Результат = ПроцессОС;
Прервать;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ПолучитьЛитералДатыДляWQLЛкс(Знач Результат) Экспорт
Результат = Результат - СмещениеСтандартногоВремени();
Результат = "'" + Формат(Результат, "ДФ='yyyyMMdd HH:mm:ss'; ДП=") + "'";
Возврат Результат
КонецФункции
Функция ПолучитьФайлWMIЛкс(ПолноеИмяФайла, КомпьютерИлиИмя = Неопределено) Экспорт
СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс(КомпьютерИлиИмя);
ФайлыWMI = СлужбаWMI.ExecQuery("Select * from CIM_Datafile where name='" + ЗаменитьСлешиНаДвойныеЛкс(ПолноеИмяФайла) + "'");
Для каждого ФайлWMI Из ФайлыWMI цикл
КонецЦикла;
Возврат ФайлWMI;
КонецФункции
Процедура ЗаполнитьДоступныеСборкиПлатформыЛкс(СборкиПлатформы, Компьютер = "", ТипыComКлассов = Неопределено, ТабличноеПоле = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
СборкиПлатформы = Обработки.ирУправлениеСлужбамиСервера1С.Создать().СборкиПлатформы;
#КонецЕсли
Если ТабличноеПоле <> Неопределено Тогда
СостояниеСтрокТП = ирОбщий.ТабличноеПолеСостояниеСтрокЛкс(ТабличноеПоле, "Каталог");
КонецЕсли;
СборкиПлатформы.Очистить();
// Оба варианта пришлось оставить, т.к. WMI вариант очень долгий
Если ирОбщий.ЭтоИмяЛокальногоКомпьютераЛкс(Компьютер) Тогда
Инсталлер = Новый COMОбъект("WindowsInstaller.Installer");
Продукты = Инсталлер.Products;
Иначе
СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс(Компьютер);
Если СлужбаWMI = Неопределено Тогда
Возврат;
КонецЕсли;
Продукты = СлужбаWMI.ExecQuery("SELECT * FROM Win32_Product WHERE Vendor LIKE '1C' OR Vendor LIKE '1С'");
КонецЕсли;
Для Каждого Продукт Из Продукты Цикл
Если ЭтоИмяЛокальногоКомпьютераЛкс(Компьютер) Тогда
Попытка
ПубликаторПродукта = Инсталлер.ProductInfo(Продукт, "Publisher");
Исключение
Продолжить;
КонецПопытки;
Если Истина
И ПубликаторПродукта <> "1C" // латинские буквы
И ПубликаторПродукта <> "1С" // русские буквы
И ПубликаторПродукта <> "1C-Soft" // латинские буквы
И ПубликаторПродукта <> "1С-Софт" // русские буквы
Тогда
Продолжить;
КонецЕсли;
//НаименованиеПродукта = Инсталлер.ProductInfo(Продукт, "ProductName");
КаталогВерсии = Инсталлер.ProductInfo(Продукт, "InstallLocation");
//СтрокаРелиза = Инсталлер.ProductInfo(Продукт, "VersionString");
Иначе
КаталогВерсии = Продукт.InstallLocation;
КонецЕсли;
СтрокаТаблицыСборок = СборкиПлатформы.Добавить();
СтрокаТаблицыСборок.Каталог = КаталогВерсии;
ФайлПолученияВерсии = Неопределено;
Если ТипыComКлассов <> Неопределено Тогда
Для Каждого ТипКласса Из ТипыComКлассов Цикл
//Если Метаданные().ТабличныеЧасти.СборкиПлатформы.Реквизиты.Найти(ВыборкаКлассов.Имя) = Неопределено Тогда
// Продолжить;
//КонецЕсли;
ФайлКомпоненты = Новый Файл(СтрокаТаблицыСборок.Каталог + "bin\" + ТипКласса.КлючевойФайл); // Быстро
СтрокаТаблицыСборок[ТипКласса.Имя] = ФайлКомпоненты.Существует();
Если ФайлПолученияВерсии = Неопределено И СтрокаТаблицыСборок[ТипКласса.Имя] Тогда
ФайлПолученияВерсии = ФайлКомпоненты;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ИсполняемыйФайл = Новый Файл(СтрокаТаблицыСборок.Каталог + "bin\ragent.exe"); // Быстро
СтрокаТаблицыСборок.АгентСервера = ИсполняемыйФайл.Существует();
Если ФайлПолученияВерсии = Неопределено И СтрокаТаблицыСборок.АгентСервера Тогда
ФайлПолученияВерсии = ИсполняемыйФайл;
КонецЕсли;
ИсполняемыйФайл = Новый Файл(СтрокаТаблицыСборок.Каталог + "bin\ras.exe"); // Быстро
СтрокаТаблицыСборок.СерверАдминистрирования = ИсполняемыйФайл.Существует();
Если ФайлПолученияВерсии = Неопределено И СтрокаТаблицыСборок.СерверАдминистрирования Тогда
ФайлПолученияВерсии = ИсполняемыйФайл;
КонецЕсли;
ИсполняемыйФайл = Новый Файл(СтрокаТаблицыСборок.Каталог + "bin\dbgs.exe"); // Быстро
СтрокаТаблицыСборок.СерверОтладки = ИсполняемыйФайл.Существует();
Если ФайлПолученияВерсии = Неопределено И СтрокаТаблицыСборок.СерверОтладки Тогда
ФайлПолученияВерсии = ИсполняемыйФайл;
КонецЕсли;
ИсполняемыйФайл = Новый Файл(СтрокаТаблицыСборок.Каталог + "bin\crserver.exe"); // Быстро
СтрокаТаблицыСборок.СерверХранилища = ИсполняемыйФайл.Существует();
Если ФайлПолученияВерсии = Неопределено И СтрокаТаблицыСборок.СерверХранилища Тогда
ФайлПолученияВерсии = ИсполняемыйФайл;
КонецЕсли;
Если ФайлПолученияВерсии <> Неопределено Тогда
ФайлПолученияВерсии = ПолучитьФайлWMIЛкс(ФайлПолученияВерсии.ПолноеИмя, Компьютер);
СтрокаТаблицыСборок.ФайлыСуществуют = Истина;
СтрокаТаблицыСборок.x64 = ирКэш.Это64битнаяОСЛкс() И Найти(СтрокаТаблицыСборок.Каталог, "(x86)") = 0;
СтрокаТаблицыСборок.СборкаПлатформы = ФайлПолученияВерсии.Version;
СтрокаТаблицыСборок.КлючСборки = КлючСборкиПлатформыЛкс(СтрокаТаблицыСборок);
СтрокаВерсии = ФайлПолученияВерсии.Version;
Если ЗначениеЗаполнено(СтрокаВерсии) Тогда
СтрокаТаблицыСборок.СборкаПлатформы = СтрокаВерсии;
Фрагменты = СтрРазделитьЛкс(СтрокаВерсии);
ИзданиеПлатформы = Фрагменты[0] + "." + Фрагменты[1];
СтрокаТаблицыСборок.ИзданиеПлатформы = ИзданиеПлатформы;
СтрокаТаблицыСборок.Порядок = Фрагменты[0] * 10000000 + Фрагменты[1] * 1000000 + Фрагменты[2] * 10000 + Фрагменты[3];
КонецЕсли;
КонецЕсли;
СтрокаТаблицыСборок.НКаталог = НРег(СтрокаТаблицыСборок.Каталог);
КонецЦикла;
СборкиПлатформы.Сортировать("Порядок Убыв, ФайлыСуществуют Убыв, СборкаПлатформы Убыв, x64");
Если ТабличноеПоле <> Неопределено Тогда
ирОбщий.ТабличноеПолеВосстановитьСостояниеСтрокЛкс(ТабличноеПоле, СостояниеСтрокТП);
КонецЕсли;
КонецПроцедуры
Функция КлючСборкиПлатформыЛкс(Знач СтрокаТаблицыСборок) Экспорт
Возврат СтрокаТаблицыСборок.СборкаПлатформы + " - " + ?(СтрокаТаблицыСборок.x64, "64", "32");
КонецФункции
Функция ЗаменитьСлешиНаДвойныеЛкс(Строка) Экспорт
Результат = СтрЗаменить(Строка, "\", "\\");
Возврат Результат;
КонецФункции
Функция ПолучитьТекстРезультатаКомандыОСЛкс(Знач СтрокаКоманды = "", ОжидатьЗавершения = Истина, Знач ИмяКомпьютера = "", Элевация = Ложь) Экспорт
Платформа = ирКэш.Получить();
Если Ложь Тогда
Платформа = Обработки.ирПлатформа.Создать();
КонецЕсли;
ФайлРезультата = Новый Файл(ПолучитьИмяВременногоФайла("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 Тогда
ГлавнаяТаблица.Индексы.Добавить("Метаданные");
КонецЕсли;
Для Каждого ИмяМД Из ОтборПоМетаданным Цикл
Для Каждого СтрокаТаблицы Из ГлавнаяТаблица.НайтиСтроки("Метаданные", ИмяМД) Цикл
ЗаполнитьЗначенияСвойств(Результат.Добавить(), СтрокаТаблицы);
КонецЦикла;
КонецЦикла;
Иначе
Результат = ГлавнаяТаблица;
КонецЕсли;
Иначе
Результат = ПолучитьСтруктуруХраненияБазыДанных(ОтборПоМетаданным, ЛиИменаБД);
КонецЕсли;
ОбработатьВыборкуСтруктурыХраненияБДЛкс(Результат, ЛиИменаБД, ВычислитьИменаИндексов);
Если ОтборПоМетаданным = Неопределено Тогда
#Если Клиент Тогда
СостояниеЛкс("");
#КонецЕсли
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьЧужуюСхемуБДЛкс(АдресЧужойСхемыБД) Экспорт
Если Не ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда
Возврат Неопределено;
Иначе
Результат = ПолучитьИзВременногоХранилища(АдресЧужойСхемыБД);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ДочернийОбъектМДПоИмениЛкс(Знач МетаОбъект, Знач ИмяПоля, Знач ТипТаблицы = "") Экспорт
Если Не ЗначениеЗаполнено(ТипТаблицы) Тогда
ТипТаблицы = ПолучитьКорневойТипКонфигурацииЛкс(МетаОбъект);
КонецЕсли;
Если Ложь
Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы)
Или ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы)
Тогда
#Если Сервер И Не Сервер Тогда
МетаОбъект = Метаданные.Справочники.Валюты;
#КонецЕсли
Результат = МетаОбъект.Реквизиты.Найти(ИмяПоля);
ИначеЕсли ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда
#Если Сервер И Не Сервер Тогда
МетаОбъект = Метаданные.РегистрыСведений.КурсыВалют;
#КонецЕсли
Результат = МетаОбъект.Измерения.Найти(ИмяПоля);
Если Не ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы) Тогда
Если Результат = Неопределено Тогда
Результат = МетаОбъект.Ресурсы.Найти(ИмяПоля);
КонецЕсли;
Если Результат = Неопределено Тогда
Результат = МетаОбъект.Реквизиты.Найти(ИмяПоля);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Результат = Неопределено И ирКэш.ДоступныОбщиеРеквизитыЛкс() Тогда
ОбщийРеквизит = Метаданные.ОбщиеРеквизиты.Найти(ИмяПоля);
Если ОбщийРеквизит <> Неопределено Тогда
Если ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, МетаОбъект) Тогда
Результат = ОбщийРеквизит;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОбновитьПовторноИспользуемыеЗначенияЛкс() Экспорт
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ирПортативный.ОбновитьПовторноИспользуемыеЗначенияЛкс();
Иначе
ОбновитьПовторноИспользуемыеЗначения();
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСовместимоеЗначениеПараметраЗапросаЛкс(Знач ЗначениеПараметра, ИмяПараметра, ОписаниеТиповЭлементаУправленияПараметра = Неопределено) Экспорт
Результат = ЗначениеПараметра;
ТипЗначенияПараметра = ТипЗнч(Результат);
Если Истина
И ТипЗначенияПараметра = Тип("Массив")
И ОписаниеТиповЭлементаУправленияПараметра <> Неопределено
Тогда
СписокЗначений = Новый СписокЗначений;
ПреобразованиеУспешно = Истина;
Для Каждого ЭлементМассива Из Результат Цикл
Если ОписаниеТиповЭлементаУправленияПараметра.СодержитТип(ТипЗнч(ЭлементМассива)) Тогда
СписокЗначений.Добавить(ЭлементМассива);
Иначе
ПреобразованиеУспешно = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПреобразованиеУспешно Тогда
Результат = СписокЗначений;
КонецЕсли;
Иначе
// http://www.hostedredmine.com/issues/885230
//МетаданныеТипаЗначения = Метаданные.НайтиПоТипу(ТипЗначенияПараметра);
//Если МетаданныеТипаЗначения <> Неопределено Тогда
// ТипТаблицы = ТипТаблицыБДЛкс(МетаданныеТипаЗначения.ПолноеИмя());
// Если ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
// Результат = ЗначениеПараметра.Выгрузить();
// КонецЕсли;
//КонецЕсли;
Попытка
Результат = Результат.Выгрузить();
Исключение
КонецПопытки;
Если ОписаниеТиповЭлементаУправленияПараметра <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ОписаниеТиповЭлементаУправленияПараметра = Новый ОписаниеТипов;
#КонецЕсли
Результат = ОписаниеТиповЭлементаУправленияПараметра.ПривестиЗначение(Результат);
КонецЕсли;
КонецЕсли;
Если Результат <> ЗначениеПараметра Тогда
СообщитьЛкс("Значение параметра """ + ИмяПараметра + """ было преобразовано """ + ТипЗначенияПараметра + """->""" + ТипЗнч(Результат) + """", СтатусСообщения.Внимание);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПолучитьСхемуИНастройкиКомпоновкиДинамическогоСпискаЛкс(Знач ДинамическийСписок, выхНастройкаКомпоновки, выхСхема) Экспорт
ТекстЗапроса = ДинамическийСписок.ТекстЗапроса;
Если Не ЗначениеЗаполнено(ТекстЗапроса) Тогда
ТекстЗапроса = "ВЫБРАТЬ * ИЗ " + ДинамическийСписок.ОсновнаяТаблица;
КонецЕсли;
Запрос = Новый Запрос(ТекстЗапроса);
выхНастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
ТекущаяГруппировка = выхНастройкаКомпоновки;
Для Каждого ПолеГруппировки Из ДинамическийСписок.Группировка.Элементы Цикл
Если ПолеГруппировки.Использование Тогда
ТекущаяГруппировка = НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура, ПолеГруппировки.Поле);
КонецЕсли;
КонецЦикла;
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура);
Для Каждого ДоступноеПоле Из ДинамическийСписок.УсловноеОформление.ДоступныеПоляПолей.Элементы Цикл
Если ДоступноеПоле.Папка Тогда
Продолжить;
КонецЕсли;
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(выхНастройкаКомпоновки.Выбор, ДоступноеПоле.Поле);
КонецЦикла;
НастройкаXDTO = СериализаторXDTO.ЗаписатьXDTO(выхНастройкаКомпоновки);
НастройкаXDTO.Filter = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Отбор);
НастройкаXDTO.DataParameters = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Параметры);
НастройкаXDTO.Order = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Порядок);
НастройкаXDTO.ConditionalAppearance = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.УсловноеОформление);
выхНастройкаКомпоновки = СериализаторXDTO.ПрочитатьXDTO(НастройкаXDTO);
выхСхема = СоздатьСхемуКомпоновкиПоЗапросу(Запрос);
КонецПроцедуры
// Если передана НастройкаКомпоновкиПриемник, то в качестве результата вернется ее копия!
Функция СкопироватьНастройкиКомпоновкиЛкс(НастройкаКомпоновкиИлиДинамическийСписокИсточник, Знач НастройкаКомпоновкиПриемник = Неопределено, КопироватьОтбор = Ложь,
КопироватьПараметрыДанных = Ложь, КопироватьПорядок = Ложь, КопироватьУсловноеОформление = Ложь, КопироватьВыбор = Ложь, КопироватьПараметрыВывода = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновкиИсточник = Новый НастройкиКомпоновкиДанных;
НастройкаКомпоновкиИлиДинамическийСписокИсточник = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
Если ТипЗнч(НастройкаКомпоновкиИлиДинамическийСписокИсточник) = Тип("НастройкиКомпоновкиДанных") Тогда
Если КопироватьПараметрыДанных Тогда
ПараметрыДанных = НастройкаКомпоновкиИлиДинамическийСписокИсточник.ПараметрыДанных;
КонецЕсли;
Если КопироватьПараметрыВывода Тогда
ПараметрыВывода = НастройкаКомпоновкиИлиДинамическийСписокИсточник.ПараметрыВывода;
КонецЕсли;
Иначе // ДинамическийСписок
Если КопироватьПараметрыДанных Тогда
ПараметрыДанных = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Параметры;
КонецЕсли;
КонецЕсли;
Если КопироватьВыбор Тогда
Выбор = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Выбор;
КонецЕсли;
Если КопироватьОтбор Тогда
Отбор = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Отбор;
КонецЕсли;
Если КопироватьПорядок Тогда
Порядок = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Порядок;
КонецЕсли;
Если КопироватьУсловноеОформление Тогда
УсловноеОформление = НастройкаКомпоновкиИлиДинамическийСписокИсточник.УсловноеОформление;
КонецЕсли;
НастройкаКомпоновкиПриемник = УстановитьКомпонентыНастроекКомпоновкиЛкс(НастройкаКомпоновкиПриемник, ПараметрыДанных, Выбор, Отбор, Порядок, УсловноеОформление, ПараметрыВывода);
Возврат НастройкаКомпоновкиПриемник;
КонецФункции
// Параметры:
// НастройкаКомпоновкиПриемник - ? -
// Параметры - ? -
// Выбор - ? -
// Отбор - ? -
// Порядок - ? -
// УсловноеОформление - ? -
// Возвращаемое значение:
// НастройкиКомпоновкиДанных - новый объект настроек с установленными компонентами
Функция УстановитьКомпонентыНастроекКомпоновкиЛкс(Знач НастройкаКомпоновкиПриемник = Неопределено, Знач ПараметрыДанных = Неопределено, Знач Выбор = Неопределено, Знач Отбор = Неопределено,
Знач Порядок = Неопределено, Знач УсловноеОформление = Неопределено, ПараметрыВывода = Неопределено) Экспорт
Если НастройкаКомпоновкиПриемник = Неопределено Тогда
НастройкаКомпоновкиПриемник = Новый НастройкиКомпоновкиДанных;
КонецЕсли;
НастройкаXDTO = СериализаторXDTO.ЗаписатьXDTO(НастройкаКомпоновкиПриемник);
Если ПараметрыДанных <> Неопределено Тогда
НастройкаXDTO.DataParameters = СериализаторXDTO.ЗаписатьXDTO(ПараметрыДанных);
КонецЕсли;
Если Выбор <> Неопределено Тогда
НастройкаXDTO.selection = СериализаторXDTO.ЗаписатьXDTO(Выбор);
КонецЕсли;
Если Отбор <> Неопределено Тогда
НастройкаXDTO.Filter = СериализаторXDTO.ЗаписатьXDTO(Отбор);
КонецЕсли;
Если Порядок <> Неопределено Тогда
НастройкаXDTO.Order = СериализаторXDTO.ЗаписатьXDTO(Порядок);
КонецЕсли;
Если УсловноеОформление <> Неопределено Тогда
НастройкаXDTO.ConditionalAppearance = СериализаторXDTO.ЗаписатьXDTO(УсловноеОформление);
КонецЕсли;
Если ПараметрыВывода <> Неопределено Тогда
НастройкаXDTO.OutputParameters = СериализаторXDTO.ЗаписатьXDTO(ПараметрыВывода);
КонецЕсли;
НастройкаКомпоновкиПриемник = СериализаторXDTO.ПрочитатьXDTO(НастройкаXDTO);
Возврат НастройкаКомпоновкиПриемник;
КонецФункции
Функция ПолучитьРасширениеФайловДляОтладкиЛкс() Экспорт
Результат = "deb";
Возврат Результат;
КонецФункции
Функция ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки = Неопределено, Знач Наименование = "")
Если Не ЗначениеЗаполнено(Наименование) Тогда
Наименование = "" + СтруктураПараметров.Объект;
КонецЕсли;
Наименование = "" + ТекущаяДата() + " " + СтруктураПараметров.ТипОперации + " " + Наименование;
Успех = Ложь;
ДоступноФоновоеЗадание = Не (Истина
И ТранзакцияАктивна()
И ирКэш.ЭтоФайловаяБазаЛкс()
// В файловой базе даже 8.3 не получится, т.к. там не истинной параллельности
//И (Ложь
// Или РежимСовместимостиМеньше8_3_4Лкс()
// Или ирКэш.ЭтоФоновоеЗаданиеЛкс())
);
Если Истина
И Метаданные.Справочники.Найти("ирОбъектыДляОтладки") <> Неопределено
И ДоступноФоновоеЗадание
Тогда
Попытка
ХранимоеЗначение = СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров);
СтруктураОбъекта = ОбъектБДПоКлючуЛкс(Метаданные.Справочники.ирОбъектыДляОтладки.ПолноеИмя());
ОбъектДляОтладки = СтруктураОбъекта.Данные;
ОбъектДляОтладки.Наименование = Наименование;
ОбъектДляОтладки.XML = ХранимоеЗначение;
выхОбъектДляОтладки = ЗаписатьОбъектДляОтладкиЛкс(СтруктураОбъекта.Методы);
Успех = Истина;
Исключение
Результат = "Ошибка записи объекта для отладки: " + ОписаниеОшибки();
КонецПопытки;
Если Успех Тогда
Результат = "Скопируйте эту строку и используйте команду ""Открыть объект для отладки"". Данные помещены в справочник ""Объекты для отладки""."
+ " Объект """ + ОбъектДляОтладки + """(" + выхОбъектДляОтладки.УникальныйИдентификатор() + ")";
КонецЕсли;
Иначе
//выхОбъектДляОтладки = ПоместитьВоВременноеХранилище(ХранимоеЗначение, Новый УникальныйИдентификатор);
//Результат = "Данные помещены в хранилище ДО КОНЦА СЕАНСА. Скопируйте эту строку и используйте команду ""Открыть объект для отладки""."
//+ " Адрес """ + выхОбъектДляОтладки + """";
КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс();
Успех = Ложь;
Если ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
РасширениеФайловДляОтладки = ПолучитьРасширениеФайловДляОтладкиЛкс();
Платформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
Платформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Наименование = Платформа.ИдентификаторИзПредставленияЛкс(Наименование);
ИмяФайла = КаталогОбъектовДляОтладки + "\" + Наименование + "." + РасширениеФайловДляОтладки;
ФайлОбъектаДляОтладки = Новый Файл(ИмяФайла);
Попытка
СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров, , ФайлОбъектаДляОтладки.ПолноеИмя);
Успех = Истина;
Исключение
СообщитьЛкс("Ошибка сохранения файла для отладки: " + ОписаниеОшибки());
КонецПопытки;
Если Успех Тогда
выхОбъектДляОтладки = ФайлОбъектаДляОтладки.ПолноеИмя;
Результат = "Скопируйте эту строку и используйте команду ""Открыть объект для отладки"". Данные помещены в файл."
+ " Файл """ + выхОбъектДляОтладки + """";
КонецЕсли;
Иначе
ТекстРекомендации = "Рекомендуется в общих настройках инструментов задать каталог объектов для отладки.";
СообщитьЛкс(ТекстРекомендации);
КонецЕсли;
Если Не Успех Тогда
Если ТранзакцияАктивна() И Не ДоступноФоновоеЗадание Тогда
Попытка
ОтменитьТранзакцию();
Успех = Истина;
Исключение
// Системная транзакция записи объекта
КонецПопытки;
Если Не Успех Тогда
Результат = "Невозможно отменить транзакцию записи объекта для сохранения объекта для отладки в общие настройки. " + ТекстРекомендации;
Иначе
СообщитьЛкс("Транзакция была отменена для сохранения объекта для отладки в общие настройки");
КонецЕсли;
Иначе
Успех = Истина;
КонецЕсли;
Если Успех Тогда
Успех = Ложь;
Попытка
КлючНастройки = ЗаписатьОбъектДляОтладкиЛкс(СтруктураПараметров);
Успех = Истина;
Исключение
Результат = "Ошибка записи объекта для отладки: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Если Успех Тогда
Результат = РезультатСохраненияОбъектаОтложеннойОтладкиВНастройкуЛкс(КлючНастройки);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// КлючНастройки - Ссылка, Строка
Функция РезультатСохраненияОбъектаОтложеннойОтладкиВНастройкуЛкс(Знач КлючНастройки = "") Экспорт
Если Не ЗначениеЗаполнено(КлючНастройки) Тогда
КлючНастройки = ИмяНастройкиХраненияОбъектаОтложеннойОтладкиЛкс();
КонецЕсли;
Результат = "Скопируйте эту строку и используйте команду ""Открыть объект для отладки"". Данные помещены в настройку """ + КлючНастройки + """."
+ " Пользователь """ + ИмяПользователя() + """";
Возврат Результат;
КонецФункции
Функция СоздаваемыеВременныеТаблицыПакетаЛкс(ТекстЗапроса, ТолькоТребующиеУничтоженияНаВходе = Ложь) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
МассивТаблиц = мПлатформа.ПолучитьМассивСоздаваемыхВременныхТаблицПакета(ТекстЗапроса, ТолькоТребующиеУничтоженияНаВходе);
Возврат МассивТаблиц;
КонецФункции
// Подставляет параметры в строку. Максимально возможное число параметров - 9.
// Параметры в строке задаются как %<номер параметра>. Нумерация параметров начинается с единицы.
//
// Параметры:
// СтрокаПодстановки - Строка - шаблон строки с параметрами (вхождениями вида "%ИмяПараметра");
// Параметр - Строка - подставляемый параметр.
//
// Возвращаемое значение:
// Строка - текстовая строка с подставленными параметрами.
//
// Пример:
// ПодставитьПараметрыВСтроку(НСтр("ru='%1 пошел в %2'"), "Вася", "Зоопарк") = "Вася пошел в Зоопарк".
//
Функция ПодставитьПараметрыВСтрокуЛкс(Знач СтрокаПодстановки,
Знач Параметр1, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено,
Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено,
Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) Экспорт
ИспользоватьАльтернативныйАлгоритм = Ложь
Или Найти(Параметр1, "%")
Или Найти(Параметр2, "%")
Или Найти(Параметр3, "%")
Или Найти(Параметр4, "%")
Или Найти(Параметр5, "%")
Или Найти(Параметр6, "%")
Или Найти(Параметр7, "%")
Или Найти(Параметр8, "%")
Или Найти(Параметр9, "%");
Если ИспользоватьАльтернативныйАлгоритм Тогда
СтрокаПодстановки = ПодставитьПараметрыВСтрокуАльтернативныйАлгоритм(СтрокаПодстановки, Параметр1,
Параметр2, Параметр3, Параметр4, Параметр5, Параметр6, Параметр7, Параметр8, Параметр9);
Иначе
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%1", Параметр1);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%2", Параметр2);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%3", Параметр3);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%4", Параметр4);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%5", Параметр5);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%6", Параметр6);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%7", Параметр7);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%8", Параметр8);
СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%9", Параметр9);
КонецЕсли;
Возврат СтрокаПодстановки;
КонецФункции
// Вставляет параметры в строку, учитывая, что в параметрах могут использоваться подстановочные слова %1, %2 и т.д.
Функция ПодставитьПараметрыВСтрокуАльтернативныйАлгоритм(Знач СтрокаПодстановки,
Знач Параметр1, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено,
Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено,
Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено)
Результат = "";
Позиция = Найти(СтрокаПодстановки, "%");
Пока Позиция > 0 Цикл
Результат = Результат + Лев(СтрокаПодстановки, Позиция - 1);
СимволПослеПроцента = Сред(СтрокаПодстановки, Позиция + 1, 1);
ПодставляемыйПараметр = "";
Если СимволПослеПроцента = "1" Тогда
ПодставляемыйПараметр = Параметр1;
ИначеЕсли СимволПослеПроцента = "2" Тогда
ПодставляемыйПараметр = Параметр2;
ИначеЕсли СимволПослеПроцента = "3" Тогда
ПодставляемыйПараметр = Параметр3;
ИначеЕсли СимволПослеПроцента = "4" Тогда
ПодставляемыйПараметр = Параметр4;
ИначеЕсли СимволПослеПроцента = "5" Тогда
ПодставляемыйПараметр = Параметр5;
ИначеЕсли СимволПослеПроцента = "6" Тогда
ПодставляемыйПараметр = Параметр6;
ИначеЕсли СимволПослеПроцента = "7" Тогда
ПодставляемыйПараметр = Параметр7
ИначеЕсли СимволПослеПроцента = "8" Тогда
ПодставляемыйПараметр = Параметр8;
ИначеЕсли СимволПослеПроцента = "9" Тогда
ПодставляемыйПараметр = Параметр9;
КонецЕсли;
Если ПодставляемыйПараметр = "" Тогда
Результат = Результат + "%";
СтрокаПодстановки = Сред(СтрокаПодстановки, Позиция + 1);
Иначе
Результат = Результат + ПодставляемыйПараметр;
СтрокаПодстановки = Сред(СтрокаПодстановки, Позиция + 2);
КонецЕсли;
Позиция = Найти(СтрокаПодстановки, "%");
КонецЦикла;
Результат = Результат + СтрокаПодстановки;
Возврат Результат;
КонецФункции
Функция ПолучитьКаталогОбъектовДляОтладкиЛкс(ДляСервера = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ирПортативный = Обработки.ирПортативный.Создать();
#КонецЕсли
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
КаталогОбъектовДляОтладки = ирПортативный.ПолучитьКаталогОбъектовДляОтладкиЛкс();
Иначе
//ИмяФайла = ПолучитьИмяВременногоФайла(РасширениеФайловДляОтладки);
КаталогОбъектовДляОтладки = ВосстановитьЗначениеЛкс("КаталогОбъектовДляОтладки");
#Если Клиент Тогда
Если Не ДляСервера И Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
КаталогОбъектовДляОтладки = ирКэш.Получить().КаталогФайловогоКэша;
КонецЕсли;
#КонецЕсли
Если ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
ИмяКаталогаБазы = ирКэш.Получить().ИдентификаторИзПредставленияЛкс(СтрокаСоединенияИнформационнойБазы());
КаталогОбъектовДляОтладки = КаталогОбъектовДляОтладки + "\" + ИмяКаталогаБазы + "\";
Каталог = Новый Файл(КаталогОбъектовДляОтладки);
Если Не Каталог.Существует() Тогда
Попытка
СоздатьКаталог(КаталогОбъектовДляОтладки);
Исключение
СообщитьЛкс("Ошибка создания каталога объектов для отладки: " + ОписаниеОшибки());
КаталогОбъектовДляОтладки = Неопределено;
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат КаталогОбъектовДляОтладки;
КонецФункции
Функция ИмяПродуктаЛкс() Экспорт
Возврат "ИнструментыРазработчикаTormozit";
КонецФункции
Функция ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(Параметры) Экспорт
// Антибаг платформы 8.2.18. Некорректная сериализация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СтруктураЗапроса.Параметры = КопияОбъектаЛкс(Объект.Параметры);
Структура = Новый Структура();
Для Каждого КлючИЗначение Из Параметры Цикл
ЗначениеПараметра = ПолучитьСовместимоеЗначениеПараметраЗапросаЛкс(КлючИЗначение.Значение, КлючИЗначение.Ключ);
Структура.Вставить(КлючИЗначение.Ключ, ЗначениеВСтрокуВнутр(ЗначениеПараметра));
КонецЦикла;
Возврат Структура;
КонецФункции
Функция СкопироватьЗапросЛкс(ЗапросИсточник, ЗапросПриемник = Неопределено) Экспорт
Если ЗапросПриемник = Неопределено Тогда
ЗапросПриемник = Новый Запрос;
КонецЕсли;
ЗапросПриемник.Текст = ЗапросИсточник.Текст;
ирОбщий.СкопироватьУниверсальнуюКоллекциюЛкс(ЗапросИсточник.Параметры, ЗапросПриемник.Параметры);
Возврат ЗапросПриемник;
КонецФункции // СкопироватьЗапросЛкс()
Функция ПолучитьТекстЗапросаВсехТиповСсылокЛкс(ИмяВременнойТаблицы = "ВсеТипыСсылок", Знач ОписаниеТипов = Неопределено) Экспорт
Если ОписаниеТипов = Неопределено Тогда
ОписаниеТипов = ОписаниеТиповВсеСсылкиЛкс();
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОписаниеВсехТипов = Новый ОписаниеТипов;
#КонецЕсли
ТекстТаблицыТипов = "";
Для Каждого Тип Из ОписаниеТипов.Типы() Цикл
ПолноеИмя = Метаданные.НайтиПоТипу(Тип).ПолноеИмя();
НоваяСтрока = "ВЫБРАТЬ ТИП(" + ПолноеИмя + ") КАК Тип, """ + ПолноеИмя + """ КАК Имя" + Символы.ПС;
Если ТекстТаблицыТипов <> "" Тогда
ТекстТаблицыТипов = ТекстТаблицыТипов + "ОБЪЕДИНИТЬ ВСЕ " + Символы.ПС;
Иначе
Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
НоваяСтрока = НоваяСтрока + "ПОМЕСТИТЬ " + ИмяВременнойТаблицы + Символы.ПС;
КонецЕсли;
КонецЕсли;
ТекстТаблицыТипов = ТекстТаблицыТипов + НоваяСтрока;
КонецЦикла;
//ТекстТаблицыТипов = ТекстТаблицыТипов + " ИНДЕКСИРОВАТЬ ПО Тип"; // По такому типу поля нельзя индексировать
Возврат ТекстТаблицыТипов;
КонецФункции
Функция ПолучитьТекстЗапросаДатВДиапазонеЛкс(ИмяВременнойТаблицы = "ДатыДиапазона") Экспорт
Текст = "ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, aa.a * 1000 + bb.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 Тогда
Если МассивИменПолей.Количество() > 0 Тогда
Для Каждого ИмяПоля Из МассивИменПолей Цикл
ЗначениеПоля = ЗначенияПолей.Найти(ИмяПоля);
ИмяСвойства = СтрЗаменить(ИмяПоля, ".", "");
Если Истина
И ЗначениеПоля <> Неопределено
И Не СтруктураПолей.Свойство(ИмяСвойства)
Тогда
СтруктураПолей.Вставить(ИмяСвойства, ЗначениеПоля.Значение);
Если СтруктураПолей.Количество() = МассивИменПолей.Количество() Тогда
Результат = Истина;
Прервать
КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе
Для Каждого ЗначениеПоля Из ЗначенияПолей Цикл
СтруктураПолей.Вставить(ЗначениеПоля.Поле, ЗначениеПоля.Значение);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не Результат Тогда
РодительскиеЭлементыРасшифровки = ЭлементРасшифровкиПоля.ПолучитьРодителей();
Для Каждого РодительскийЭлементРасшифровки Из РодительскиеЭлементыРасшифровки Цикл
Результат = ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(РодительскийЭлементРасшифровки, МассивИменПолей, СтруктураПолей);
Если Результат Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьСоединениеСУБД(Знач ИмяСервера = "", Знач ИмяБД = "", Знач ИмяПользователя = "", Знач Пароль = "", Асинхронно = Ложь) Экспорт
Если Не ЗначениеЗаполнено(ИмяСервера) Тогда
ПараметрыСоединения = ПараметрыСоединенияADOЭтойБДЛкс();
ИмяСервера = ПараметрыСоединения.ИмяСервера;
ИмяБД = ПараметрыСоединения.ИмяБД;
ИмяПользователя = ПараметрыСоединения.ИмяПользователя;
Пароль = ПараметрыСоединения.Пароль;
КонецЕсли;
КонсольЗапросов = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
ИсточникДанных = КонсольЗапросов.ПолучитьСтруктуруИсточникаДанныхADO();
ИсточникДанных.Платформа = 11; // ADO-SQLOLEDB
ИсточникДанных.БазаСервер = ИмяСервера;
ИсточникДанных.БазаИмя = ИмяБД;
ИсточникДанных.АутентификацияОС = Не ЗначениеЗаполнено(ИмяПользователя);
ИсточникДанных.Пользователь = ИмяПользователя;
ИсточникДанных.Пароль = Пароль;
СоединениеADO = Неопределено;
ОшибкиПодключения = Неопределено;
РезультатПодключения = КонсольЗапросов.ConnectADO(ИсточникДанных, СоединениеADO,, ОшибкиПодключения,, Асинхронно);
Если Асинхронно Тогда
Возврат Неопределено;
КонецЕсли;
Если Не РезультатПодключения Тогда
СообщениеОбОшибке = "Ошибки подключения к серверу СУБД (MSSQL):";
Для каждого ОшибкаПодключения Из ОшибкиПодключения Цикл
СообщениеОбОшибке = СообщениеОбОшибке + Символы.ПС + ОшибкаПодключения;
КонецЦикла;
СообщитьЛкс(СообщениеОбОшибке);
СоединениеADO = Неопределено;
Иначе
КлючНастроек = "" + Новый УникальныйИдентификатор;
ХранилищеОбщихНастроек.Сохранить(ирКэш.ИмяПродукта(), КлючНастроек, Неопределено);
РезультатЗапроса = ирОбщий.ВыполнитьЗапросКЭтойБазеЧерезADOЛкс("SELECT * FROM _CommonSettings WITH(NOLOCK) WHERE _SettingsKey = '" + КлючНастроек + "'",,,,, Ложь, СоединениеADO);
ХранилищеОбщихНастроек.Удалить(ирКэш.ИмяПродукта(), КлючНастроек, ИмяПользователя());
Если РезультатЗапроса.Количество() = 0 Тогда
СообщитьЛкс("Указаны параметры подключения к БД, не связанной с текущей базой 1С", СтатусСообщения.Внимание);
СоединениеADO = Неопределено;
КонецЕсли;
КонецЕсли;
Возврат СоединениеADO;
КонецФункции
Функция ОткрытьЗапросСУБДЛкс(ТекстЗапроса, ИмяЗапроса = "Запрос для отладки", Параметры = Неопределено, Автоподключение = Ложь) Экспорт
КонсольЗапросов = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
КонсольЗапросов.ОткрытьЗапросБД(ТекстЗапроса, ИмяЗапроса, Параметры, Автоподключение);
КонецФункции
Функция HTTPСоединение(ИмяСервера, Таймаут = 0, Порт = Неопределено, ИспользоватьЗащищенноеСоединение = Ложь) Экспорт
ЗащищенноеСоединение = Неопределено;
Если ИспользоватьЗащищенноеСоединение Тогда
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL;
КонецЕсли;
Попытка
Результат = Новый HTTPСоединение(ИмяСервера, Порт,,,, Таймаут, ЗащищенноеСоединение);
Исключение
// Антибаг платформы https://bugboard.v8.1c.ru/error/000013833.html
Результат = Новый HTTPСоединение(ИмяСервера, Порт,,, Новый ИнтернетПрокси(Ложь), Таймаут, ЗащищенноеСоединение);
КонецПопытки;
Возврат Результат;
КонецФункции
Функция ИнтернетПрокси(ИспользоватьСобственныйПрокси = Ложь, ЗащищенноеСоединение = Ложь) Экспорт
ИнтернетПрокси = Новый ИнтернетПрокси(Не ИспользоватьСобственныйПрокси);
Если ИспользоватьСобственныйПрокси Тогда
СобственныеПрокси = ирОбщий.ВосстановитьЗначениеЛкс("ИнтернетПрокси");
#Если Сервер И Не Сервер Тогда
СобственныеПрокси = Новый Структура;
#КонецЕсли
Протокол = ?(ЗащищенноеСоединение, "https", "http");
Если СобственныеПрокси.Свойство(Протокол) Тогда
НастройкиПрокси = СобственныеПрокси[Протокол];
Если ЗначениеЗаполнено(НастройкиПрокси.Сервер) Тогда
ИнтернетПрокси.Установить(Протокол, НастройкиПрокси.Сервер, НастройкиПрокси.Порт, НастройкиПрокси.Пользователь, НастройкиПрокси.Пароль, НастройкиПрокси.АутентификацияОС);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ИнтернетПрокси;
КонецФункции
Функция ОбновитьМодульВнешнейОбработкиДляОтладкиЛкс(БазовоеИмяВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля, ТекстМодуляВКонсолиНеМенялся, ДатаИзмененияВнешнейОбработки) Экспорт
// Из-за негарантированной последовательности изменений одного файла в сетевом ресурсе, проводимых с разных компьютеров, серверное выполнение лишено смысла
//Если НаСервере Тогда
// Результат = ирСервер.ОбновитьМодульВнешнейОбработкиДляОтладкиЛкс(БазовоеИмяВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля, ТекстМодуляВКонсолиНеМенялся, ДатаИзмененияВнешнейОбработки);
// Возврат Результат;
//Иначе
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ИмяФайлаВнешнейОбработки = ФайлВнешнейОбработкиДляОтладкиЛкс(БазовоеИмяВнешнейОбработки);
Если Не ЗначениеЗаполнено(ИмяФайлаВнешнейОбработки) Тогда
Возврат Ложь;
КонецЕсли;
ФайловыйКэшАлгоритмовДопускаетРедактирование = Истина;
ФайлВнешнейОбработки = Новый Файл(ИмяФайлаВнешнейОбработки);
Если ДатаИзмененияВнешнейОбработки <> Неопределено Тогда
Если Ложь
Или (Истина
И ФайлВнешнейОбработки.Существует()
И ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс() > ДатаИзмененияВнешнейОбработки
И ФайловыйКэшАлгоритмовДопускаетРедактирование)
Или (Истина
И ФайлВнешнейОбработки.Существует()
И ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс() = ДатаИзмененияВнешнейОбработки
И ТекстМодуляВКонсолиНеМенялся)
Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
мПлатформа.СформироватьВнешнююОбработку(ФайлВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля);
//// 19.01.2019 Для ВерсияАлгоритма в консоли кода
////ДатаИзмененияВнешнейОбработки = ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс();
//Если ЗначениеЗаполнено(ДатаИзмененияВнешнейОбработки) Тогда
// ФайлВнешнейОбработки.УстановитьВремяИзменения(ДатаИзмененияВнешнейОбработки);
//КонецЕсли;
Возврат Истина;
//КонецЕсли;
КонецФункции
// Получает идентификатор из любой строки.
// "3-я Дебиторка По контрагентам с интервалами СНГ (для Руководства)" => "_3_яДебиторкаПоКонтрагентамСИнтерваламиСНГ_дляРуководства_".
// Обертка ирПлатформа.ИдентификаторИзПредставленияЛкс()
//
// Параметры:
// Представление – Строка.
//
// Возвращаемое значение:
// Строка.
//
Функция ИдентификаторИзПредставленияЛкс(Знач Представление = Неопределено, ЗаменаПустойСтроки = "_", ДопРазрешенныеСимволы = "") Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если Представление = Неопределено Тогда
Представление = Новый УникальныйИдентификатор;
КонецЕсли;
Результат = мПлатформа.ИдентификаторИзПредставленияЛкс(Представление, ЗаменаПустойСтроки, ДопРазрешенныеСимволы);
Возврат Результат;
КонецФункции
Функция ФайлВнешнейОбработкиДляОтладкиЛкс(Знач ИмяВнешнейОбработки) Экспорт
КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс();
Если Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
СообщитьЛкс("В общих настройках инструментов не задан каталог объектов для отладки! Сохранение внешней обработки не выполнено.", СтатусСообщения.Внимание);
Возврат "";
КонецЕсли;
ИмяФайлаВнешнейОбработки = КаталогОбъектовДляОтладки + "\" + ИмяВнешнейОбработки + ".epf";
Возврат ИмяФайлаВнешнейОбработки;
КонецФункции
Процедура ЗаписатьДокументDOMВФайлЛкс(Знач ДокументДом, Знач ИмяФайла) Экспорт
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяФайла);
ЗаписьДом = Новый ЗаписьDOM;
ЗаписьДом.Записать(ДокументДом, ЗаписьXML);
ЗаписьXML.Закрыть();
КонецПроцедуры
Функция ЗаписатьДокументDOMВСтрокуЛкс(Знач ДокументДом) Экспорт
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("");
ЗаписьДом = Новый ЗаписьDOM;
ЗаписьДом.Записать(ДокументДом, ЗаписьXML);
Результат = ЗаписьXML.Закрыть();
Возврат Результат;
КонецФункции
Функция ПрочитатьФайлВДокументDOMЛкс(Знач ИмяФайла, ИгнорироватьПробельныеСимволы = Ложь) Экспорт
ЧтениеXML = Новый ЧтениеXML;
ПараметрыЧтения = Новый ПараметрыЧтенияXML(,,,,,,,, ИгнорироватьПробельныеСимволы);
ЧтениеXML.ОткрытьФайл(ИмяФайла, ПараметрыЧтения);
ПостроительДом = Новый ПостроительDOM();
ДокументДОМ = ПостроительДом.Прочитать(ЧтениеXML);
ЧтениеXML.Закрыть();
Возврат ДокументДОМ;
КонецФункции
Функция ПрочитатьТекстВДокументDOMЛкс(Знач Текст, ИгнорироватьПробельныеСимволы = Ложь) Экспорт
ЧтениеXML = Новый ЧтениеXML;
ПараметрыЧтения = Новый ПараметрыЧтенияXML(,,,,,,,, ИгнорироватьПробельныеСимволы);
ЧтениеXML.УстановитьСтроку(Текст, ПараметрыЧтения);
ПостроительDOM = Новый ПостроительDOM;
ДокументДом = ПостроительDOM.Прочитать(ЧтениеXML);
Возврат ДокументДом;
КонецФункции
Функция ПолучитьДокументDOMИзСтрокиВнутрЛкс(ТекстФайла, ИгнорироватьПробельныеСимволы = Истина) Экспорт
XMLСтрока = СтрокаВнутрВХМЛТелоЛкс(ТекстФайла);
ДокументDOM = ПрочитатьТекстВДокументDOMЛкс(XMLСтрока, ИгнорироватьПробельныеСимволы);
Возврат ДокументDOM;
КонецФункции
Функция ЭтотРасширениеКонфигурацииЛкс() Экспорт
Результат = Неопределено;
Если Не ирОбщий.РежимСовместимостиМеньше8_3_4Лкс() Тогда
Попытка
ЭтиРасширения = Вычислить("РасширенияКонфигурации").Получить(); // Антибаг платформы https://partners.v8.1c.ru/forum/t/1607016/m/1607016
Исключение
Возврат Результат;
КонецПопытки;
ОтборРасширений = Новый Структура("Имя", ирОбщий.ИмяПродуктаЛкс());
ЭтиРасширения = Вычислить("РасширенияКонфигурации").Получить(ОтборРасширений);
Если ЭтиРасширения.Количество() > 0 Тогда
Результат = ЭтиРасширения[0];
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция АдаптироватьРасширениеЛкс(ИмяПользователя = "", ПарольПользователя = "", ВключатьНомерСтроки = Истина) Экспорт
#Если ТонкийКлиент Или ВебКлиент Тогда
Результат = ирСервер.АдаптироватьРасширениеЛкс();
Возврат Результат;
#КонецЕсли
ПометкиКоманд = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.ПометкиКоманд",, ирОбщий.ИмяПродуктаЛкс());
ПодключитьОтладкуВнешнихОбработокБСП = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.ПодключитьОтладкуВнешнихОбработокБСП",, ирОбщий.ИмяПродуктаЛкс());
//ПодключитьОтладкуОтчетов = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.ПодключитьОтладкуОтчетов",, ирОбщий.ИмяПродуктаЛкс());
ПодключитьОтладкуОтчетов = Ложь; // Теперь это делается через глобальную команду
//СгенерироватьРольВсеПрава = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.СгенерироватьРольВсеПрава",, ирОбщий.ИмяПродуктаЛкс());
СгенерироватьРольВсеПрава = Ложь; // Давать права на верхние объекты метаданных недостаточно. Поэтому отключил пока этот флажок
НадоДобавитьВсеСсылочныеМетаданнные = СгенерироватьРольВсеПрава;
Для Каждого КлючИЗначение Из ПометкиКоманд Цикл
Если КлючИЗначение.Значение Тогда
НадоДобавитьВсеСсылочныеМетаданнные = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
ЭтотРасширение = ЭтотРасширениеКонфигурацииЛкс();
#Если Сервер И Не Сервер Тогда
ЭтотРасширение = РасширенияКонфигурации.Создать();
#КонецЕсли
ИмяРасширения = ЭтотРасширение.Имя;
ТекстСпискаОбъектовКонфигурации = "";
Если НадоДобавитьВсеСсылочныеМетаданнные Тогда
ТипыСсылок = ирОбщий.ОписаниеТиповВсеСсылкиЛкс(Ложь).Типы();
#Если Сервер И Не Сервер Тогда
ТипыСсылок = Новый Массив;
#КонецЕсли
ТипыСсылокПлановОбмена = ПланыОбмена.ТипВсеСсылки().Типы();
// Сначала выгружаем из конфигурации все метаданные
//ТекстСпискаОбъектовКонфигурации = Метаданные.ПолноеИмя();
ДобавляемыеТипы = СкопироватьУниверсальнуюКоллекциюЛкс(ТипыСсылок);
#Если Сервер И Не Сервер Тогда
ДобавляемыеТипы = Новый Массив;
#КонецЕсли
Если СгенерироватьРольВсеПрава Тогда
ДобавляемыеТипыРегистров = Новый Массив;
ДобавляемыеТипыРегистров.Добавить("РегистрыСведений");
ДобавляемыеТипыРегистров.Добавить("РегистрыНакопления");
ДобавляемыеТипыРегистров.Добавить("РегистрыРасчета");
ДобавляемыеТипыРегистров.Добавить("РегистрыБухгалтерии");
ДобавляемыеТипыРегистров.Добавить("Последовательности");
Для Каждого ИмяКоллекцииРегистров Из ДобавляемыеТипыРегистров Цикл
Для Каждого ОбъектМД Из Метаданные[ИмяКоллекцииРегистров] Цикл
ДобавляемыеТипы.Добавить(Тип(СтрЗаменить(ОбъектМД.ПолноеИмя(), ".", "НаборЗаписей.")));
КонецЦикла;
КонецЦикла;
КонецЕсли;
Для Каждого Тип Из ДобавляемыеТипы Цикл
ОбъектМД = Метаданные.НайтиПоТипу(Тип);
ТекстСпискаОбъектовКонфигурации = ТекстСпискаОбъектовКонфигурации + Символы.ПС + ОбъектМД.ПолноеИмя();
КонецЦикла;
Для Каждого ОбъектМД Из Метаданные.ВнешниеИсточникиДанных Цикл
Если ОбъектМД.РасширениеКонфигурации() <> Неопределено Тогда
Продолжить;
КонецЕсли;
ТекстСпискаОбъектовКонфигурации = ТекстСпискаОбъектовКонфигурации + Символы.ПС + ОбъектМД.ПолноеИмя();
КонецЦикла;
КонецЕсли;
Если ПодключитьОтладкуВнешнихОбработокБСП И ирКэш.НомерВерсииБСПЛкс() >= 204 Тогда
ТекстСпискаОбъектовКонфигурации = ТекстСпискаОбъектовКонфигурации + Символы.ПС + Метаданные.ОбщиеМодули.ДополнительныеОтчетыИОбработки.ПолноеИмя();
КонецЕсли;
ПодключитьОтладкуОтчетов = ПодключитьОтладкуОтчетов И Метаданные.ОсновнаяФормаОтчета <> Неопределено И Метаданные.ОсновнаяФормаОтчета.РасширениеКонфигурации() = Неопределено;
Если ПодключитьОтладкуОтчетов Тогда
ТекстСпискаОбъектовКонфигурации = ТекстСпискаОбъектовКонфигурации + Символы.ПС + Метаданные.ОсновнаяФормаОтчета.ПолноеИмя();
КонецЕсли;
ТекстСпискаОбъектовКонфигурации = Сред(ТекстСпискаОбъектовКонфигурации, 2); // !
ИмяФайлаСпискаВыгрузкиКонфигурации = ПолучитьИмяВременногоФайла("txt");
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ТекстСпискаОбъектовКонфигурации);
ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиКонфигурации);
КаталогВыгрузкиКонфигурации = ПолучитьИмяВременногоФайла();
СоздатьКаталог(КаталогВыгрузкиКонфигурации);
ТекстЛога = "";
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиКонфигурации + """ -listFile """ + ИмяФайлаСпискаВыгрузкиКонфигурации + """ -Format Plain",
СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка конфигурации в файлы",,,, ИмяПользователя, ПарольПользователя);
УдалитьФайлы(ИмяФайлаСпискаВыгрузкиКонфигурации);
Если Не Успех Тогда
УдалитьФайлы(КаталогВыгрузкиКонфигурации);
СообщитьЛкс(ТекстЛога);
Возврат Ложь;
КонецЕсли;
// Выгружаем объекты из расширения
КаталогВыгрузкиРасширения = ПолучитьИмяВременногоФайла();
ИмяФайлаСпискаВыгрузкиРасширения = ПолучитьИмяВременногоФайла("txt");
ТекстЛога = "";
СоздатьКаталог(КаталогВыгрузкиРасширения);
ТекстСпискаОбъектовРасширения = "Конфигурация." + ИмяРасширения;
Для Каждого КлючИЗначение Из ПометкиКоманд Цикл
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + "ОбщаяКоманда." + КлючИЗначение.Ключ;
КонецЦикла;
ТекстовыйДокумент.УстановитьТекст(ТекстСпискаОбъектовРасширения);
ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиРасширения);
// Пришлось отказаться от частичной загрузки из-за непонятной ошибки
// Файл - Configuration.xml: ошибка частичной загрузки - идентификатор 15dc941a-fd9f-4d00-bc7e-3ef077518def загружаемой конфигурации отличается от идентификатора b9c0a797-9739-4c3f-a665-796b3bf92d6a сохраненной конфигурации
//Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -listFile """ + ИмяФайлаСпискаВыгрузкиРасширения + """ -Format Plain",
// СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка расширения в файлы");
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -Format Plain",
СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка расширения в файлы",,,, ИмяПользователя, ПарольПользователя);
Если Не Успех Тогда
УдалитьФайлы(КаталогВыгрузкиРасширения);
СообщитьЛкс(ТекстЛога);
Возврат Ложь;
КонецЕсли;
// Добавим ссылочные объекты в расширение
ИмяФайла = КаталогВыгрузкиРасширения + "\Configuration.xml";
ОписаниеРасширения = Новый ТекстовыйДокумент;
ОписаниеРасширения.Прочитать(ИмяФайла);
ОписаниеРасширения = ОписаниеРасширения.ПолучитьТекст();
ДокументДОМ = ирОбщий.ПрочитатьФайлВДокументDOMЛкс(ИмяФайла);
УзелТиповСпискаОбъектов = ДокументДом.ПолучитьЭлементыПоИмени("ChildObjects");
УзелТиповСпискаОбъектов = УзелТиповСпискаОбъектов[0];
Если НадоДобавитьВсеСсылочныеМетаданнные Тогда
Если СгенерироватьРольВсеПрава Тогда
ТекстФайлаПрав = Новый ЗаписьXML;
ТекстФайлаПрав.УстановитьСтроку("");
ТекстФайлаПрав.ЗаписатьБезОбработки("
|
| true
| true
| false");
КонецЕсли;
ДобавленныеВнешниеИсточникиДанных = Новый Соответствие;
Для Каждого Тип Из ДобавляемыеТипы Цикл
ПолноеИмяМДXML = XMLТип(Тип).ИмяТипа;
Если Ложь
Или Найти(ПолноеИмяМДXML, "RoutePointRef.") > 0
Тогда
Продолжить;
КонецЕсли;
ЭтоТаблицаВИД = Найти(ПолноеИмяМДXML, "ExternalDataSourceTableRef.") > 0;
Если ЭтоТаблицаВИД Тогда
Фрагменты = СтрРазделитьЛкс(ПолноеИмяМДXML);
Фрагменты[0] = "ExternalDataSource";
Фрагменты.Вставить(2, "Table");
МассивТаблицВИД = ДобавленныеВнешниеИсточникиДанных[Фрагменты[1]];
Если МассивТаблицВИД = Неопределено Тогда
МассивТаблицВИД = Новый Массив;
ДобавленныеВнешниеИсточникиДанных.Вставить(Фрагменты[1], МассивТаблицВИД);
КонецЕсли;
ПолноеИмяМДXML = СтрСоединитьЛкс(Фрагменты, ".");
КонецЕсли;
ПолноеИмяМДXML = СтрЗаменить(ПолноеИмяМДXML, "Ref.", ".");
ПолноеИмяМДXML = СтрЗаменить(ПолноеИмяМДXML, "RecordSet.", ".");
// Добавим в описание конфигурации (Configuration.xml)
ОбъектМД = Метаданные.НайтиПоТипу(Тип);
Если Не ЭтоТаблицаВИД Тогда
ИмяКлассаМДXML = ПервыйФрагментЛкс(ПолноеИмяМДXML);
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + ОбъектМД.ПолноеИмя();
Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + ОбъектМД.Имя + "<") > 0 Тогда
Продолжить;
КонецЕсли;
УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML);
УзелОбъекта.ТекстовоеСодержимое = ОбъектМД.Имя;
УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта);
Иначе
МассивТаблицВИД.Добавить(ОбъектМД.Имя);
ИмяКлассаМДXML = "Table";
КонецЕсли;
// Укажем принадлежность объекта в его описании
ФайлИсточник = Новый Файл(КаталогВыгрузкиКонфигурации + "\" + ПолноеИмяМДXML + ".xml");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ФайлИсточник.Имя);
//ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя);
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "", "" + ИмяКлассаМДXML + ">", Ложь, Истина, Истина);
НаЧтоЗаменять =
"
| " + ирОбщий.ПоследнийФрагментЛкс(ФайлИсточник.ИмяБезРасширения) + "
| Adopted
|
|
| " + ИмяКлассаМДXML + ">";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМДXML + " uuid=", ">", Ложь, Истина, Истина);
НаЧтоЗаменять = "<" + ИмяКлассаМДXML + " uuid=""" + Новый УникальныйИдентификатор + """>";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ТекстовыйДокумент.УстановитьТекст(ТекстФайла);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
Если СгенерироватьРольВсеПрава Тогда
Если Истина
И Найти(ПолноеИмяМДXML, "Enum.") = 0
Тогда
// Даем права Просмотр и ПросмотрИстории
ТекстФайлаПрав.ЗаписатьБезОбработки("
| ");
КонецЕсли;
КонецЕсли;
КонецЦикла;
Для Каждого КлючИЗначение Из ДобавленныеВнешниеИсточникиДанных Цикл
ПолноеИмяМДXML = "ExternalDataSource." + КлючИЗначение.Ключ;
ИмяКлассаМДXML = ПервыйФрагментЛкс(ПолноеИмяМДXML);
// Добавим в описание конфигурации (Configuration.xml)
ОбъектМД = Метаданные.ВнешниеИсточникиДанных[КлючИЗначение.Ключ];
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + ОбъектМД.ПолноеИмя();
Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + ОбъектМД.Имя + "<") > 0 Тогда
Продолжить;
КонецЕсли;
УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML);
УзелОбъекта.ТекстовоеСодержимое = ОбъектМД.Имя;
УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта);
// Укажем принадлежность объекта в его описании
ФайлИсточник = Новый Файл(КаталогВыгрузкиКонфигурации + "\" + ПолноеИмяМДXML + ".xml");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ФайлИсточник.Имя);
//ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя);
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "", "" + ИмяКлассаМДXML + ">", Ложь, Истина, Истина);
НаЧтоЗаменять =
"
| " + ирОбщий.ПоследнийФрагментЛкс(ФайлИсточник.ИмяБезРасширения) + "
| Adopted
|
|
| " + ИмяКлассаМДXML + ">";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМДXML + " uuid=", ">", Ложь, Истина, Истина);
НаЧтоЗаменять = "<" + ИмяКлассаМДXML + " uuid=""" + Новый УникальныйИдентификатор + """>";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ДокументДомВИД = ирОбщий.ПрочитатьТекстВДокументDOMЛкс(ТекстФайла);
УзелТиповСпискаДочернихОбъектов = ДокументДомВИД.ПолучитьЭлементыПоИмени("ChildObjects");
УзелТиповСпискаДочернихОбъектов = УзелТиповСпискаДочернихОбъектов[0];
Для Каждого ИмяТаблицы Из КлючИЗначение.Значение Цикл
УзелОбъекта = ДокументДомВИД.СоздатьЭлемент("Table");
УзелОбъекта.ТекстовоеСодержимое = ИмяТаблицы;
УзелТиповСпискаДочернихОбъектов.ДобавитьДочерний(УзелОбъекта);
КонецЦикла;
ирОбщий.ЗаписатьДокументDOMВФайлЛкс(ДокументДомВИД, ФайлПриемник.ПолноеИмя);
КонецЦикла;
Если СгенерироватьРольВсеПрава Тогда
// Добавим в описание конфигурации (Configuration.xml)
ИмяКлассаМДXML = "Role";
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + "Роль.ирВсеПрава";
Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + "ирВсеПрава" + "<") = 0 Тогда
УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML);
УзелОбъекта.ТекстовоеСодержимое = "ирВсеПрава";
УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта);
КонецЕсли;
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + ".ирВсеПрава.xml");
ТекстФайла = "
|
|
|
| ирВсеПрава
|
|
| ru
| Все права (ИР)
|
|
| Сгенерирована инструментом ""Адаптация расширения"" для доступа на просмотр ко всем данным
|
|
|";
ТекстовыйДокумент.УстановитьТекст(ТекстФайла);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + ".ирВсеПрава.Rights.xml");
ТекстФайлаПрав.ЗаписатьБезОбработки("
|");
ТекстовыйДокумент.УстановитьТекст(ТекстФайлаПрав.Закрыть());
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
КонецЕсли;
КонецЕсли;
Если ПодключитьОтладкуВнешнихОбработокБСП И ирКэш.НомерВерсииБСПЛкс() >= 204 Тогда
ИмяОбъектаОригинала = "ДополнительныеОтчетыИОбработки";
ИмяОбъектаРасширения = "ирДополнительныеОтчетыИОбработкиБСП";
// Добавим в описание конфигурации (Configuration.xml)
ИмяКлассаМДXML = "CommonModule";
ОбъектМД = Метаданные.ОбщиеМодули[ИмяОбъектаОригинала];
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + ОбъектМД.ПолноеИмя();
Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + ОбъектМД.Имя + "<") = 0 Тогда
УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML);
УзелОбъекта.ТекстовоеСодержимое = ОбъектМД.Имя;
УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта);
// Укажем принадлежность объекта в его описании
ФайлИсточник = Новый Файл(КаталогВыгрузкиКонфигурации + "\" + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".xml");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ФайлИсточник.Имя);
//ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя);
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "", "" + ИмяКлассаМДXML + ">", Ложь, Истина, Истина);
НаЧтоЗаменять =
"
| " + ИмяОбъектаОригинала + "
| Adopted
|
| " + ИмяКлассаМДXML + ">";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМДXML + " uuid=", ">", Ложь, Истина, Истина);
НаЧтоЗаменять = "<" + ИмяКлассаМДXML + " uuid=""" + Новый УникальныйИдентификатор + """>";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ТекстовыйДокумент.УстановитьТекст(ТекстФайла);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
КонецЕсли;
ФайлИсточник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + "." + ИмяОбъектаРасширения + ".Module.txt");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".Module.txt");
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
КонецЕсли;
Если ПодключитьОтладкуОтчетов И Метаданные.ОсновнаяФормаОтчета <> Неопределено Тогда
ИмяОбъектаОригинала = Метаданные.ОсновнаяФормаОтчета.Имя;
ИмяОбъектаРасширения = Метаданные.ОбщиеФормы.ирФормаОтчетаРасширение.Имя;
// Добавим в описание конфигурации (Configuration.xml)
ИмяКлассаМДXML = "CommonForm";
ОбъектМД = Метаданные.ОбщиеФормы[ИмяОбъектаОригинала];
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + ОбъектМД.ПолноеИмя();
Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + ОбъектМД.Имя + "<") = 0 Тогда
УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML);
УзелОбъекта.ТекстовоеСодержимое = ОбъектМД.Имя;
УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта);
// Укажем принадлежность объекта в его описании
ФайлИсточник = Новый Файл(КаталогВыгрузкиКонфигурации + "\" + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".xml");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ФайлИсточник.Имя);
//ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя);
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "", "" + ИмяКлассаМДXML + ">", Ложь, Истина, Истина);
НаЧтоЗаменять =
"
| " + ИмяОбъектаОригинала + "
| Adopted
| Managed
|
| " + ИмяКлассаМДXML + ">";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМДXML + " uuid=", ">", Ложь, Истина, Истина);
НаЧтоЗаменять = "<" + ИмяКлассаМДXML + " uuid=""" + Новый УникальныйИдентификатор + """>";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ТекстовыйДокумент.УстановитьТекст(ТекстФайла);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
КонецЕсли;
// Модуль
ФайлИсточник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + "." + ИмяОбъектаРасширения + ".Form.Module.txt");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".Form.Module.txt");
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
// Диалог
ФайлИсточник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + "." + ИмяОбъектаРасширения + ".Form.xml");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".Form.xml");
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
ЧтоЗаменять = "";
НаЧтоЗаменять = "";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ЧтоЗаменять = "";
НаЧтоЗаменять = "";
ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять, Истина);
ТекстовыйДокумент.УстановитьТекст(ТекстФайла);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
КонецЕсли;
ирОбщий.ЗаписатьДокументDOMВФайлЛкс(ДокументДом, ИмяФайла);
// Добавим типы ссылочных объектов в общие команды
#Если Сервер И Не Сервер Тогда
ТипыСсылок = Новый ОписаниеТипов;
#КонецЕсли
Для Каждого КлючИЗначение Из ПометкиКоманд Цикл
ИмяКоманды = КлючИЗначение.Ключ;
ИмяФайла = КаталогВыгрузкиРасширения + "\CommonCommand." + ИмяКоманды + ".xml";
ДокументДОМ = ирОбщий.ПрочитатьФайлВДокументDOMЛкс(ИмяФайла);
УзелТиповПараметра = ДокументДом.ПолучитьЭлементыПоИмени("CommandParameterType");
УзелТиповПараметра = УзелТиповПараметра[0];
Пока УзелТиповПараметра.ДочерниеУзлы.Количество() > 0 Цикл
УзелТиповПараметра.УдалитьДочерний(УзелТиповПараметра.ПервыйДочерний);
КонецЦикла;
Если КлючИЗначение.Значение Тогда
Если ИмяКоманды = Метаданные.ОбщиеКоманды.ирРедактироватьИзмененияНаУзле.Имя Тогда
ТипыПараметра = ТипыСсылокПлановОбмена;
Иначе
ТипыПараметра = ТипыСсылок;
КонецЕсли;
Для Каждого Тип Из ТипыПараметра Цикл
УзелТипа = ДокументДом.СоздатьЭлемент("v8:Type"); // http://v8.1c.ru/8.1/data/core
УзелТипа.ТекстовоеСодержимое = "cfg:" + XMLТип(Тип).ИмяТипа; // http://v8.1c.ru/8.1/data/enterprise/current-config
УзелТиповПараметра.ДобавитьДочерний(УзелТипа);
КонецЦикла;
КонецЕсли;
ирОбщий.ЗаписатьДокументDOMВФайлЛкс(ДокументДом, ИмяФайла);
КонецЦикла;
ТекстЛога = "";
// Пришлось отказаться от частичной загрузки из-за непонятной ошибки
// Файл - Configuration.xml: ошибка частичной загрузки - идентификатор 15dc941a-fd9f-4d00-bc7e-3ef077518def загружаемой конфигурации отличается от идентификатора b9c0a797-9739-4c3f-a665-796b3bf92d6a сохраненной конфигурации
//ФайлыДляЗагрузки = НайтиФайлы(КаталогВыгрузкиРасширения, "*");
//ТекстовыйДокумент.Очистить();
//Для Каждого Файл Из ФайлыДляЗагрузки Цикл
// ТекстовыйДокумент.ДобавитьСтроку(Файл.ПолноеИмя);
//КонецЦикла;
//ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиРасширения);
//Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadConfigFromFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -listFile """ + ИмяФайлаСпискаВыгрузкиРасширения + """ -Format Plain",
// СтрокаСоединенияИнформационнойБазы(), ТекстЛога,,, "Загрузка расширения из файлов");
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadConfigFromFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -Format Plain",
СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Загрузка расширения из файлов",,,, ИмяПользователя, ПарольПользователя);
УдалитьФайлы(КаталогВыгрузкиРасширения);
Если Не Успех Тогда
СообщитьЛкс(ТекстЛога);
Возврат Ложь;
КонецЕсли;
// Почему то без этого расширение не применялось (оставалась активной кнопка "Обновить конфигурацию БД"
//ЭтотРасширение.Записать();
КонечныйФайл = ПолучитьИмяВременногоФайла();
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpCfg """ + КонечныйФайл + """ -Extension """ + ИмяРасширения + """", СтрокаСоединенияИнформационнойБазы(), ТекстЛога,,,,,, ИмяПользователя, ПарольПользователя);
Если Не Успех Тогда
СообщитьЛкс(ТекстЛога);
Возврат Ложь;
КонецЕсли;
ЭтотРасширение.Записать(Новый ДвоичныеДанные(КонечныйФайл));
Возврат Истина;
КонецФункции
Функция ПредставлениеКлючаСтрокиБДЛкс(Знач КлючСтроки, ПолучатьПредставленияСсылок = Истина) Экспорт
Если ЛиКлючЗаписиРегистраЛкс(КлючСтроки) Тогда
ПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(КлючСтроки)).ПолноеИмя();
СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяМД, , Ложь, Ложь);
ПредставленияКлюча = "";
Для Каждого ЭлементСписка Из СтруктураКлюча Цикл
Если ПредставленияКлюча <> "" Тогда
ПредставленияКлюча = ПредставленияКлюча + ", ";
КонецЕсли;
ПредставлениеЗначения = КлючСтроки[ЭлементСписка.Представление];
Если Не ПолучатьПредставленияСсылок И ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ПредставлениеЗначения) Тогда
ПредставлениеЗначения = "" + ИдентификаторСсылкиЛкс(ПредставлениеЗначения);
Иначе
ПредставлениеЗначения = "" + ПредставлениеЗначения;
КонецЕсли;
ПредставленияКлюча = ПредставленияКлюча + ЭлементСписка.Представление + " = " + ПредставлениеЗначения;
КонецЦикла;
Иначе
ПредставленияКлюча = "" + КлючСтроки;
//СтруктураЧтения = Новый Структура("Владелец");
//Попытка
// ЗаполнитьЗначенияСвойств(СтруктураЧтения, КлючСтроки);
//Исключение
// // Нет доступа
//КонецПопытки;
//Если ЗначениеЗаполнено(СтруктураЧтения.Владелец) Тогда
// Если ПолучатьПредставленияСсылок Тогда
// Владелец = Владелец.УникальныйИдентификатор();
// КонецЕсли;
// ПредставленияКлюча = "[" + ПредставлениеКлючаСтрокиБДЛкс(Владелец) + "]" + ПредставленияКлюча;
//КонецЕсли;
КонецЕсли;
Возврат ПредставленияКлюча;
КонецФункции
Функция ПеременныеОкруженияПроцессаЛкс()
Shell = Новый COMОбъект("WScript.Shell");
ПеременныеОкружения = Shell.Environment("PROCESS");
Возврат ПеременныеОкружения;
КонецФункции
Процедура ПроверитьСоздатьКаталогПередСозданиемФайлаЛкс(Знач ИмяКонфигурационногоФайла) Экспорт
Файл = Новый Файл(ИмяКонфигурационногоФайла);
ФайлКаталога = Новый Файл(Файл.Путь);
Если Не ФайлКаталога.Существует() Тогда
СоздатьКаталог(ФайлКаталога.ПолноеИмя);
КонецЕсли;
КонецПроцедуры
Функция КаталогПрограммныхФайловОСЛкс(x64 = Ложь) Экспорт
ПеременныеОкружения = ПеременныеОкруженияПроцессаЛкс();
Если ирКэш.Это64битнаяОСЛкс() Тогда
Если x64 Тогда
ИмяПеременной = "ProgramW6432";
Иначе
ИмяПеременной = "ProgramFiles(x86)";
КонецЕсли;
Иначе
ИмяПеременной = "ProgramFiles";
КонецЕсли;
КаталогПрограммныхФайлов = ПеременныеОкружения.Item(ИмяПеременной);
Возврат КаталогПрограммныхФайлов;
КонецФункции
Функция КаталогПеремещаемыхДанныхПриложенийЛкс() Экспорт
ПеременныеОкружения = ПеременныеОкруженияПроцессаЛкс();
КаталогПеремещаемыхДанныхПриложений = ПеременныеОкружения.Item("Appdata");
Возврат КаталогПеремещаемыхДанныхПриложений;
КонецФункции
Функция ПараметрыСоединенияADOЭтойБДЛкс(выхСтрокаСвойств = "") Экспорт
выхСтрокаСвойств = "ИмяСервера, ИмяБД, ИмяПользователя, Пароль, НаСервере";
Результат = Новый Структура(выхСтрокаСвойств);
Результат.ИмяСервера = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.ИмяСервера");
Результат.ИмяБД = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.ИмяБД");
Результат.ИмяПользователя = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.ИмяПользователя");
НовыйПароль = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.Пароль");
Если НовыйПароль <> Неопределено Тогда
Результат.Пароль = НовыйПароль.Получить();
КонецЕсли;
Результат.НаСервере = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.НаСервере");
Возврат Результат;
КонецФункции
Функция ПроверитьСоединениеADOЭтойБДЛкс(Знач ИмяСервера = "", Знач ИмяБД = "", Знач ИмяПользователя = "", Знач Пароль = "", Знач НаСервере = Неопределено, ЗапрашиватьПараметрыПодключения = Истина,
Асинхронно = Ложь) Экспорт
КоличествоПопыток = 1;
НачальнаяПопытка = 1;
Если ЗапрашиватьПараметрыПодключения Тогда
КоличествоПопыток = 2;
Если Не ЗначениеЗаполнено(ИмяСервера) Тогда
ПараметрыСоединения = ПараметрыСоединенияADOЭтойБДЛкс();
Если Не ЗначениеЗаполнено(ПараметрыСоединения.ИмяСервера) Тогда
НачальнаяПопытка = 2;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Для НомерПопытки = НачальнаяПопытка По КоличествоПопыток Цикл
Если НомерПопытки = 2 Тогда
#Если Клиент Тогда
ФормаПодключения = ОткрытьФормуСоединенияСУБДЛкс(Истина);
Если ФормаПодключения = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Если НаСервере = Неопределено Тогда
НаСервере = ФормаПодключения.НаСервере;
КонецЕсли;
#Иначе
СообщитьЛкс("Необходимо с клиента выполнить проверку установки соединения с СУБД");
Возврат Ложь;
#КонецЕсли
Иначе
Если НаСервере = Неопределено Тогда
Если ПараметрыСоединения = Неопределено Тогда
ПараметрыСоединения = ПараметрыСоединенияADOЭтойБДЛкс();
КонецЕсли;
НаСервере = ПараметрыСоединения.НаСервере;
КонецЕсли;
КонецЕсли;
Если НомерПопытки = 2 И Не ЗначениеЗаполнено(ИмяСервера) Тогда
ЛиСоединениеУстановлено = Ложь;
ИначеЕсли НаСервере = Истина Тогда
ЛиСоединениеУстановлено = ирСервер.ПроверитьСоединениеADOЭтойБДЛкс(ИмяСервера, ИмяБД, ИмяПользователя, Пароль, Асинхронно);
Иначе
Соединение = ПолучитьСоединениеСУБД(ИмяСервера, ИмяБД, ИмяПользователя, Пароль, Асинхронно);
ЛиСоединениеУстановлено = Соединение <> Неопределено;
КонецЕсли;
Если ЛиСоединениеУстановлено Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Возврат ЛиСоединениеУстановлено;
КонецФункции
Функция ВыполнитьЗапросКЭтойБазеЧерезADOЛкс(Знач ТекстЗапроса, Знач РежимОтладки = Ложь, Знач ПредставлениеЗапроса = "", Знач СмещениеГода = 2000, Знач ИспользованиеGWF = Истина,
Знач НаСервере = Неопределено, СоединениеADO = Неопределено) Экспорт
Если РежимОтладки Тогда
ирОбщий.ОткрытьЗапросСУБДЛкс(ТекстЗапроса, ПредставлениеЗапроса);
Возврат Неопределено;
КонецЕсли;
#Если Клиент Тогда
Если НаСервере = Неопределено Тогда
НаСервере = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.НаСервере");
КонецЕсли;
#КонецЕсли
Если НаСервере = Истина Тогда
Таблица = ирСервер.ВыполнитьЗапросКЭтойБазеЧерезADOЛкс(ТекстЗапроса, СмещениеГода, ИспользованиеGWF);
Иначе
Если СоединениеADO = Неопределено Тогда
СоединениеADO = ПолучитьСоединениеСУБД();
Если СоединениеADO = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
//КомандаADO = Новый COMОбъект("ADODB.Command");
//КомандаADO.CommandTimeout = 30; // секунд
//КомандаADO.CommandText = ТекстЗапроса;
//КомандаADO.CommandType = 1;
//КомандаADO.ActiveConnection = мСоединениеADO;
//Если РежимОтладки = 1 Тогда
// ирОбщий.ОтладитьЛкс(КомандаADO);
// Возврат Неопределено;
//КонецЕсли;
//РезультатЗапроса = КомандаADO.Execute();
РезультатЗапроса = Новый COMОбъект("ADODB.Recordset");
adOpenStatic = 3;
adLockOptimistic = 3;
adCmdText = 1;
РезультатЗапроса.Open(ТекстЗапроса, СоединениеADO, adOpenStatic, adLockOptimistic, adCmdText);
Таблица = ирОбщий.РезультатЗапросаADOВТаблицуЗначенийОбщийЛкс(РезультатЗапроса, , , , СмещениеГода, ИспользованиеGWF);
КонецЕсли;
Возврат Таблица;
КонецФункции
//Функция получает на вход текст html, из которого создает COM объект HtmlFile
//Параметры
// ТекстHtml - Строка. Текст в формате HTML
// ПереопределятьБазу - используется только при УстановитьБазу = Истина
//Возвращаемое значение
//COM объект с типом HtmlFile
Функция ПолучитьHtmlFileИзТекстаHtmlЛкс(ТекстHtml = "", Результат = Неопределено) Экспорт
Если Результат = Неопределено Тогда
Результат = Новый COMОбъект("HtmlFile");
КонецЕсли;
Результат.open("text/html");
Результат.write(ТекстHtml);
Результат.close();
Возврат Результат;
КонецФункции
Функция ПолучитьHtmlТекстВыделенияЛкс(ДокументHtml) Экспорт
Результат = "";
Если ДокументHtml.getSelection() <> Неопределено Тогда
Выделение = ДокументHtml.getSelection();
Если Выделение.rangeCount > 0 Тогда
ЭлементDiv = ДокументHtml.createElement("div");
Для Счетчик = 0 по Выделение.rangeCount - 1 Цикл
ЭлементDiv.appendChild(Выделение.getRangeAt(Счетчик).cloneContents());
КонецЦикла;
Результат = ЭлементDiv.innerHTML;
КонецЕсли;
ИначеЕсли ДокументHtml.selection <> Неопределено Тогда
//Если ДокументHtml.selection.type = "Text" Тогда
// Результат = ДокументHtml.selection.createRange().htmlText;
//КонецЕсли;
Результат = ДокументHtml.selection.CreateRange().htmlText;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОбработатьПорциюСтрокТаблицыЛкс(АдресТаблицыЗначений, НачальныйНомерСтроки, РазмерПорции, МодальныйРежим = Ложь, ПропускатьОшибки = Ложь, ТекстАлгоритма, ПараметраАлгоритмы = Неопределено, ПерейтиНаСервер = Ложь) Экспорт
Если ПерейтиНаСервер Тогда
ирСервер.ОбработатьПорциюСтрокТаблицыЛкс(АдресТаблицыЗначений, НачальныйНомерСтроки, РазмерПорции, МодальныйРежим, ПропускатьОшибки, ТекстАлгоритма, ПараметраАлгоритмы);
Возврат Неопределено;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
ТаблицаЗначений = ПолучитьИзВременногоХранилища(АдресТаблицыЗначений);
КоличествоСтрокТаблицы = ТаблицаЗначений.Количество();
Для НомерСтроки = НачальныйНомерСтроки По Мин(НачальныйНомерСтроки + РазмерПорции - 1, ТаблицаЗначений.Количество()) Цикл
СтрокаТаблицы = ТаблицаЗначений[НомерСтроки - 1];
Попытка
ирОбщий.ВыполнитьАлгоритм(ТекстАлгоритма,,, ПараметраАлгоритмы, СтрокаТаблицы, НомерСтроки = 1, НомерСтроки = КоличествоСтрокТаблицы);
Исключение
Если Не ПропускатьОшибки Тогда
ВызватьИсключение
КонецЕсли;
ирОбщий.СообщитьСУчетомМодальностиЛкс("Строка результата №" + НомерСтроки + ": " + ОписаниеОшибки(), МодальныйРежим);
КонецПопытки;
КонецЦикла;
КонецФункции
Процедура ПаузаЛкс(ЧислоСекунд) Экспорт
Попытка
ВК = ирКэш.ВКОбщаяЛкс();
ВК.Sleep(ЧислоСекунд * 1000);
Исключение
// Антибаг платформы 8.3 https://www.hostedredmine.com/issues/889213
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
Процедура ПаузаМиллисекундЛкс(Число) Экспорт
Попытка
ВК = ирКэш.ВКОбщаяЛкс();
ВК.Sleep(Число);
Исключение
// Антибаг платформы 8.3 https://www.hostedredmine.com/issues/889213
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
Функция СеансКонфигуратора() Экспорт
Сеансы = ПолучитьСеансыИнформационнойБазы();
Для Каждого Сеанс Из Сеансы Цикл
Если СтрокиРавныЛкс(Сеанс.ИмяПриложения, "Designer") Тогда
Возврат Сеанс;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Функция ПростойРезультатЗапросаЛкс(ТекстЗапроса, АдресХранилища = Неопределено) Экспорт
Если ЗначениеЗаполнено(ТекстЗапроса) Тогда
ЗапросКоличестваСтрок = Новый Запрос(ТекстЗапроса);
Результат = ЗапросКоличестваСтрок.Выполнить().Выгрузить()[0][0];
Иначе
Результат = 0;
КонецЕсли;
Если ЗначениеЗаполнено(АдресХранилища) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресХранилища);
КонецЕсли;
КонецФункции
Функция КоличествоСтрокВТаблицеБДЛкс(ПолноеИмяМД, АдресВременногоХранилища = "") Экспорт
Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда
Возврат "";
КонецЕсли;
ЗапросКоличестваСтрок = Новый Запрос("ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ " + ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД));
Попытка
КоличествоСтрок = ЗапросКоличестваСтрок.Выполнить().Выгрузить()[0][0];
Исключение
КоличествоСтрок = Неопределено;
КонецПопытки;
Если ЗначениеЗаполнено(АдресВременногоХранилища) Тогда
ПоместитьВоВременноеХранилище(КоличествоСтрок, АдресВременногоХранилища);
КонецЕсли;
Возврат КоличествоСтрок;
КонецФункции
Процедура ВыделитьПервыеСтрокиДинамическогоСпискаЛкс(Знач ТабличноеПоле, Знач Количество, Знач НастройкиСписка = Неопределено) Экспорт
ДинамическийСписок = ирОбщий.ДанныеЭлементаФормыЛкс(ТабличноеПоле);
ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле);
СхемаКомпоновки = ирОбщий.ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицы,,,,,,, Количество);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
Если НастройкиСписка = Неопределено Тогда
НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДинамическийСписок);
КонецЕсли;
ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, НастройкиСписка.Отбор);
ирОбщий.СкопироватьПорядокЛюбойЛкс(НастройкаКомпоновки.Порядок, НастройкиСписка.Порядок);
СтруктураКлюча = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы,, Ложь);
Для Каждого ЭлементСписка Из СтруктураКлюча Цикл
ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ЭлементСписка.Представление);
КонецЦикла;
КлючиСтрок = ирОбщий.СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки);
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КлючиСтрок.Количество(), "Выделение");
Для Каждого КлючСтроки Из КлючиСтрок Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
ВыделенныеСтроки.Добавить(ирОбщий.КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, КлючСтроки));
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Если КлючиСтрок.Количество() <> Количество Тогда
СообщитьЛкс("Выделены все отобранные элементы, но меньшим количеством " + XMLСтрока(КлючиСтрок.Количество()));
КонецЕсли;
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
ТабличноеПоле.ОбновитьСтроки();
КонецЕсли;
КонецПроцедуры
// Если в текущей строке не достаточно полей для заполнения ключа записи регистра, то всегда возвращается набор записей, не смотря на параметр ДляРегистровСоздатьНаборЗаписей.
// Параметры:
// СтруктураКлюча - Структура - для ускорения в циклах;
// ОбъектМД - ОбъектМетаданных - для ускорения в циклах;
Функция КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, Знач ТекущаяСтрока, ДляПодчиненногоРегистраСведенийНомерСтроки = Ложь, выхСтруктураЛокальногоКлючаСтроки = Неопределено,
ОбъектыНаСервере = Неопределено, СтруктураКлюча = Неопределено, ОбъектМД = Неопределено) Экспорт
ИмяПоляСсылка = ирОбщий.ПеревестиСтроку("Ссылка");
ИмяПоляНомерСтроки = ирОбщий.ПеревестиСтроку("НомерСтроки");
ИмяПоляПериод = ирОбщий.ПеревестиСтроку("Период");
ТипТаблицы = ТипТаблицыБДЛкс(ПолноеИмяТаблицы);
Если СтруктураКлюча = Неопределено Тогда
СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы,,, ДляПодчиненногоРегистраСведенийНомерСтроки);
КонецЕсли;
#Если Сервер И Не Сервер Тогда
СтруктураКлюча = Новый Структура;
#КонецЕсли
Если СтруктураКлюча.Свойство(ИмяПоляНомерСтроки) Тогда
выхСтруктураЛокальногоКлючаСтроки = Новый Структура(ИмяПоляНомерСтроки);
ИначеЕсли СтруктураКлюча.Свойство(ИмяПоляПериод) Тогда
выхСтруктураЛокальногоКлючаСтроки = Новый Структура(ИмяПоляПериод);
Иначе
выхСтруктураЛокальногоКлючаСтроки = Неопределено;
КонецЕсли;
Если выхСтруктураЛокальногоКлючаСтроки <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(выхСтруктураЛокальногоКлючаСтроки, ТекущаяСтрока);
КонецЕсли;
ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы);
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.ВнешниеИсточникиДанных.ВнешнийИсточникДанных1.Таблицы.Таблица1;
#КонецЕсли
Если Ложь
Или ирОбщий.ЛиМетаданныеСсылочногоОбъектаЛкс(ОбъектМД)
Или ЛиКорневойТипЖурналаДокументовЛкс(ТипТаблицы)
Тогда
Если ирОбщий.ЛиТипСсылкиБДЛкс(ТипЗнч(ТекущаяСтрока), Ложь) Тогда
КлючОбъекта = ТекущаяСтрока;
Иначе
КлючОбъекта = ТекущаяСтрока[ИмяПоляСсылка];
КонецЕсли;
ПолноеИмяТаблицы = Метаданные.НайтиПоТипу(ТипЗнч(КлючОбъекта)).ПолноеИмя();
ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
КлючОбъекта = ТекущаяСтрока[ИмяПоляСсылка];
ИначеЕсли ирОбщий.ЛиМетаданныеРегистраЛкс(ОбъектМД, Ложь) Тогда
Если Не ДляПодчиненногоРегистраСведенийНомерСтроки Тогда
НайденыВсеПоляКлючаЗаписи = Истина;
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
Попытка
Пустышка = ТекущаяСтрока[КлючИЗначение.Ключ];
Исключение
НайденыВсеПоляКлючаЗаписи = Ложь;
Прервать;
КонецПопытки;
КонецЦикла;
КонецЕсли;
ЗаполнитьЗначенияСвойств(СтруктураКлюча, ТекущаяСтрока);
Если Ложь
Или ДляПодчиненногоРегистраСведенийНомерСтроки
Или Не НайденыВсеПоляКлючаЗаписи
Тогда
//КлючОбъекта = ПолучитьНаборЗаписейПоКлючуЛкс(ПолноеИмяТаблицы, ТекущаяСтрока);
УдаляемыеКлючи = Новый Массив;
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
Если ТипЗнч(КлючИЗначение.Значение) = Тип("ОписаниеТипов") Тогда
УдаляемыеКлючи.Добавить(КлючИЗначение.Ключ);
КонецЕсли;
КонецЦикла;
Для Каждого УдаляемыйКлюч Из УдаляемыеКлючи Цикл
СтруктураКлюча.Удалить(УдаляемыйКлюч);
КонецЦикла;
КлючОбъекта = ОбъектБДПоКлючуЛкс(ПолноеИмяТаблицы, СтруктураКлюча,, Ложь, ОбъектыНаСервере);
Иначе
Если ОбъектМД = Неопределено Тогда
ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы);
КонецЕсли;
МенеджерРегистра = Новый (ИмяТипаИзПолногоИмениМДЛкс(ОбъектМД.ПолноеИмя(), "Менеджер"));
КлючОбъекта = МенеджерРегистра.СоздатьКлючЗаписи(СтруктураКлюча);
КонецЕсли;
ИначеЕсли ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы) Тогда
ЗаполнитьЗначенияСвойств(СтруктураКлюча, ТекущаяСтрока);
КлючОбъекта = Новый Структура("ПолноеИмяТаблицы, Структура", ПолноеИмяТаблицы, СтруктураКлюча);
Иначе
КлючОбъекта = Неопределено;
КонецЕсли;
Возврат КлючОбъекта;
КонецФункции
Функция СообщенияПользователюОтФоновогоЗаданияЛкс(Знач ФоновоеЗадание, УдалятьПолученные = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ФоновоеЗадание = ФоновыеЗадания.Выполнить();
#КонецЕсли
СообщенияПользователю = ФоновоеЗадание.ПолучитьСообщенияПользователю(УдалятьПолученные);
// Антибаг платформы 8.2.14
Если СообщенияПользователю = Неопределено Тогда
СообщенияПользователю = Новый Массив;
КонецЕсли;
Возврат СообщенияПользователю;
КонецФункции
Функция СоединитьСообщенияПользователюЛкс(Знач СообщенияОбъекта) Экспорт
СообщенияОбработки = Новый ЗаписьXML;
СообщенияОбработки.УстановитьСтроку("");
Для Каждого СообщениеОбъекта Из СообщенияОбъекта Цикл
#Если Сервер И Не Сервер Тогда
СообщениеОбъекта = Новый СообщениеПользователю;
#КонецЕсли
СообщенияОбработки.ЗаписатьБезОбработки(СообщениеОбъекта.Текст + Символы.ПС);
КонецЦикла;
ТекстСообщений = СообщенияОбработки.Закрыть();
Возврат ТекстСообщений;
КонецФункции
Функция ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание, ЭтаФорма = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору();
#КонецЕсли
ИдентификаторФоновогоЗадания = ФоновоеЗадание.УникальныйИдентификатор;
#Если Клиент Тогда
ПодключитьГлобальныйОбработчикОжиданияСПараметрамиЛкс("ОтменитьФоновоеЗаданиеОтложенноЛкс", Новый Структура("ИдентификаторФоновогоЗадания", ИдентификаторФоновогоЗадания));
СостояниеЛкс("Выполняем фоновое задание", Истина);
#КонецЕсли
Пока Истина Цикл
#Если Клиент Тогда
ОбработкаПрерыванияПользователя();
#КонецЕсли
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторФоновогоЗадания);
ОбработатьСообщенияФоновогоЗаданияЛкс(ФоновоеЗадание);
Если ФоновоеЗадание.Состояние <> СостояниеФоновогоЗадания.Активно Тогда
Прервать;
КонецЕсли;
ПаузаМиллисекундЛкс(100);
КонецЦикла;
#Если Клиент Тогда
ОтлючитьГлобальныйОбработчикОжиданияСПараметрамиЛкс();
#КонецЕсли
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда
ИнформацияОбОшибке = ФоновоеЗадание.ИнформацияОбОшибке;
ТекстСообщения = "Фоновое задание завершено аварийно! Описание ошибки получить не удалось";
#Если Клиент Тогда
Если ИнформацияОбОшибке <> Неопределено Тогда
ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке);
Иначе
СообщитьЛкс(ТекстСообщения, СтатусСообщения.Внимание);
КонецЕсли;
#Иначе
Если ИнформацияОбОшибке <> Неопределено Тогда
ВызватьИсключение ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
Иначе
ВызватьИсключение ТекстСообщения;
КонецЕсли;
#КонецЕсли
Результат = Ложь;
Иначе
Результат = Истина;
КонецЕсли;
Возврат Результат;
КонецФункции
// Функция - Обработать сообщения фонового задания лкс
//
// Параметры:
// ФоновоеЗадание - -
//
// Возвращаемое значение:
// - Булево - был ли изменен текст состояния
//
Функция ОбработатьСообщенияФоновогоЗаданияЛкс(Знач ФоновоеЗадание, ФормаЗадания = Неопределено, Открывать = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору();
#КонецЕсли
Результат = Ложь;
СообщенияПользователю = СообщенияПользователюОтФоновогоЗаданияЛкс(ФоновоеЗадание, Истина);
Если СообщенияПользователю <> Неопределено Тогда
ТекстСостояния = "";
Для Каждого СообщениеПользователю Из СообщенияПользователю Цикл
#Если Сервер И Не Сервер Тогда
СообщениеПользователю = Новый СообщениеПользователю;
#КонецЕсли
МассивИндикаторов = Неопределено;
Если Найти(СообщениеПользователю.Текст, "#Индикатор-") = 1 Тогда
МассивИндикаторов = ЗначениеИзСтрокиВнутр(ирОбщий.СтрокаМеждуМаркерамиЛкс(СообщениеПользователю.Текст, "#Индикатор-"));
КонецЕсли;
Если МассивИндикаторов = Неопределено Тогда
Если ФормаЗадания <> Неопределено Тогда
ТекстовыйДокумент = ФормаЗадания.ЭлементыФормы.ПолеТекста;
ТекстовыйДокумент.ДобавитьСтроку(СообщениеПользователю.Текст);
НомерСтроки = Макс(1, ТекстовыйДокумент.КоличествоСтрок()); // https://www.hostedredmine.com/issues/891268
ТекстовыйДокумент.УстановитьГраницыВыделения(НомерСтроки, 1, НомерСтроки, 1);
Иначе
СообщитьЛкс(СообщениеПользователю.Текст,, Истина);
СообщениеПользователю.Сообщить();
КонецЕсли;
Иначе
Индикатор = ОбновитьТекстСостоянияВсехИндикаторовЛкс(МассивИндикаторов);
ТекстСостояния = Индикатор.ТекстСостояния;
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
Если ЗначениеЗаполнено(ТекстСостояния) Тогда
Если ФормаЗадания <> Неопределено Тогда
ФормаЗадания.Заголовок = ТекстСостояния;
Если Открывать И Не ФормаЗадания.Открыта() Тогда
ФормаЗадания.Открыть();
КонецЕсли;
Иначе
СостояниеЛкс(ТекстСостояния, Истина);
КонецЕсли;
Результат = Истина;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПоместитьПереданныйКэшВоВременноеХранищеЛкс(Знач ОбщиеПараметрыОбработки)
#Если Сервер И Не Сервер Тогда
ОбщиеПараметрыОбработки = Новый Структура;
#КонецЕсли
Если ОбщиеПараметрыОбработки.Свойство("Кэш") Тогда
ирКэш.ПараметрыСеансаЛкс().ПереданныйКэш = ПоместитьВоВременноеХранилище(ОбщиеПараметрыОбработки.Кэш, Новый УникальныйИдентификатор);
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьПереданныйКэшВСтруктуруЛкс(Знач Структура)
#Если Сервер И Не Сервер Тогда
Структура = Новый Структура;
#КонецЕсли
ТаблицаВсехТаблицБД = ирОбщий.ТаблицаВсехТаблицБДБезОжиданияЛкс();
Если ТаблицаВсехТаблицБД <> Неопределено Тогда
Структура.Вставить("Кэш", Новый Структура("ТаблицаВсехТаблицБД", ТаблицаВсехТаблицБД));
КонецЕсли;
КонецПроцедуры
////////////////////////////////////////////////
// Многопоточность
Функция НоваяСтруктураМногопоточнойОбработкиЛкс(Знач ИмяОбработчикаОбъекта, Знач МодульОбработчика, Знач ИмяОбработчикаРезультатаОбъекта, Знач КоличествоОбъектовВПорции,
Знач ВыполнятьНаСервере, Знач КоличествоПотоков, Знач ОбщиеПараметрыОбработкиОдногоОбъекта = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
МодульОбработчика = Обработки.ирПодборИОбработкаОбъектов.Создать();
#КонецЕсли
ПотокиОбработки = Новый ТаблицаЗначений;
ПотокиОбработки.Колонки.Добавить("АдресРезультата");
ПотокиОбработки.Колонки.Добавить("СтрокиРезультатовОбъектов");
ПотокиОбработки.Колонки.Добавить("УникальныйИдентификатор");
ДоступностьМногопоточности = ВыполнятьНаСервере И Не ирКэш.ЭтоФайловаяБазаЛкс() И Не ирКэш.ЛиПортативныйРежимЛкс();
Для Счетчик = 1 По КоличествоПотоков Цикл
Если Счетчик > 1 И Не ДоступностьМногопоточности Тогда
Прервать;
КонецЕсли;
ПотокиОбработки.Добавить();
КонецЦикла;
Если ОбщиеПараметрыОбработкиОдногоОбъекта = Неопределено Тогда
ОбщиеПараметрыОбработкиОдногоОбъекта = Новый Структура();
Для Каждого МетаРеквизит Из МодульОбработчика.Метаданные().Реквизиты Цикл
ЗначениеРеквизита = МодульОбработчика[МетаРеквизит.Имя];
Если Ложь
Или ТипЗнч(ЗначениеРеквизита) = Тип("Строка")
Или ТипЗнч(ЗначениеРеквизита) = Тип("Булево")
Или ТипЗнч(ЗначениеРеквизита) = Тип("Дата")
Или ТипЗнч(ЗначениеРеквизита) = Тип("Число")
Тогда
ОбщиеПараметрыОбработкиОдногоОбъекта.Вставить(МетаРеквизит.Имя, ЗначениеРеквизита);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Статистика = Новый ТаблицаЗначений;
Статистика.Колонки.Добавить("Длительность");
СтруктураПотоков = Новый Структура;
СтруктураПотоков.Вставить("ПорцияОбъектов", Неопределено);
СтруктураПотоков.Вставить("ПотокиОбработки", ПотокиОбработки);
СтруктураПотоков.Вставить("Статистика", Статистика);
СтруктураПотоков.Вставить("ФактическоеКоличествоПотоков", ПотокиОбработки.Количество());
СтруктураПотоков.Вставить("КоличествоОбъектовВПорции", КоличествоОбъектовВПорции);
СтруктураПотоков.Вставить("МодульОбработчика", МодульОбработчика);
СтруктураПотоков.Вставить("ОбщиеПараметрыОбработкиОдногоОбъекта", ОбщиеПараметрыОбработкиОдногоОбъекта);
СтруктураПотоков.Вставить("ИмяОбработчикаРезультатаОбъекта", ИмяОбработчикаРезультатаОбъекта);
СтруктураПотоков.Вставить("ИмяОбработчикаОбъекта", ИмяОбработчикаОбъекта);
Возврат СтруктураПотоков;
КонецФункции
Процедура ДобавитьОбъектВОчередьМногопоточнойОбработкиЛкс(СтруктураПотоков, ПараметрыОбработкиОбъекта, СтрокиРезультатовОбъекта = Неопределено) Экспорт
МодульОбработчика = СтруктураПотоков.МодульОбработчика;
Если СтруктураПотоков.ФактическоеКоличествоПотоков = 1 Тогда
РезультатОбработки = Вычислить("МодульОбработчика." + СтруктураПотоков.ИмяОбработчикаОбъекта + "(ПараметрыОбработкиОбъекта)");
Выполнить("МодульОбработчика." + СтруктураПотоков.ИмяОбработчикаРезультатаОбъекта + "(РезультатОбработки, СтрокиРезультатовОбъекта)");
Возврат;
КонецЕсли;
ПорцияОбъектов = СтруктураПотоков.ПорцияОбъектов;
Если ПорцияОбъектов = Неопределено Тогда
ПорцияОбъектов = Новый Структура("ПараметрыОбработкиОбъектов, СтрокиРезультатовОбъектов", Новый Массив, Новый Массив);
СтруктураПотоков.ПорцияОбъектов = ПорцияОбъектов;
КонецЕсли;
ПорцияОбъектов.ПараметрыОбработкиОбъектов.Добавить(ПараметрыОбработкиОбъекта);
ПорцияОбъектов.СтрокиРезультатовОбъектов.Добавить(СтрокиРезультатовОбъекта);
Если ПорцияОбъектов.ПараметрыОбработкиОбъектов.Количество() < СтруктураПотоков.КоличествоОбъектовВПорции Тогда
Возврат;
КонецЕсли;
ЗапуститьПотокОбработкиПорцииЛкс(СтруктураПотоков);
КонецПроцедуры
Процедура ОжидатьЗавершенияВсехПотоковОбработкиЛкс(СтруктураПотоков) Экспорт
Если СтруктураПотоков.ПорцияОбъектов <> Неопределено Тогда
ЗапуститьПотокОбработкиПорцииЛкс(СтруктураПотоков);
КонецЕсли;
Пока ОбновитьПотокиОбработкиОбъектовЛкс(СтруктураПотоков, Ложь).Количество() < СтруктураПотоков.ПотокиОбработки.Количество() Цикл
ПаузаМиллисекундЛкс(10);
КонецЦикла;
Если СтруктураПотоков.ПотокиОбработки.Количество() > 1 Тогда
СообщитьСтатистикуПорцийСРекомендациями(СтруктураПотоков, Истина);
КонецЕсли;
КонецПроцедуры
Процедура СообщитьСтатистикуПорцийСРекомендациями(Знач СтруктураПотоков, ВыводитьСтатистикуОбязательно = Ложь)
Статистика = СтруктураПотоков.Статистика;
СредняяДлительностьПорции = Окр(Статистика.Итог("Длительность") / Статистика.Количество(), 1);
ТекстСообщения = "Обработано " + Статистика.Количество() + " порций в " + СтруктураПотоков.ФактическоеКоличествоПотоков + " потоков. Средняя длительность порции - " + СредняяДлительностьПорции + " сек";
Если СредняяДлительностьПорции > 5 Тогда
ТекстСообщения = ТекстСообщения + ". Рекомендуется уменьшить количество объектов в порции.";
ИначеЕсли СредняяДлительностьПорции < 1 Тогда
ТекстСообщения = ТекстСообщения + ". Рекомендуется увеличить количество объектов в порции.";
ИначеЕсли Не ВыводитьСтатистикуОбязательно Тогда
Возврат;
КонецЕсли;
ирОбщий.СообщитьЛкс(ТекстСообщения);
КонецПроцедуры
Процедура ЗапуститьПотокОбработкиПорцииЛкс(Знач СтруктураПотоков)
//ФоновыеЗадания.ОжидатьЗавершенияВыполнения() // Не позволяет ждать одного из
Пока Истина Цикл
НомераСвободныхПотоков = ОбновитьПотокиОбработкиОбъектовЛкс(СтруктураПотоков);
Если НомераСвободныхПотоков.Количество() > 0 Тогда
Прервать;
КонецЕсли;
ПаузаМиллисекундЛкс(5);
КонецЦикла;
ПорцияОбъектов = СтруктураПотоков.ПорцияОбъектов;
НомерСвободногоПотока = НомераСвободныхПотоков[0];
ПотокиОбработки = СтруктураПотоков.ПотокиОбработки;
ПотокиОбработки[НомерСвободногоПотока].СтрокиРезультатовОбъектов = ПорцияОбъектов.СтрокиРезультатовОбъектов;
АдресРезультата = ПоместитьВоВременноеХранилище(Null);
ПараметрыЗадания = Новый Массив(5);
ПолноеИмяМодуля = СтруктураПотоков.МодульОбработчика.Метаданные().ПолноеИмя();
ПараметрыЗадания[0] = ПолноеИмяМодуля;
ПараметрыЗадания[1] = СтруктураПотоков.ИмяОбработчикаОбъекта;
ПараметрыЗадания[2] = СтруктураПотоков.ОбщиеПараметрыОбработкиОдногоОбъекта;
ПараметрыЗадания[3] = ПорцияОбъектов.ПараметрыОбработкиОбъектов;
ПараметрыЗадания[4] = АдресРезультата;
//ДобавитьПереданныйКэшВСтруктуруЛкс(СтруктураПотоков.ОбщиеПараметрыОбработкиОдногоОбъекта);
#Если Сервер И Не Сервер Тогда
ирОбщий.ОбработатьПорциюОбъектовЛкс();
#КонецЕсли
ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ОбработатьПорциюОбъектовЛкс", ПараметрыЗадания, ПолноеИмяМодуля + "." + НомерСвободногоПотока, "Поток обработки объектов " + НомерСвободногоПотока);
ПотокиОбработки[НомерСвободногоПотока].АдресРезультата = АдресРезультата;
ПотокиОбработки[НомерСвободногоПотока].УникальныйИдентификатор = ФоновоеЗадание.УникальныйИдентификатор;
СтруктураПотоков.ПорцияОбъектов = Неопределено;
КонецПроцедуры
Процедура ОбработатьПорциюОбъектовЛкс(ПолноеИмяМД, ИмяОбработчикаОбъекта, ОбщиеПараметрыОбработки, ПараметрыМетода, АдресРезультата) Экспорт
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = СоздатьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД);
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирПодборИОбработкаОбъектов.Создать()
#КонецЕсли
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
РезультатПорции = Новый Массив;
Для Каждого ПараметрыВызова Из ПараметрыМетода Цикл
РезультатПорции.Добавить(Вычислить("Обработка." + ИмяОбработчикаОбъекта + "(ПараметрыВызова)"));
КонецЦикла;
ПоместитьВоВременноеХранилище(РезультатПорции, АдресРезультата);
КонецПроцедуры
Функция ОбновитьПотокиОбработкиОбъектовЛкс(СтруктураПотоков, ОбновлятьДоПервогоСвободного = Истина)
ПотокиОбработки = СтруктураПотоков.ПотокиОбработки;
Статистика = СтруктураПотоков.Статистика;
НомераСвободныхПотоков = Новый Массив;
МодульОбработчика = СтруктураПотоков.МодульОбработчика;
Для Каждого ПотокОбработки Из СтруктураПотоков.ПотокиОбработки Цикл
Если ЗначениеЗаполнено(ПотокОбработки.УникальныйИдентификатор) Тогда
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ПотокОбработки.УникальныйИдентификатор);
СообщенияПользователю = СообщенияПользователюОтФоновогоЗаданияЛкс(ФоновоеЗадание, Истина);
Для Каждого СообщениеПользователю Из СообщенияПользователю Цикл
СообщитьЛкс(СообщениеПользователю.Текст,, Истина);
СообщениеПользователю.Сообщить();
КонецЦикла;
Если ФоновоеЗадание.Состояние <> СостояниеФоновогоЗадания.Активно Тогда
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Завершено Тогда
РезультатПорции = ПолучитьИзВременногоХранилища(ПотокОбработки.АдресРезультата);
Если Статистика <> Неопределено Тогда
СтрокаСтатистики = Статистика.Добавить();
СтрокаСтатистики.Длительность = ФоновоеЗадание.Конец - ФоновоеЗадание.Начало;
Если Статистика.Количество() = 4 Тогда
СообщитьСтатистикуПорцийСРекомендациями(СтруктураПотоков);
КонецЕсли;
КонецЕсли;
Иначе
РезультатОбработки = "Фоновое задание отменено";
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда
РезультатОбработки = ПодробноеПредставлениеОшибки(ФоновоеЗадание.ИнформацияОбОшибке);
КонецЕсли;
ВызватьИсключение РезультатОбработки;
//РезультатПорции = Новый Массив;
//ТекстСообщений = ирОбщий.СоединитьСообщенияПользователюЛкс(СообщенияПользователю);
//Для Счетчик = 1 По ПотокОбработки.СтрокиРезультатовОбъектов.Количество() Цикл
// РезультатПорции.Добавить(Новый Структура("Результат, ТекстСообщений", РезультатОбработки, ТекстСообщений));
//КонецЦикла;
КонецЕсли;
Для ИндексОбъектаПорции = 0 По ПотокОбработки.СтрокиРезультатовОбъектов.ВГраница() Цикл
РезультатОбработки = РезультатПорции[ИндексОбъектаПорции];
СтрокиРезультатов = ПотокОбработки.СтрокиРезультатовОбъектов[ИндексОбъектаПорции];
Выполнить("МодульОбработчика." + СтруктураПотоков.ИмяОбработчикаРезультатаОбъекта + "(РезультатОбработки, СтрокиРезультатов)");
ПотокОбработки.СтрокиРезультатовОбъектов[ИндексОбъектаПорции] = СтрокиРезультатов;
КонецЦикла;
ПотокОбработки.УникальныйИдентификатор = Неопределено;
КонецЕсли;
КонецЕсли;
Если ПотокОбработки.УникальныйИдентификатор = Неопределено Тогда
НомерСвободногоПотока = СтруктураПотоков.ПотокиОбработки.Индекс(ПотокОбработки);
НомераСвободныхПотоков.Добавить(НомерСвободногоПотока);
КонецЕсли;
КонецЦикла;
Возврат НомераСвободныхПотоков;
КонецФункции
////////////////////////////////////////////////
// Групповые обработки с возможностью фонового выполнения
Процедура ОчиститьДвиженияДокументаЛкс(Знач Ссылка, Знач ВключаяПоследовательности = Ложь, Знач ВключаяПерерасчеты = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
Ссылка = Документы.АвансовыйОтчет.ПустаяСсылка();
#КонецЕсли
ОбъектыМД = ирОбщий.ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(Ссылка.Метаданные(), ВключаяПоследовательности, ВключаяПерерасчеты);
Для Каждого МетаРегистр из ОбъектыМД Цикл
ПолноеИмяМД = МетаРегистр.ПолноеИмя();
ИмяТаблицыБДРегистра = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
ИмяПоляОтбора = ирОбщий.ИмяПоляОтбораПодчиненногоНабораЗаписейЛкс(ИмяТаблицыБДРегистра);
СтруктураНаборЗаписей = ирОбщий.ОбъектБДПоКлючуЛкс(ПолноеИмяМД, Новый Структура(ИмяПоляОтбора, Ссылка),, Ложь);
ирОбщий.ЗаписатьОбъектЛкс(СтруктураНаборЗаписей.Методы);
КонецЦикла;
КонецПроцедуры
Функция ПодборИОбработкаОбъектов_ВыполнитьОбработкуЛкс(Знач ИмяОбработки, ОбщиеПараметрыОбработки, Знач НастройкаОбработки, Знач АдресРезультата = Неопределено, Знач ЭтаФорма = Неопределено,
Знач Кнопка = Неопределено, Знач ОбработчикЗавершения = Неопределено, Знач Кэш = Неопределено, БлокируемыеЭлементыФормы = Неопределено) Экспорт
Если Ложь
Или Кнопка = Неопределено
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Или Не ОбщиеПараметрыОбработки.ВыполнятьНаСервере
Тогда
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирПодборИОбработкаОбъектов");
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирПодборИОбработкаОбъектов.Создать()
#КонецЕсли
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
НастройкаОбработки.Вставить("ИмяОбработки", ИмяОбработки);
Если ЗначениеЗаполнено(ОбщиеПараметрыОбработки.Запрос.Текст) Тогда
Запрос = Новый Запрос;
Запрос.Текст = ОбщиеПараметрыОбработки.Запрос.Текст;
ирОбщий.СкопироватьУниверсальнуюКоллекциюЛкс(ОбщиеПараметрыОбработки.Запрос.Параметры, Запрос.Параметры);
Обработка.мЗапрос = Запрос;
КонецЕсли;
РезультатМетода = Обработка.ВыполнитьГрупповуюОбработку(НастройкаОбработки);
Результат = Новый Структура(Обработка.мИменаВозвращаемыхСвойств);
ЗаполнитьЗначенияСвойств(Результат, Обработка, Обработка.мИменаВозвращаемыхСвойств);
Результат.Вставить("Результат", РезультатМетода);
Результат.Вставить("СтрокиДляОбработки", Обработка.СтрокиДляОбработки);
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(ОбщиеПараметрыОбработки, АдресРезультата);
КонецЕсли;
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
Иначе
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
ПредставлениеЗадания = "Обработка объектов";
ИмяЗадания = "ОбработкаОбъектов";
ПолноеИмяЭтогоМетода = "ирОбщий.ПодборИОбработкаОбъектов_ВыполнитьОбработкуЛкс";
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ОбщиеПараметрыОбработки.Удалить("Компоновщик");
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ИмяОбработки); // ИмяОбработки
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки); // ОбщиеПараметрыОбработки
ПараметрыЗадания.Добавить(НастройкаОбработки); // НастройкаОбработки
ПараметрыЗадания.Добавить(АдресРезультата); // АдресРезультата
ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма
ПараметрыЗадания.Добавить(Неопределено); // Кнопка
ПараметрыЗадания.Добавить(Неопределено); // ОбработчикЗавершения
ПараметрыЗадания.Добавить(Неопределено); // Кэш
ДобавитьПереданныйКэшВСтруктуруЛкс(ОбщиеПараметрыОбработки);
Если БлокируемыеЭлементыФормы = Неопределено Тогда
БлокируемыеЭлементыФормы = Новый Массив;
КонецЕсли;
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс(ИмяЗадания, ПолноеИмяЭтогоМетода, ПараметрыЗадания, ПредставлениеЗадания, Кнопка, ОбработчикЗавершения, АдресРезультата,,
БлокируемыеЭлементыФормы);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ирУдалениеОбъектовСКонтролемСсылок_КонтролироватьЛкс(Знач ОбщиеПараметрыОбработки, Знач ЗапуститьУдалениеПослеКонтроля, Знач АдресРезультата = Неопределено, Знач ЭтаФорма = Неопределено,
Знач Кнопка = Неопределено, Знач ОбработчикЗавершения = Неопределено, Знач Кэш = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ОбщиеПараметрыОбработки = Новый Структура;
#КонецЕсли
Если Ложь
Или Кнопка = Неопределено
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Или Не ОбщиеПараметрыОбработки.ВыполнятьНаСервере
Тогда
Если ЭтаФорма <> Неопределено Тогда
Обработка = ЭтаФорма;
Иначе
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирУдалениеОбъектовСКонтролемСсылок");
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирУдалениеОбъектовСКонтролемСсылок.Создать()
#КонецЕсли
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
Обработка.УдаляемыеОбъекты.Загрузить(ОбщиеПараметрыОбработки.УдаляемыеОбъекты);
Обработка.НеблокирующиеТипы.Загрузить(ОбщиеПараметрыОбработки.НеблокирующиеТипы);
КонецЕсли;
Обработка.КонтролироватьСсылкиНаКандидаты();
Результат = Новый Структура;
Результат.Вставить("ЗапуститьУдалениеПослеКонтроля", ЗапуститьУдалениеПослеКонтроля);
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
Иначе
Результат.Вставить("ТаблицаСсылок", Обработка.ТаблицаСсылок);
Результат.Вставить("УдаляемыеОбъекты", Обработка.УдаляемыеОбъекты.Выгрузить());
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
ЭтаФорма.ОтключитьОбработчикОжидания("СброситьКолонкуУдаляется");
ОбщиеПараметрыОбработки.Вставить("УдаляемыеОбъекты", ЭтаФорма.УдаляемыеОбъекты.Выгрузить());
ОбщиеПараметрыОбработки.Вставить("НеблокирующиеТипы", ЭтаФорма.НеблокирующиеТипы.Выгрузить());
ДобавитьПереданныйКэшВСтруктуруЛкс(ОбщиеПараметрыОбработки);
ПредставлениеЗадания = "Контролировать ссылки";
ИмяЗадания = "КонтролироватьСсылки";
ПолноеИмяЭтогоМетода = "ирОбщий.ирУдалениеОбъектовСКонтролемСсылок_КонтролироватьЛкс";
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки);
ПараметрыЗадания.Добавить(ЗапуститьУдалениеПослеКонтроля);
ПараметрыЗадания.Добавить(АдресРезультата);
ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма
ПараметрыЗадания.Добавить(Неопределено); // Кнопка
ПараметрыЗадания.Добавить(Неопределено); // ОбработчикЗавершения
БлокируемыеЭлементыФормы = Новый Массив;
БлокируемыеЭлементыФормы.Добавить(ЭтаФорма.ЭлементыФормы.УдаляемыеОбъекты.Имя);
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс(ИмяЗадания, ПолноеИмяЭтогоМетода, ПараметрыЗадания, ПредставлениеЗадания, Кнопка, ОбработчикЗавершения, АдресРезультата,,
БлокируемыеЭлементыФормы);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция УдалениеОбъектовСКонтролемСсылок_УдалитьОбъектыЛкс(Знач ОбщиеПараметрыОбработки, Знач АдресРезультата = Неопределено, Знач ЭтаФорма = Неопределено,
Знач Кнопка = Неопределено, Знач ОбработчикЗавершения = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ОбщиеПараметрыОбработки = Новый Структура;
#КонецЕсли
Если Ложь
Или Кнопка = Неопределено
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Или Не ОбщиеПараметрыОбработки.ВыполнятьНаСервере
Тогда
Если ЭтаФорма <> Неопределено Тогда
Обработка = ЭтаФорма;
Иначе
ирКэш.ПараметрыСеансаЛкс().ПереданныйКэш = ПоместитьВоВременноеХранилище(ОбщиеПараметрыОбработки.Кэш, Новый УникальныйИдентификатор);
Обработка = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирУдалениеОбъектовСКонтролемСсылок");
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирУдалениеОбъектовСКонтролемСсылок.Создать()
#КонецЕсли
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
Обработка.УдаляемыеОбъекты.Загрузить(ОбщиеПараметрыОбработки.УдаляемыеОбъекты);
КонецЕсли;
Обработка.УдалитьОбъектыЛкс();
Результат = Новый Структура;
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
Иначе
Результат.Вставить("УдаляемыеОбъекты", Обработка.УдаляемыеОбъекты.Выгрузить());
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
ЭтаФорма.ОтключитьОбработчикОжидания("СброситьКолонкуУдаляется");
ОбщиеПараметрыОбработки.Вставить("УдаляемыеОбъекты", ЭтаФорма.УдаляемыеОбъекты.Выгрузить());
ОбщиеПараметрыОбработки.Вставить("НеблокирующиеТипы", ЭтаФорма.НеблокирующиеТипы.Выгрузить());
ДобавитьПереданныйКэшВСтруктуруЛкс(ОбщиеПараметрыОбработки);
ПредставлениеЗадания = "Удалить объекты";
ИмяЗадания = "УдалитьОбъекты";
ПолноеИмяЭтогоМетода = "ирОбщий.УдалениеОбъектовСКонтролемСсылок_УдалитьОбъектыЛкс";
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки);
ПараметрыЗадания.Добавить(АдресРезультата);
ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма
ПараметрыЗадания.Добавить(Неопределено); // Кнопка
ПараметрыЗадания.Добавить(Неопределено); // ОбработчикЗавершения
БлокируемыеЭлементыФормы = Новый Массив;
БлокируемыеЭлементыФормы.Добавить(ЭтаФорма.ЭлементыФормы.УдаляемыеОбъекты.Имя);
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс(ИмяЗадания, ПолноеИмяЭтогоМетода, ПараметрыЗадания, ПредставлениеЗадания, Кнопка, ОбработчикЗавершения, АдресРезультата,,
БлокируемыеЭлементыФормы);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПоискДублейИЗаменаСсылок_ВыполнитьЗаменуЛкс(Знач ОбщиеПараметрыОбработки, Знач СоответствиеЗамен, Знач НайденныеСсылки, Знач АдресРезультата = Неопределено, Знач ЭтаФорма = Неопределено,
Знач Кнопка = Неопределено, Знач ОбработчикЗавершения = Неопределено) Экспорт
Если Ложь
Или Кнопка = Неопределено
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Или Не ОбщиеПараметрыОбработки.ВыполнятьНаСервере
Тогда
Если ЭтаФорма <> Неопределено Тогда
Обработка = ЭтаФорма;
Иначе
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирПоискДублейИЗаменаСсылок");
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирПоискДублейИЗаменаСсылок.Создать()
#КонецЕсли
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
КонецЕсли;
БезОшибок = Обработка.ВыполнитьЗаменуЭлементов(СоответствиеЗамен, НайденныеСсылки);
Результат = Новый Структура;
Результат.Вставить("ИзмененныеПроведенныеДокументы", Обработка.ИзмененныеПроведенныеДокументы.Выгрузить());
Результат.Вставить("СоответствиеЗамен", СоответствиеЗамен);
Результат.Вставить("БезОшибок", БезОшибок);
Если ЭтаФорма <> Неопределено Тогда
Если ЗначениеЗаполнено(ОбработчикЗавершения) Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
КонецЕсли;
Иначе
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
ПредставлениеЗадания = "Замена ссылок";
ИмяЗадания = "ЗаменаСсылок";
ПолноеИмяЭтогоМетода = "ирОбщий.ПоискДублейИЗаменаСсылок_ВыполнитьЗаменуЛкс";
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ДобавитьПереданныйКэшВСтруктуруЛкс(ОбщиеПараметрыОбработки);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки);
ПараметрыЗадания.Добавить(СоответствиеЗамен);
ПараметрыЗадания.Добавить(НайденныеСсылки);
ПараметрыЗадания.Добавить(АдресРезультата);
ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма
ПараметрыЗадания.Добавить(Неопределено); // Кнопка
ПараметрыЗадания.Добавить(Неопределено); // ОбработчикЗавершения
БлокируемыеЭлементыФормы = Новый Массив;
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс(ИмяЗадания, ПолноеИмяЭтогоМетода, ПараметрыЗадания, ПредставлениеЗадания, Кнопка, ОбработчикЗавершения, АдресРезультата,,
БлокируемыеЭлементыФормы);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЗагрузкаТабличныхДанных_ЗагрузитьЛкс(Знач ОбщиеПараметрыОбработки, Знач Записывать, Знач АдресРезультата = Неопределено, Знач ЭтаФорма = Неопределено, Знач Кнопка = Неопределено,
Знач ОбработчикЗавершения = Неопределено) Экспорт
Если Ложь
Или Кнопка = Неопределено
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Или Не ОбщиеПараметрыОбработки.ВыполнятьНаСервере
Тогда
Если ЭтаФорма <> Неопределено Тогда
Обработка = ЭтаФорма;
Иначе
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирЗагрузкаТабличныхДанных");
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирЗагрузкаТабличныхДанных.Создать()
#КонецЕсли
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
КонецЕсли;
Обработка.ЗагрузитьВТаблицуБДИзТаблицыЗначений(Записывать);
Результат = Новый Структура;
Результат.Вставить("ТаблицаБД", Обработка.ТаблицаБД);
Результат.Вставить("КоличествоУспешно", Обработка.КоличествоУспешно);
Результат.Вставить("КоличествоНеуспешно", Обработка.КоличествоНеуспешно);
Если ЭтаФорма <> Неопределено Тогда
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
Иначе
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
ПредставлениеЗадания = "Загрузка данных";
ИмяЗадания = "ЗагрузкаДанных";
ПолноеИмяЭтогоМетода = "ирОбщий.ЗагрузкаТабличныхДанных_ЗагрузитьЛкс";
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки);
ПараметрыЗадания.Добавить(Записывать);
ПараметрыЗадания.Добавить(АдресРезультата);
ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма
ПараметрыЗадания.Добавить(Неопределено); // Кнопка
ПараметрыЗадания.Добавить(Неопределено); // ОбработчикЗавершения
ДобавитьПереданныйКэшВСтруктуруЛкс(ОбщиеПараметрыОбработки);
БлокируемыеЭлементыФормы = Новый Массив;
БлокируемыеЭлементыФормы.Добавить(ЭтаФорма.ЭлементыФормы.ПолноеИмяТаблицы.Имя);
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс(ИмяЗадания, ПолноеИмяЭтогоМетода, ПараметрыЗадания, ПредставлениеЗадания, Кнопка, ОбработчикЗавершения, АдресРезультата,,
БлокируемыеЭлементыФормы);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПоискБитыхСсылок_ВыполнитьПоискЛкс(Знач ОбщиеПараметрыОбработки, Знач ПолучатьДанные, Знач НачалаПоиска, Знач СвязанныеДанные = Неопределено, Знач АдресРезультата = Неопределено,
Знач ЭтаФорма = Неопределено, Знач Кнопка = Неопределено, Знач ОбработчикЗавершения = Неопределено) Экспорт
Если Ложь
Или Кнопка = Неопределено
Или ЭтаФорма = Неопределено
Или Не ЛиАсинхронностьДоступнаЛкс()
Или Не ОбщиеПараметрыОбработки.ВыполнятьНаСервере
Тогда
Если ЭтаФорма <> Неопределено Тогда
Обработка = ЭтаФорма;
Иначе
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирПоискБитыхСсылок");
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирПоискБитыхСсылок.Создать()
#КонецЕсли
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
Обработка.СвязанныеДанные.Загрузить(СвязанныеДанные);
КонецЕсли;
Обработка.ПолучитьЗапросВыборки(ПолучатьДанные, ЭтаФорма);
Результат = Новый Структура;
Результат.Вставить("НачалаПоиска", НачалаПоиска);
Если ЭтаФорма <> Неопределено Тогда
Результат.Вставить("СвязанныеДанные", Обработка.СвязанныеДанные);
Выполнить("ЭтаФорма." + ОбработчикЗавершения + "(, Результат)");
Результат = Неопределено;
Иначе
Результат.Вставить("СвязанныеДанные", Обработка.СвязанныеДанные.Выгрузить());
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Иначе
ПредставлениеЗадания = "Поиск";
ИмяЗадания = "Поиск";
ПолноеИмяЭтогоМетода = "ирОбщий.ПоискБитыхСсылок_ВыполнитьПоискЛкс";
АдресРезультата = ирОбщий.НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(ЭтаФорма);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки);
ПараметрыЗадания.Добавить(ПолучатьДанные);
ПараметрыЗадания.Добавить(НачалаПоиска);
ПараметрыЗадания.Добавить(СвязанныеДанные.Выгрузить());
ПараметрыЗадания.Добавить(АдресРезультата); // АдресРезультата
ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма
ПараметрыЗадания.Добавить(Неопределено); // Кнопка
ПараметрыЗадания.Добавить(Неопределено); // ОбработчикЗавершения
ДобавитьПереданныйКэшВСтруктуруЛкс(ОбщиеПараметрыОбработки);
БлокируемыеЭлементыФормы = Новый Массив;
ОписаниеЗадания = ирОбщий.ОписаниеФоновогоЗаданияФормыЛкс(ИмяЗадания, ПолноеИмяЭтогоМетода, ПараметрыЗадания, ПредставлениеЗадания, Кнопка, ОбработчикЗавершения, АдресРезультата,, БлокируемыеЭлементыФормы);
ирОбщий.ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ВыгрузкаЗагрузкаДанныхЧерезФайл_ВыполнитьВыгрузкуЛкс(Знач ОбщиеПараметрыОбработки, Знач АдресРезультата = Неопределено, Знач ЭтаФорма = Неопределено) Экспорт
#Если Клиент Тогда
Если ОбщиеПараметрыОбработки.ВыполнятьНаСервере Тогда
ФормаРезультата = НоваяФормаРезультатаФоновогоЗаданияЛкс();
АдресРезультата = ПоместитьВоВременноеХранилище(Неопределено, ФормаРезультата.УникальныйИдентификатор);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки);
ПараметрыЗадания.Добавить(АдресРезультата); // АдресРезультата
ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма
ДобавитьПереданныйКэшВСтруктуруЛкс(ОбщиеПараметрыОбработки);
ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ВыгрузкаЗагрузкаДанныхЧерезФайл_ВыполнитьВыгрузкуЛкс", ПараметрыЗадания, НомерСеансаИнформационнойБазы());
Если ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание, ЭтаФорма) Тогда
Результат = ПрочитатьРезультатФоновогоЗаданияЛкс(АдресРезультата, ФормаРезультата);
Результат.Записать(ОбщиеПараметрыОбработки.ИмяФайла);
КонецЕсли;
Иначе
#КонецЕсли
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирВыгрузкаЗагрузкаДанныхЧерезФайл");
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирВыгрузкаЗагрузкаДанныхЧерезФайл.Создать()
#КонецЕсли
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
Результат = Обработка.ВыполнитьВыгрузку();
#Если Сервер И Не Сервер Тогда
Результат = Новый ДвоичныеДанные;
#КонецЕсли
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
Иначе
Результат.Записать(Обработка.ИмяФайла);
КонецЕсли;
#Если Клиент Тогда
КонецЕсли;
#КонецЕсли
Возврат Результат;
КонецФункции
Функция ВыгрузкаЗагрузкаДанныхЧерезФайл_ВыполнитьЗагрузкуЛкс(Знач ОбщиеПараметрыОбработки, Знач ДвоичныеДанные = Неопределено, Знач АдресРезультата = Неопределено, Знач ЭтаФорма = Неопределено) Экспорт
#Если Клиент Тогда
Если ДвоичныеДанные = Неопределено Тогда
ДвоичныеДанные = Новый ДвоичныеДанные(ОбщиеПараметрыОбработки.ИмяФайла);
КонецЕсли;
Если ОбщиеПараметрыОбработки.ВыполнятьНаСервере Тогда
ФормаРезультата = НоваяФормаРезультатаФоновогоЗаданияЛкс();
//ОбщиеПараметрыОбработки.ИмяФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанные, ФормаРезультатФоновогоЗадания.УникальныйИдентификатор);
АдресРезультата = ПоместитьВоВременноеХранилище(Неопределено, ФормаРезультата.УникальныйИдентификатор);
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки);
ПараметрыЗадания.Добавить(ДвоичныеДанные);
ПараметрыЗадания.Добавить(АдресРезультата); // АдресРезультата
ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма
ДобавитьПереданныйКэшВСтруктуруЛкс(ОбщиеПараметрыОбработки);
ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ВыгрузкаЗагрузкаДанныхЧерезФайл_ВыполнитьЗагрузкуЛкс", ПараметрыЗадания, НомерСеансаИнформационнойБазы());
Если ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание, ЭтаФорма) Тогда
Результат = ПрочитатьРезультатФоновогоЗаданияЛкс(АдресРезультата, ФормаРезультата);
КонецЕсли;
Иначе
#КонецЕсли
ПоместитьПереданныйКэшВоВременноеХранищеЛкс(ОбщиеПараметрыОбработки);
Обработка = СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирВыгрузкаЗагрузкаДанныхЧерезФайл");
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирВыгрузкаЗагрузкаДанныхЧерезФайл.Создать()
#КонецЕсли
ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки);
Обработка.ИмяФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанные);
Результат = Обработка.ВыполнитьЗагрузку();
Если ЗначениеЗаполнено(АдресРезультата) Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
#Если Клиент Тогда
КонецЕсли;
ирОбщий.ОповеститьФормыПодсистемыЛкс("ЗаписанОбъект", , ЭтаФорма);
#КонецЕсли
Возврат Результат;
КонецФункции
////////////////////////////////////////////////
#КонецЕсли
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент И Клиент Тогда
Функция ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле, Знач Строка = Неопределено) Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
ДанныеСтроки = Неопределено;
Если Строка = Неопределено Тогда
Строка = ТабличноеПоле.ТекущаяСтрока;
КонецЕсли;
Если Строка <> Неопределено Тогда
//ДанныеТаблицы = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
//#Если Сервер И Не Сервер Тогда
// ДанныеТаблицы = Новый ТаблицаЗначений;
//#КонецЕсли
//ДанныеСтроки = ДанныеТаблицы.НайтиПоИдентификатору(Строка);
ДанныеСтроки = ТабличноеПоле.ДанныеСтроки(Строка);
Если ДанныеСтроки = Неопределено Тогда
// Ключ записи регистра без ресурсов и измерений (ШтрихкодыНоменклатуры) иногда почему то дает Неопределено
ДанныеСтроки = Строка;
КонецЕсли;
КонецЕсли;
Иначе
ДанныеСтроки = Строка;
Если Ложь
Или ДанныеСтроки = Неопределено
Или ЛиКлючЗаписиРегистраЛкс(ДанныеСтроки)
Тогда
ДанныеСтроки = ТабличноеПоле.ТекущиеДанные;
КонецЕсли;
КонецЕсли;
Возврат ДанныеСтроки;
КонецФункции
Функция ОткрытьСистемнуюФормуОтчетПоВерсииЛкс(Данные, НомерВерсии) Экспорт
Попытка
ОткрытьФорму("sysForm:DataHistoryVersionDataRuForm", Новый Структура("Данные, НомерВерсии", Данные, НомерВерсии));
Исключение
ОписаниеОшибки = ОписаниеОшибки();
ИсследоватьВерсиюОбъектаДанныхЛкс(Данные, НомерВерсии);
КонецПопытки;
КонецФункции
Процедура ИсследоватьВерсиюОбъектаДанныхЛкс(Знач Данные, Знач НомерВерсии) Экспорт
#Если ВебКлиент Тогда
СообщитьЛкс("Команда недоступна в вебклиенте");
#Иначе
ИсторияДанныхМоя = Вычислить("ИсторияДанных");
#Если Сервер И Не Сервер Тогда
ИсторияДанныхМоя = ИсторияДанных;
#КонецЕсли
Структура = ИсторияДанныхМоя.ПолучитьДанныеВерсии(Данные, НомерВерсии);
ИсследоватьЛкс(Структура);
#КонецЕсли
КонецПроцедуры
Функция ОткрытьСистемнуюФормуСписокВерсийЛкс(Данные, НомерВерсии) Экспорт
ОткрытьФорму("sysForm:DataHistoryVersions", Новый Структура("Data, VersionNumber", Данные, НомерВерсии));
КонецФункции
Функция ОткрытьСистемнуюФормуСравненияВерсийЛкс(Данные, НомерВерсииПослеИзменения, НомерВерсииДоИзменения) Экспорт
ОткрытьФорму("sysForm:DataHistoryVersionDifferenecesRuForm", Новый Структура("Данные, НомерВерсииПослеИзменения, НомерВерсииДоИзменения", Данные, НомерВерсииПослеИзменения, НомерВерсииДоИзменения));
КонецФункции
Процедура ИсследоватьСравнениеВерсийЛкс(Знач Данные, Знач НомерВерсииПослеИзменения, Знач НомерВерсииДоИзменения) Экспорт
#Если ВебКлиент Тогда
СообщитьЛкс("Команда недоступна в вебклиенте");
#Иначе
ИсторияДанныхМоя = Вычислить("ИсторияДанных");
#Если Сервер И Не Сервер Тогда
ИсторияДанныхМоя = ИсторияДанных;
#КонецЕсли
Структура = ИсторияДанныхМоя.ПолучитьРазличияВерсий(Данные, НомерВерсииПослеИзменения, НомерВерсииДоИзменения);
ИсследоватьЛкс(Структура);
#КонецЕсли
КонецПроцедуры
Функция НоваяФормаРезультатаФоновогоЗаданияЛкс() Экспорт
// Управляемые формы так создавать нельзя!
// http://www.hostedredmine.com/issues/874998
//мПлатформа = ирКэш.Получить();
//#Если Сервер И Не Сервер Тогда
// мПлатформа = Обработки.ирПлатформа.Создать();
//#КонецЕсли
//ФормаРезультатФоновогоЗадания = мПлатформа.ПолучитьФорму("РезультатФоновогоЗадания");
ФормаРезультатФоновогоЗадания = ирОбщий.ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.РезультатФоновогоЗадания",,, Новый УникальныйИдентификатор);
Возврат ФормаРезультатФоновогоЗадания;
КонецФункции
Процедура ЗапуститьИлиОтменитьФоновоеЗаданиеФормыЛкс(Знач ЭтаФорма, Знач ОписаниеЗадания, Знач Перезапустить = Ложь) Экспорт
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ЭтаФорма);
#Если Сервер И Не Сервер Тогда
СлужебныеДанные = Новый Структура;
ОписаниеЗадания = ОписаниеФоновогоЗаданияФормыЛкс();
#КонецЕсли
Если Не МетодРеализованЛкс(ЭтаФорма, ОписаниеЗадания.ОбработчикЗавершения) Тогда
ВызватьИсключение "У формы " + СсылкаНаМодульКонфигурацииЛкс(СлужебныеДанные.ИмяФормы) + " не обнаружен экспортный метод " + ОписаниеЗадания.ОбработчикЗавершения;
КонецЕсли;
МаркерОтмены = "Отменить фоновое задание";
ЗаданияФормы = СлужебныеДанные.Задания;
Если ЗаданияФормы.Свойство(ОписаниеЗадания.Имя) Тогда
ОписаниеЗаданияСтарое = ЗаданияФормы[ОписаниеЗадания.Имя];
Если ОписаниеЗаданияСтарое.УникальныйИдентификатор <> Неопределено Тогда
Если ОписаниеЗадания.Кнопка.Картинка <> ирКэш.КартинкаПоИмениЛкс("ирОстановить") Тогда
Перезапустить = Истина;
КонецЕсли;
ОтменитьЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗаданияСтарое);
Если Не Перезапустить Тогда
Возврат;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ОписаниеЗадания.НачалоВыполнения = ТекущаяДата();
Если ОписаниеЗадания.БлокируемыеЭлементыФормы <> Неопределено Тогда
Для Каждого ИмяЭлементаФормы Из ОписаниеЗадания.БлокируемыеЭлементыФормы Цикл
ИмяЭлементаФормы.Значение.Вставить("Доступность");
ИмяЭлементаФормы.Значение.Вставить("ТолькоПросмотр");
БлокуруемыйЭлемент = ЭтаФорма.ЭлементыФормы[ИмяЭлементаФормы.Ключ];
ЗаполнитьЗначенияСвойств(ИмяЭлементаФормы.Значение, БлокуруемыйЭлемент);
Попытка
БлокуруемыйЭлемент.ТолькоПросмотр = Истина;
Исключение
БлокуруемыйЭлемент.Доступность = Ложь;
КонецПопытки;
КонецЦикла;
КонецЕсли;
ФоновоеЗадание = ФоновыеЗадания.Выполнить(ОписаниеЗадания.Метод, ОписаниеЗадания.Параметры, , ЭтаФорма.Метаданные().Представление() + ". " + ОписаниеЗадания.Представление);
ОписаниеЗадания.УникальныйИдентификатор = ФоновоеЗадание.УникальныйИдентификатор;
ЗаданияФормы.Вставить(ОписаниеЗадания.Имя, ОписаниеЗадания);
Если ТипЗнч(ОписаниеЗадания.Кнопка) = Тип("КнопкаКоманднойПанели") Тогда
ИменаСвойств = "Подсказка, Картинка, Отображение";
Иначе
ИменаСвойств = "Подсказка, Картинка";
КонецЕсли;
СвойстваКнопки = Новый Структура(ИменаСвойств);
ЗаполнитьЗначенияСвойств(СвойстваКнопки, ОписаниеЗадания.Кнопка, ИменаСвойств);
ОписаниеЗадания.СвойстваКнопки = СвойстваКнопки;
ОписаниеЗадания.Кнопка.Картинка = ирКэш.КартинкаПоИмениЛкс("ирОстановить");
ОписаниеЗадания.Кнопка.Подсказка = МаркерОтмены + " - " + ОписаниеЗадания.Представление;
Если СвойстваКнопки.Свойство("Отображение") Тогда
ОписаниеЗадания.Кнопка.Отображение = ОтображениеКнопкиКоманднойПанели.НадписьКартинка;
КонецЕсли;
ФормаЗадания = ФормаЗаданияФормыЛкс(ОписаниеЗадания, ЭтаФорма);
ФормаЗадания.ЭлементыФормы.ПолеТекста.Очистить();
ФормаЗадания.ЭлементыФормы.Отменить.Доступность = Истина;
ФормаЗадания.Отменить = Ложь;
ФормаЗадания.ИдентификаторЗадания = ФоновоеЗадание.УникальныйИдентификатор;
ФормаЗадания.ОбновитьСостояниеЗадания(ФоновоеЗадание);
ПроверитьЗавершениеФоновыхЗаданийФормыЛкс(ЭтаФорма);
КонецПроцедуры
Функция ОписаниеФоновогоЗаданияФормыЛкс(Имя = "", Метод = "", Параметры = Неопределено, Представление = "", Кнопка = Неопределено, ОбработчикЗавершения = "", АдресРезультата = "",
ОповещатьПользователяОбУспехе = Истина, БлокируемыеЭлементыФормы = Неопределено) Экспорт
ОписаниеЗадания = Новый Структура("Имя, Параметры, Метод, Представление, Кнопка, ОбработчикЗавершения, АдресРезультата, УникальныйИдентификатор, НачалоВыполнения, Состояние, СвойстваКнопки,
|ОповещатьПользователяОбУспехе, БлокируемыеЭлементыФормы, ФормаЗадания");
ОписаниеЗадания.Имя = Имя;
ОписаниеЗадания.Параметры = Параметры;
ОписаниеЗадания.Метод = Метод;
ОписаниеЗадания.Представление = Представление;
ОписаниеЗадания.Кнопка = Кнопка;
ОписаниеЗадания.ОбработчикЗавершения = ОбработчикЗавершения;
ОписаниеЗадания.АдресРезультата = АдресРезультата;
ОписаниеЗадания.ОповещатьПользователяОбУспехе = ОповещатьПользователяОбУспехе;
Если БлокируемыеЭлементыФормы <> Неопределено Тогда
СтруктураБлокировки = Новый Структура;
Для Каждого ИмяЭлемента Из БлокируемыеЭлементыФормы Цикл
СтруктураБлокировки.Вставить(ИмяЭлемента, Новый Структура());
КонецЦикла;
ОписаниеЗадания.БлокируемыеЭлементыФормы = СтруктураБлокировки;
КонецЕсли;
Возврат ОписаниеЗадания;
КонецФункции
Функция НовыйАдресРезультатаФоновогоЗаданияФормыЛкс(Знач ЭтаФорма) Экспорт
ФормаРезультатовЗаданий = ФормаРезультатовЗаданийФормыЛкс(ЭтаФорма);
АдресРезультата = ПоместитьВоВременноеХранилище(Null, ФормаРезультатовЗаданий.УникальныйИдентификатор);
Возврат АдресРезультата;
КонецФункции
Функция ФормаРезультатовЗаданийФормыЛкс(Знач ЭтаФорма) Экспорт
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ЭтаФорма);
#Если Сервер И Не Сервер Тогда
СлужебныеДанные = Новый Структура;
#КонецЕсли
Результат = Неопределено;
Если Не СлужебныеДанные.Свойство("ФормаРезультатовЗаданий", Результат) Тогда
Результат = ирОбщий.НоваяФормаРезультатаФоновогоЗаданияЛкс();
СлужебныеДанные.Вставить("ФормаРезультатовЗаданий", Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
// Функция - Проверить завершение фоновых заданий формы лкс
//
// Параметры:
// ЭтаФорма - -
//
// Возвращаемое значение:
// - Булево - активные задания отсутствуют
//
Функция ПроверитьЗавершениеФоновыхЗаданийФормыЛкс(Знач ЭтаФорма) Экспорт
//Если Не ЭтаФорма.Открыта() Тогда
// Возврат Истина;
//КонецЕсли;
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ЭтаФорма);
#Если Сервер И Не Сервер Тогда
ЭтаФорма = ПолучитьОбщуюФорму();
СлужебныеДанные = Новый Структура;
#КонецЕсли
ЗадержкаВызова = 100;
ПредставленияЗаданийВЗаголовке = Новый Массив;
РазделительДлительности = "-";
ЧистыйЗаголовокФормы = Сред(ЭтаФорма.Заголовок, Найти(ЭтаФорма.Заголовок, РазделительДлительности) + СтрДлина(РазделительДлительности));
ФормаРезультата = ФормаРезультатовЗаданийФормыЛкс(ЭтаФорма);
Завершенные = Новый Массив;
ЛиАктивныеЗаданияОтсутствуют = Истина;
Для Каждого КлючИЗначение Из СлужебныеДанные.Задания Цикл
ОписаниеЗадания = КлючИЗначение.Значение;
Если ОписаниеЗадания.УникальныйИдентификатор = Неопределено Тогда
// Уже обработано. Защита от зацикливания
Продолжить;
КонецЕсли;
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ОписаниеЗадания.УникальныйИдентификатор);
ФормаЗадания = ФормаЗаданияФормыЛкс(ОписаниеЗадания, ЭтаФорма);
Если ФормаЗадания.Отменить Тогда
ОтменитьЗаданиеФормыЛкс(ЭтаФорма, ОписаниеЗадания);
КонецЕсли;
ДлительностьСекунд = ТекущаяДата() - ОписаниеЗадания.НачалоВыполнения;
СостояниеЗадания = ФоновоеЗадание.Состояние;
Если СостояниеЗадания = СостояниеФоновогоЗадания.Активно Тогда
ПредставленияЗаданийВЗаголовке.Добавить(ирОбщий.ПредставлениеДлительностиЛкс(ДлительностьСекунд));
Если ДлительностьСекунд > 20 Тогда
ЗадержкаВызова = Мин(ЗадержкаВызова, 4);
ИначеЕсли ДлительностьСекунд > 10 Тогда
ЗадержкаВызова = Мин(ЗадержкаВызова, 2);
ИначеЕсли ДлительностьСекунд > 5 Тогда
ЗадержкаВызова = Мин(ЗадержкаВызова, 1);
ИначеЕсли ДлительностьСекунд > 2 Тогда
ЗадержкаВызова = Мин(ЗадержкаВызова, 0.5);
Иначе
ЗадержкаВызова = Мин(ЗадержкаВызова, 0.2);
КонецЕсли;
Если ЭтаФорма.ВводДоступен() Или ФормаЗадания.ВводДоступен() Тогда
ФормаЗаданияБылаОткрыта = ФормаЗадания.Открыта();
ИзменилиТекстСостояния = ОбработатьСообщенияФоновогоЗаданияЛкс(ФоновоеЗадание, ФормаЗадания);
Если Ложь
Или ИзменилиТекстСостояния
Или ТекущаяДатаСеанса() - ФоновоеЗадание.Начало > 5
Тогда
Если Не ФормаЗадания.Открыта() Тогда
ФормаЗадания.Открыть();
КонецЕсли;
КонецЕсли;
Если Не ФормаЗаданияБылаОткрыта Тогда
Если ФормаЗадания.Открыта() Тогда
ЭтаФорма.Открыть();
КонецЕсли;
КонецЕсли;
Иначе
Если ФормаЗадания.Открыта() Тогда
ФормаЗадания.Закрыть();
КонецЕсли;
КонецЕсли;
ЛиАктивныеЗаданияОтсутствуют = Ложь;
Иначе
ОписаниеЗадания.Состояние = СостояниеЗадания;
Если ЗначениеЗаполнено(ОписаниеЗадания.АдресРезультата) Тогда
Результат = ПрочитатьРезультатФоновогоЗаданияЛкс(ОписаниеЗадания.АдресРезультата, ФормаРезультата);
КонецЕсли;
ПараметрыЗадания = ОписаниеЗадания.Параметры;
ДлительностьСекунд = ФоновоеЗадание.Конец - ФоновоеЗадание.Начало;
ДлительностьСтрока = ирОбщий.ПредставлениеДлительностиЛкс(ДлительностьСекунд);
ЭтаИлиФормаЗаданияАктивна = ЭтаФорма.ВводДоступен() Или ФормаЗадания.ВводДоступен();
Если СостояниеЗадания = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда
СообщитьЛкс("Ошибка через " + ДлительностьСтрока + " фонового задания - " + ФоновоеЗадание.Наименование + ": " + ПодробноеПредставлениеОшибки(ФоновоеЗадание.ИнформацияОбОшибке), СтатусСообщения.Внимание);
ИначеЕсли Не ЭтаИлиФормаЗаданияАктивна И ОписаниеЗадания.ОповещатьПользователяОбУспехе Тогда
СообщитьЛкс("Завершено через " + ДлительностьСтрока + " фоновое задание - " + ФоновоеЗадание.Наименование);
КонецЕсли;
ОбработатьЗавершениеЗаданияФормыЛкс(ОписаниеЗадания, ЭтаФорма, ФоновоеЗадание);
ФормаЗадания.Представление = ЧистыйЗаголовокФормы + ". " + ФормаЗадания.Представление;
Выполнить("ЭтаФорма." + ОписаниеЗадания.ОбработчикЗавершения + "(СостояниеЗадания, Результат)");
Завершенные.Добавить(КлючИЗначение.Ключ);
КонецЕсли;
КонецЦикла;
Для Каждого Ключ Из Завершенные Цикл
СлужебныеДанные.Задания.Удалить(Ключ);
КонецЦикла;
Если ЗадержкаВызова <> 100 Тогда
ЭтаФорма.Заголовок = ирОбщий.СтрСоединитьЛкс(ПредставленияЗаданийВЗаголовке, РазделительДлительности) + РазделительДлительности + ЧистыйЗаголовокФормы;
ЭтаФорма.ПодключитьОбработчикОжидания("ПроверкаЗавершенияФоновыхЗаданий", ЗадержкаВызова, Истина);
Иначе
ЭтаФорма.Заголовок = ЧистыйЗаголовокФормы;
КонецЕсли;
Возврат ЛиАктивныеЗаданияОтсутствуют;
КонецФункции
Процедура ОбработатьЗавершениеЗаданияФормыЛкс(Знач ОписаниеЗадания, Знач ЭтаФорма, Знач ФоновоеЗадание = Неопределено, Знач ПоЗапросуПользователя = Ложь, Знач ЗакрытьФормуЗадания = Ложь)
Если ФоновоеЗадание = Неопределено Тогда
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ОписаниеЗадания.УникальныйИдентификатор);
КонецЕсли;
ЗаполнитьЗначенияСвойств(ОписаниеЗадания.Кнопка, ОписаниеЗадания.СвойстваКнопки);
ФормаЗадания = ФормаЗаданияФормыЛкс(ОписаниеЗадания, ЭтаФорма);
Если ОписаниеЗадания.БлокируемыеЭлементыФормы <> Неопределено Тогда
Для Каждого БлокуемыйЭлемент Из ОписаниеЗадания.БлокируемыеЭлементыФормы Цикл
ЗаполнитьЗначенияСвойств(ЭтаФорма.ЭлементыФормы[БлокуемыйЭлемент.Ключ], БлокуемыйЭлемент.Значение);
КонецЦикла;
КонецЕсли;
ОбработатьСообщенияФоновогоЗаданияЛкс(ФоновоеЗадание, ФормаЗадания, Ложь);
Если ПустаяСтрока(ФормаЗадания.ЭлементыФормы.ПолеТекста.ПолучитьТекст()) Тогда
Если ФормаЗадания.Открыта() Тогда
ФормаЗадания.Закрыть();
КонецЕсли;
Иначе
Если ПоЗапросуПользователя Тогда
ФормаЗадания.ЭлементыФормы.ПолеТекста.ДобавитьСтроку("Выполнение прервано пользователем!");
КонецЕсли;
Если Не ФормаЗадания.Открыта() Тогда
ФормаЗадания.Открыть();
КонецЕсли;
КонецЕсли;
Если ЗакрытьФормуЗадания Тогда
Если ФормаЗадания.Открыта() Тогда
ФормаЗадания.Закрыть();
КонецЕсли;
КонецЕсли;
ОписаниеЗадания.УникальныйИдентификатор = Неопределено; // Защита от зацикливания
ОписаниеЗадания.ФормаЗадания = Неопределено;
Если ФормаЗадания.Открыта() Тогда
ФормаЗадания.ОбновитьСостояниеЗадания(ФоновоеЗадание);
КонецЕсли;
КонецПроцедуры
Функция ФормаЗаданияФормыЛкс(Знач ОписаниеЗадания, Знач ФормаВладелец)
ФормаЗадания = ОписаниеЗадания.ФормаЗадания;
Если ФормаЗадания = Неопределено Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаЗадания = мПлатформа.ПолучитьФорму("ФоновоеЗаданиеФормы", ФормаВладелец, ОписаниеЗадания.Имя);
ФормаЗадания.Представление = ОписаниеЗадания.Представление;
ОписаниеЗадания.ФормаЗадания = ФормаЗадания;
КонецЕсли;
Возврат ФормаЗадания;
КонецФункции
// Функция - Прочитать результат фонового задания лкс
//
// Параметры:
// АдресРезультата - -
// ФормаРезультата - УправляемаяФорма - Обработка.ирПлатформа.Форма.РезультатФоновогоЗадания, с ее идентификатором создавался адрес временного хранилища
//
// Возвращаемое значение:
// -
//
Функция ПрочитатьРезультатФоновогоЗаданияЛкс(Знач АдресРезультата, Знач ФормаРезультата = Неопределено) Экспорт
Результат = ПолучитьИзВременногоХранилища(АдресРезультата);
Если Результат = Неопределено И ФормаРезультата <> Неопределено Тогда
// https://www.hostedredmine.com/issues/884756
ФормаРезультата.ОбновитьВременноеХранилище(АдресРезультата); // Тяжелая операция
Результат = ПолучитьИзВременногоХранилища(АдресРезультата);
КонецЕсли;
УдалитьИзВременногоХранилища(АдресРезультата);
Возврат Результат
КонецФункции
Процедура ОтменитьФоновоеЗаданиеОтложенноЛкс(Параметры) Экспорт
ОтменитьФоновоеЗаданиеЛкс(Параметры.ИдентификаторФоновогоЗадания);
КонецПроцедуры
Процедура ОтменитьФоновоеЗаданиеЛкс(Знач ИдентификаторФоновогоЗадания) Экспорт
Если Не ЗначениеЗаполнено(ИдентификаторФоновогоЗадания) Тогда
Возврат;
КонецЕсли;
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторФоновогоЗадания);
Если ФоновоеЗадание <> Неопределено И ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Активно Тогда
ФоновоеЗадание.Отменить();
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
ПроверитьОтмененныеФоновыеЗаданияОтложенноЛкс();
#КонецЕсли
мПлатформа.ОтмененныеФоновыеЗадания.Добавить(ИдентификаторФоновогоЗадания);
ПодключитьГлобальныйОбработчикОжиданияЛкс("ПроверитьОтмененныеФоновыеЗаданияОтложенноЛкс", 2);
КонецЕсли;
КонецПроцедуры
Функция ЗагрузитьТабличныйДокументИнтерактивноЛкс(Знач ТабличныйДокумент = Неопределено, выхПолноеИмяФайла = "") Экспорт
Если ТабличныйДокумент = Неопределено Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
КонецЕсли;
ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДиалогВыбораФайла.Заголовок = "Прочитать табличный документ из файла";
ДиалогВыбораФайла.Фильтр = "Табличный документ (*.mxl)|*.mxl|Лист Excel (*.xls)|*.xls|Лист Excel (*.xlsx)|*.xlsx|Open document (*.ods)|*.ods|Текстовый документ (*.txt)|*.txt|Текстовый документ (*.csv)|*.csv|dBase III (*.dbf)|*.dbf|";
Если ДиалогВыбораФайла.Выбрать() Тогда
выхПолноеИмяФайла = ДиалогВыбораФайла.ПолноеИмяФайла;
ФайлНаДиске = Новый Файл(выхПолноеИмяФайла);
Если Ложь
Или ирОбщий.СтрокиРавныЛкс(ФайлНаДиске.Расширение, ".txt")
Или ирОбщий.СтрокиРавныЛкс(ФайлНаДиске.Расширение, ".csv")
Тогда
ПрочитатьТабличныйДокументИзТекстаЛкс(ТабличныйДокумент, выхПолноеИмяФайла);
ИначеЕсли нРег(ФайлНаДиске.Расширение) = ".dbf" Тогда
ПрочитатьТабличныйДокументИзDBFЛкс(ТабличныйДокумент, выхПолноеИмяФайла);
Иначе
ТабличныйДокумент.Прочитать(выхПолноеИмяФайла);
КонецЕсли;
Иначе
ТабличныйДокумент = Неопределено;
КонецЕсли;
Возврат ТабличныйДокумент;
КонецФункции
Функция СохранитьТабличныйДокументИнтерактивноЛкс(Знач ТабличныйДокументИсточник, выхПолноеИмяФайла = "", Знач СразуОткрыть = Ложь, Знач УстанавливатьПризнакСодержитЗначение = Ложь) Экспорт
Если Не ЗначениеЗаполнено(выхПолноеИмяФайла) Тогда
ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
ДиалогВыбораФайла.Заголовок = "Записать табличный документ в файл";
ДиалогВыбораФайла.Фильтр = "Табличный документ (*.mxl)|*.mxl|Лист Excel (*.xls)|*.xls|Лист Excel (*.xlsx)|*.xlsx|Open document (*.ods)|*.ods|Текстовый документ (*.txt)|*.txt";
Если Не ДиалогВыбораФайла.Выбрать() Тогда
Возврат Ложь;
КонецЕсли;
выхПолноеИмяФайла = ДиалогВыбораФайла.ПолноеИмяФайла;
КонецЕсли;
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.ВставитьОбласть(ТабличныйДокументИсточник.Область(),,, Ложь);
Файл = Новый файл(выхПолноеИмяФайла);
ТипФайла = ТипФайлаТабличногоДокумента.MXL;
Если ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".xls") Тогда
ТипФайла = ТипФайлаТабличногоДокумента.XLS;
Если УстанавливатьПризнакСодержитЗначение Тогда
УстановитьПризнакСодержитЗначение(ТабличныйДокумент);
КонецЕсли;
ИначеЕсли ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".xlsx") Тогда
ТипФайла = ТипФайлаТабличногоДокумента.XLSX;
Если УстанавливатьПризнакСодержитЗначение Тогда
УстановитьПризнакСодержитЗначение(ТабличныйДокумент);
КонецЕсли;
ИначеЕсли ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".ods") Тогда
ТипФайла = ТипФайлаТабличногоДокумента.ODS;
ИначеЕсли ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".txt") Тогда
ТипФайла = ТипФайлаТабличногоДокумента.TXT;
КонецЕсли;
Попытка
ТабличныйДокумент.Записать(выхПолноеИмяФайла, ТипФайла);
Исключение
СообщитьЛкс(ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;
Если Не СразуОткрыть И Не ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".mxl") Тогда
Ответ = Вопрос("Хотите сразу открыть сохраненный файл в сопоставленном приложении?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Да);
СразуОткрыть = Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если СразуОткрыть Тогда
ЗапуститьПриложение(выхПолноеИмяФайла);
КонецЕсли;
Возврат Истина;
КонецФункции
Процедура УстановитьПризнакСодержитЗначение(ТабличныйДокумент)
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
// Проставим свойство СодержитЗначение, чтобы при открытии в EXCEL в строках типа "000534235" не устанавливался формат "Почтовый"
// и не пропадали лидирующие нули при входе в режим редактирования ячейки
Для ТекущаяКолонка = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Для ТекущаяСтрока = 1 По ТабличныйДокумент.ВысотаТаблицы Цикл
ОбластьЯчейки = ТабличныйДокумент.Область(ТекущаяСтрока, ТекущаяКолонка);
ОбластьЯчейки.СодержитЗначение = Истина;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция ПодтверждениеОперацииСУБДЛкс() Экспорт
ИмяБД = ПолучитьСоединениеСУБД().DefaultDatabase;
Возврат Вопрос("Вы осознаете риски и ответственность за использование прямого доступа к данным базы " + ИмяБД + " и нарушение лицензионного соглашения 1С?", РежимДиалогаВопрос.ДаНет) = КодВозвратаДиалога.Да;
КонецФункции
// РежимИмяСиноним - Булево - Истина - Имя
Процедура НастроитьАвтоТабличноеПолеДинамическогоСпискаЛкс(ОсновнойЭУ, РежимИмяСиноним = Ложь, РазрешитьСортировку = Истина, ПредельноеКоличествоВидимыхКолонок = 30) Экспорт
#Если Сервер И Не Сервер Тогда
ОсновнойЭУ = Новый ТабличноеПоле;
#КонецЕсли
// Антибаг платформы 8.2-8.3 для регистра бухгалтерии https://partners.v8.1c.ru/forum/t/1372055/m/1372055
ДинамическийСписок = ирОбщий.ДанныеЭлементаФормыЛкс(ОсновнойЭУ);
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ДинамическийСписок));
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ПолноеИмяТаблицы = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
ТипТаблицы = ирОбщий.ТипТаблицыБДЛкс(ПолноеИмяТаблицы);
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ПолноеИмяМД);
КорневойТип = ПеревестиВРусский(КорневойТип);
//СтруктураХраненияПолей = ирКэш.СтруктураХраненияБДЛкс().НайтиСтроки(Новый Структура("Назначение, Метаданные", "Основная", ПолноеИмяМД))[0].Поля;
ФильтрМетаданных = Новый Массив;
ФильтрМетаданных.Добавить(ПолноеИмяМД);
НуженПеревод = Неопределено;
СтруктураХраненияТаблиц = ПолучитьСтруктуруХраненияБазыДанных(ФильтрМетаданных);
ПеревестиКолонкиСтруктурыХраненияБДТаблицыЛкс(СтруктураХраненияТаблиц, НуженПеревод);
СтруктураХраненияТаблицы = СтруктураХраненияТаблиц.НайтиСтроки(Новый Структура("Назначение, Метаданные", ПеревестиСтроку("Основная"), ПолноеИмяМД))[0];
СтруктураХраненияПолей = СтруктураХраненияТаблицы.Поля;
ПеревестиКолонкиСтруктурыХраненияБДПоляЛкс(СтруктураХраненияПолей, НуженПеревод);
ВерсияПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
Если КорневойТип <> "РегистрБухгалтерии" Тогда
ОсновнойЭУ.СоздатьКолонки();
КонецЕсли;
Попытка
КолонкиСписка = ОсновнойЭУ.Значение.Колонки;
Исключение
// Перечисление
КонецПопытки;
КолонкиТП = ОсновнойЭУ.Колонки;
Колонка = КолонкиТП.Найти("Картинка");
Если Колонка = Неопределено Тогда
КолонкаКартинки = КолонкиТП.Добавить("Картинка");
КолонкаКартинки.ОтображатьСтандартнуюКартинку = Истина;
КолонкаКартинки.Ширина = 4;
КолонкаКартинки.ИзменениеРазмера = ИзменениеРазмераКолонки.НеИзменять;
КолонкаКартинки.ТекстШапки = "";
КонецЕсли;
Попытка
НастройкаПорядка = ОсновнойЭУ.НастройкаПорядка;
Исключение
НастройкаПорядка = Неопределено;
КонецПопытки;
КоличествоВидимыхКолонок = 0;
Если КолонкиСписка <> Неопределено Тогда
// Здесь добавляется колонка "Предопределенный", т.к. в отборе она отсутствует
Для Каждого КолонкаСписка Из ОсновнойЭУ.Значение.Колонки Цикл
Колонка = КолонкиТП.Найти(КолонкаСписка.Имя);
Если Колонка = Неопределено Тогда
Колонка = КолонкиТП.Добавить(КолонкаСписка.Имя);
Попытка
Колонка.Данные = КолонкаСписка.Имя;
Исключение
// Например поле "Ссылка" почему то является недопустимым
КолонкиТП.Удалить(Колонка);
Продолжить;
КонецПопытки;
КонецЕсли;
Колонка.ТекстШапки = КолонкаСписка.Имя;
ЭлементОтбора = ОсновнойЭУ.Значение.Отбор.Найти(КолонкаСписка.Имя);
Если Истина
И КолонкаСписка.Имя = "Предопределенный"
И ЭлементОтбора = Неопределено
Тогда
Колонка.КартинкаШапки = ирКэш.КартинкаПоИмениЛкс("ирПредопределенный");
Колонка.Ширина = 4;
Колонка.ИзменениеРазмера = ИзменениеРазмераКолонки.НеИзменять;
КонецЕсли;
Если ЭлементОтбора <> Неопределено И ЛиОписаниеТиповБулевоЛкс(ЭлементОтбора.ТипЗначения) Тогда // https://www.hostedredmine.com/issues/905911
Если КолонкаСписка.Имя = "ПометкаУдаления" Тогда
Колонка.КартинкаШапки = ирКэш.КартинкаПоИмениЛкс("ПометитьНаУдаление");
Колонка.Ширина = 4;
Колонка.ИзменениеРазмера = ИзменениеРазмераКолонки.НеИзменять;
КонецЕсли;
Если КолонкаСписка.Имя = "Проведен" Тогда
Колонка.КартинкаШапки = ирКэш.КартинкаПоИмениЛкс("Провести");
Колонка.Ширина = 4;
Колонка.ИзменениеРазмера = ИзменениеРазмераКолонки.НеИзменять;
КонецЕсли;
Если КолонкаСписка.Имя = "Активность" Тогда
Колонка.КартинкаШапки = ирКэш.КартинкаПоИмениЛкс("ПереключитьАктивность");
Колонка.Ширина = 4;
Колонка.ИзменениеРазмера = ИзменениеРазмераКолонки.НеИзменять;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Для Каждого ЭлементОтбора Из ОсновнойЭУ.Значение.Отбор Цикл
Колонка = КолонкиТП.Найти(ЭлементОтбора.Имя);
Если Колонка = Неопределено Тогда
// Антибаг 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].ИмяПоля = ПредопределенноеПоле Тогда
ЭлементПорядка.Доступность = Истина;
НовыйПорядок = ПредопределенноеПоле;
Прервать;
КонецЕсли;
КонецЦикла;
Если ЭлементПорядка.Доступность Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЗначениеЗаполнено(НовыйПорядок) Тогда
// Обязательную установку делаем, чтобы в шапках появились индикаторы сортировки (антибаг платформы)
ДинамическийСписок.Порядок.Установить(НовыйПорядок);
КонецЕсли;
//Компоновщик = ирКэш.КомпоновщикТаблицыМетаданныхЛкс(ОбъектМД.ПолноеИмя());
//#Если Сервер И Не Сервер Тогда
// Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
//#КонецЕсли
//Для Каждого ПолеВыбора Из Компоновщик.Настройки.ДоступныеПоляВыбора.Элементы Цикл
// Если ПолеВыбора.Папка Тогда
// Продолжить;
// КонецЕсли;
//КонецЦикла;
КонецЕсли;
Если ЛиКорневойТипСсылкиЛкс(КорневойТип) Тогда
КолонкаИдентификатора = КолонкиТП.Добавить("ИдентификаторСсылкиЛкс");
КолонкаИдентификатора.ТекстШапки = "Идентификатор ссылки";
КонецЕсли;
Если ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда
КолонкаИдентификатора = КолонкиТП.Добавить("ИмяПредопределенныхДанных");
КолонкаИдентификатора.ТекстШапки = "Имя предопределенных данных";
КолонкаИдентификатора.Видимость = Ложь;
КонецЕсли;
НастроитьЗаголовкиАвтоТабличногоПоляДинамическогоСпискаЛкс(ОсновнойЭУ, РежимИмяСиноним);
КонецПроцедуры
Функция ЛиОписаниеТиповБулевоЛкс(Знач ТипЗначения)
Возврат Истина
И ТипЗначения.СодержитТип(Тип("Булево"))
И ТипЗначения.Типы().Количество() = 1;
КонецФункции
Процедура НастроитьЗаголовкиАвтоТабличногоПоляДинамическогоСпискаЛкс(Знач ОсновнойЭУ, Знач РежимИмяСиноним) Экспорт
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ОсновнойЭУ.Значение));
ПоляТаблицы = ПоляТаблицыМДЛкс(ОбъектМД.ПолноеИмя());
Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл
Колонка = ОсновнойЭУ.Колонки.Найти(ПолеТаблицы.Имя);
Если Колонка = Неопределено Тогда
Продолжить;
КонецЕсли;
Если РежимИмяСиноним Тогда
Колонка.ТекстШапки = ПолеТаблицы.Имя;
Иначе
Колонка.ТекстШапки = ПолеТаблицы.Заголовок;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ФормаОбработкаОповещенияЛкс(ЭтаФорма, ИмяСобытия, Параметр, Источник) Экспорт
Если ИмяСобытия = "ЗакрытьВсеФормыИнструментовРазработчика" Тогда
Если ЭтаФорма.Открыта() Тогда
ЭтаФорма.Закрыть();
Если ЭтаФорма.Открыта() Тогда
Параметр.Отказ = Истина;
КонецЕсли;
КонецЕсли;
ИначеЕсли ИмяСобытия = "ЕстьОткрытыеФормыИнструментовРазработчика" Тогда
Если ЭтаФорма.Открыта() Тогда
Параметр.Ответ = Истина;
КонецЕсли;
ИначеЕсли ИмяСобытия = "ОбнаружитьСебя" Тогда
ИмяФормы = ИмяФормыИзФормыЛкс(ЭтаФорма);
Если Не ЗначениеЗаполнено(ИмяФормы) Тогда
Попытка
ИмяФормы = ЭтаФорма.ЭтотОбъект.Метаданные().ПолноеИмя();
Исключение
КонецПопытки;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяФормы) Тогда
ИмяФормы = "Неизвестная форма";
КонецЕсли;
СообщитьЛкс(ИмяФормы);
ИначеЕсли ИмяСобытия = "ОбнаружитьАктивную" Тогда
Если ЭтаФорма.ВводДоступен() Тогда
Параметр.Результат = ЭтаФорма;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Умеет определять активную форму инструментов и управляемую форму в управляемом приложении
Функция АктивнаяФормаЛкс() Экспорт
Результат = АктивнаяУправляемаяФормаЛкс();
Если Результат = Неопределено Тогда
Структура = Новый Структура("Результат");
ОповеститьФормыПодсистемыЛкс("ОбнаружитьАктивную", Структура);
Результат = Структура.Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОткрытьФайлСПредупреждениемЛкс(ИмяФайла, СтандартнаяОбработка = Неопределено) Экспорт
СтандартнаяОбработка = Ложь;
Ответ = Вопрос("Вы уверены, что хотите открыть """ + ИмяФайла + """?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
ЗапуститьПриложение(ИмяФайла);
КонецЕсли;
КонецПроцедуры
// Создает новый экземпляр обработки и открывает его форму.
//
// Параметры:
// Объект - ОбработкаОбъект, ОтчетОбъект.
//
// Возвращаемое значение:
// Форма.
//
Функция ОткрытьНовоеОкноФормыЛкс(ЭтотОбъект) Экспорт
Если Ложь
Или ТипЗнч(ЭтотОбъект) = Тип("Форма")
Или ТипЗнч(ЭтотОбъект) = Тип("УправляемаяФорма")
Тогда
Результат = ПолучитьФормуЛкс(ИмяФормыИзФормыЛкс(ЭтотОбъект),,, Новый УникальныйИдентификатор);
Иначе
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
НовыйОбъект = ПолучитьМенеджерЛкс(ЭтотОбъект).Создать();
Иначе
ПолноеИмяОбъекта = ЭтотОбъект.Метаданные().ПолноеИмя();
НовыйОбъект = СоздатьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяОбъекта);
КонецЕсли;
Результат = НовыйОбъект.ПолучитьФорму();
КонецЕсли;
Результат.Открыть();
Возврат Результат;
КонецФункции // ОткрытьНовоеОкноОбработкиЛкс()
Функция ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры = Неопределено, Владелец = Неопределено, Уникальность = Неопределено, Окно = Неопределено, ТолькоВнешниеФормы = Ложь) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
//ирПортативный #Если Сервер И Не Сервер Тогда
// Такой прием нужен для обхода ошибка компиляции в портативном режиме
Фрагменты = СтрРазделитьЛкс(ПолноеИмяФормы);
#Если Сервер И Не Сервер Тогда
Фрагменты = Новый Массив;
#КонецЕсли
// http://www.hostedredmine.com/issues/883626
Если Истина
И (Фрагменты[0] = "Обработка" Или Фрагменты[0] = "Отчет")
И Фрагменты.Количество() > 2
И Найти(Фрагменты[1], "ир") = 1
И Фрагменты[1] <> Метаданные.Обработки.ирДинамическийСписок.Имя
Тогда
Если Не ТолькоВнешниеФормы Тогда
ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(Фрагменты[0] + "." + Фрагменты[1]);
КонецЕсли;
Если ОбъектМД = Неопределено Тогда
ВызватьИсключение "Не найден объект метаданных " + ПолноеИмяФормы;
КонецЕсли;
Если Истина
И СтрокиРавныЛкс(Фрагменты[2], "Форма")
И Фрагменты.Количество() = 4
Тогда
ИмяФормы = Фрагменты[3];
Иначе
ИмяФормы = Неопределено;
КонецЕсли;
//Если ОбъектМД = Метаданные.Обработки.ирПлатформа Тогда
// Менеджер = ирКэш.Получить(); // Так управляемые формы нельзя получать
//Иначе
Менеджер = Новый (ПеревестиСтроку(Фрагменты[0]) + ПеревестиСтроку("Менеджер") + "." + Фрагменты[1]);
//КонецЕсли;
Результат = Менеджер.ПолучитьФорму(ИмяФормы, Владелец, Уникальность);
Иначе
Результат = ПолучитьФорму(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
КонецЕсли;
Если Найти(ПолноеИмяФормы, "Обработка.ирПлатформа.") = 1 Тогда
Попытка
ЭтоЗапрещено = Результат.ЭтотОбъект.Метаданные().ПолноеИмя() = ПеревестиСтроку("Обработка") + ".ирПлатформа";
Исключение
ЭтоЗапрещено = Ложь;
КонецПопытки;
Если ЭтоЗапрещено Тогда
СообщитьЛкс("Создан лишний экземпляр обработки ирПлатформа");
КонецЕсли;
КонецЕсли;
//ирПортативный #КонецЕсли
Иначе
Фрагменты = СтрРазделитьЛкс(ПолноеИмяФормы);
Если Не ТолькоВнешниеФормы Тогда
ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(Фрагменты[0] + "." + Фрагменты[1]);
КонецЕсли;
Если ОбъектМД = Неопределено Тогда
Если Истина
И СтрокиРавныЛкс(Фрагменты[2], "Форма")
И Фрагменты.Количество() = 4
Тогда
ИмяФормы = Фрагменты[3];
Иначе
ИмяФормы = Неопределено;
КонецЕсли;
Если Фрагменты[1] = "ирПортативный" Тогда
Результат = ирПортативный.ПолучитьФорму(ИмяФормы, Владелец, Уникальность);
Иначе
ТипМетаданных = Фрагменты[0];
Менеджер = ирПортативный.ПолучитьМенеджерТипаМетаданныхЛкс(ТипМетаданных);
ПолноеИмяФайла = ирПортативный.ПолучитьПолноеИмяФайлаПортативногоОбъектаМетаданныхЛкс(Фрагменты[1], ТипМетаданных);
Результат = Менеджер.ПолучитьФорму(ПолноеИмяФайла, ИмяФормы, Владелец, Уникальность);
КонецЕсли;
Иначе
Результат = ирПортативный.ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ЗаполнитьСписокВыбораПоляСортировкиТабличногоПоляЛкс(Знач СписокВыбора, Знач ТабличноеПоле) Экспорт
#Если Сервер И Не Сервер Тогда
СписокВыбора = Новый СписокЗначений;
#КонецЕсли
СписокВыбора.Очистить();
Для Каждого КолонкаТП Из ТабличноеПоле.Колонки Цикл
Если Истина
И ЗначениеЗаполнено(КолонкаТП.Данные)
И (КолонкаТП.Видимость Или КолонкаТП.ИзменятьВидимость)
//И Не (КолонкаТП.ТипЗначения.СодержитТип(Тип("УникальныйИдентификатор")) И КолонкаТП.ТипЗначения.Типы() = 1)
Тогда
СписокВыбора.Добавить(КолонкаТП.Данные + " Убыв", КолонкаТП.ТекстШапки + " Убыв");
СписокВыбора.Добавить(КолонкаТП.Данные + " Возр", КолонкаТП.ТекстШапки + " Возр");
КонецЕсли;
КонецЦикла;
СписокВыбора.СортироватьПоПредставлению();
КонецПроцедуры
Функция СсылкаОсновногоОбъектаФормыЛкс(Знач ТекущаяФорма) Экспорт
ИмяОсновногоРеквизита = "Объект";
Попытка
Ссылка = ТекущаяФорма[ИмяОсновногоРеквизита].Ссылка;
Исключение
ИмяОсновногоРеквизита = ирОбщий.ПеревестиСтроку(ИмяОсновногоРеквизита);
Ссылка = Неопределено;
КонецПопытки;
Если Ссылка = Неопределено Тогда
Попытка
Ссылка = ТекущаяФорма[ИмяОсновногоРеквизита].Ссылка;
Исключение
Ссылка = Неопределено;
КонецПопытки;
КонецЕсли;
Возврат Ссылка;
КонецФункции
Функция ПолучитьЦветСтиляЛкс(ИмяЦвета) Экспорт
//Результат = ирПортативный.ПолучитьЦветСтиляЛкс(Имя);
Если ИмяЦвета = "ирТекстИнформационнойНадписи" Тогда
Возврат Новый Цвет(83, 106, 194);
ИначеЕсли ИмяЦвета = "ирЦветФонаЧередованияСтрок" Тогда
//Возврат WebЦвета.МятныйКрем;
Возврат Новый Цвет(240, 255, 225);
ИначеЕсли ИмяЦвета = "ирЦветФонаВычисляемогоЗначения" Тогда
Возврат WebЦвета.ГолубойСКраснымОттенком;
ИначеЕсли ИмяЦвета = "ирЦветФонаОшибки" Тогда
Возврат Новый Цвет(255, 235, 235);
ИначеЕсли ИмяЦвета = "ирЦветФонаРасширенногоПредставленияЗначения" Тогда
Возврат Новый Цвет(255, 255, 180);
Иначе
Результат = ЦветаСтиля[ИмяЦвета];
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// Значение -
// ОчиститьПередУстановкой - Булево
// УстановитьТекст - Булево
// УстановитьЗначение - Булево
//
Функция БуферОбмена_УстановитьЗначениеЛкс(Знач Значение) Экспорт
ФорматБуфераОбмена1С = ирКэш.ФорматБуфераОбмена1СЛкс();
ВнутреннееЗначение = СохранитьОбъектВВидеСтрокиXMLЛкс(Значение,,, Ложь);
ВнутреннийБуферОбмена = ирКэш.ВнутреннийБуферОбмена();
ВнутреннийБуферОбмена.Значение = ВнутреннееЗначение;
КонецФункции
Функция БуферОбмена_ПолучитьЗначениеЛкс()
ФорматБуфераОбмена1С = ирКэш.ФорматБуфераОбмена1СЛкс();
ВнутреннийБуферОбмена = ирКэш.ВнутреннийБуферОбмена();
СтрокаXML = ВнутреннийБуферОбмена.Значение;
Результат = ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаXML,,, Ложь);
Возврат Результат;
КонецФункции
Функция СсылкаИзБуфераОбменаЛкс() Экспорт
ТекстИзБуфера = ПолучитьТекстИзБуфераОбменаОСЛкс();
ЗначениеСсылки = НавигационнаяСсылкаВЗначениеЛкс(ТекстИзБуфера);
Если ЗначениеСсылки = Неопределено Тогда
ЗначениеСсылки = БуферОбмена_ПолучитьЗначениеЛкс();
КонецЕсли;
Возврат ЗначениеСсылки;
КонецФункции
// Параметры:
// ПолеВвода - ПолеВвода
// Значение -
// Текст - Строка(0,П)
//
Функция ВставитьЗначениеВПолеВводаЛкс(Знач ПолеВвода, Знач НовоеЗначение) Экспорт
Результат = Ложь;
Если Истина
И НовоеЗначение <> Неопределено
И Не ПолеВвода.ТолькоПросмотр
Тогда
ТипНовогоЗначения = ТипЗнч(НовоеЗначение);
ТекущееЗначение = ДанныеЭлементаФормыЛкс(ПолеВвода);
Если Ложь
Или ТипЗнч(ТекущееЗначение) = ТипНовогоЗначения
Или ПолеВвода.ОграничениеТипа.Типы().Количество() = 0
Или ПолеВвода.ОграничениеТипа.СодержитТип(ТипНовогоЗначения)
Тогда
Результат = ИнтерактивноЗаписатьВЭлементУправленияЛкс(ПолеВвода, НовоеЗначение);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ЭтаФорма - Форма - для управляемой формы можно не передавать, она определится автоматически
//
Функция БуферОбмена_ВставитьЛкс(Знач ЭтаФорма = Неопределено) Экспорт
Если ЭтаФорма = Неопределено Тогда
ЭтаФорма = ирОбщий.АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если ЭтаФорма = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Значение = СсылкаИзБуфераОбменаЛкс();
Если Значение = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ВставитьЗначениеВФормуЛкс(ЭтаФорма, Значение);
КонецФункции
Процедура ВставитьЗначениеВФормуЛкс(Знач ЭтаФорма, Знач Значение) Экспорт
ТекущийЭлементФормы = ЭтаФорма.ТекущийЭлемент;
ПродолжитьОбработку = Истина;
ТипЗначения = ТипЗнч(Значение);
ПутьКДанным = "";
Если Ложь
Или ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеВвода")
Или ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеФормы")
Тогда
Если Не ЭтаФорма.ТолькоПросмотр Тогда
Если ТипЗначения = Тип("Массив") Тогда
Значение = Значение[0];
КонецЕсли;
ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ТекущийЭлементФормы, Значение);
//Если ПродолжитьОбработку И ЗначениеЗаполнено(ТекущийЭлементФормы.Данные) Тогда
// // Например ссылка таблицы внешнего источника в поле ввода не может быть установлена через оповещение выбора
// Попытка
// ЭтаФорма[ТекущийЭлементФормы.Данные] = Значение;
// Исключение
// КонецПопытки;
//КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле")
Или ТипЗнч(ТекущийЭлементФормы) = Тип("ТаблицаФормы")
Тогда
Попытка
РедактированиеВДиалоге = ТекущийЭлементФормы.СпособРедактирования = СпособРедактированияСписка.ВДиалоге;
Исключение
РедактированиеВДиалоге = Ложь;
КонецПопытки;
Если ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле") Тогда
Колонка = ТекущийЭлементФормы.ТекущаяКолонка;
ЭлементУправления = Колонка.ЭлементУправления;
Иначе
Колонка = ТекущийЭлементФормы.ТекущийЭлемент;
ЭлементУправления = Колонка;
КонецЕсли;
Если Истина
И Не РедактированиеВДиалоге
И Не ЭтаФорма.ТолькоПросмотр
И Не ТекущийЭлементФормы.ТолькоПросмотр
И Колонка <> Неопределено
И (Ложь
Или ТипЗнч(ЭлементУправления) = Тип("ПолеВвода")
Или ТипЗнч(ЭлементУправления) = Тип("ПолеФормы"))
И Не ЭлементУправления.ТолькоПросмотр
Тогда
ДобавитьСтроку = Истина
И ТекущийЭлементФормы.ТекущиеДанные = Неопределено
И ТекущийЭлементФормы.ИзменятьСоставСтрок;
Если Истина
И Значение <> Неопределено
И ТекущийЭлементФормы.ИзменятьСоставСтрок
И Не ДобавитьСтроку
Тогда
Ответ = Вопрос("Выполнить вставку значения в новую строку (иначе будет выполнена вставка в текущую)?", РежимДиалогаВопрос.ДаНет,
, КодВозвратаДиалога.Нет);
ДобавитьСтроку = Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если ДобавитьСтроку Тогда
ТекущийЭлементФормы.ДобавитьСтроку();
ТабличноеПоле_УстановитьТекущуюКолонкуЛкс(ТекущийЭлементФормы, Колонка);
КонецЕсли;
Если ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено Тогда
ТекущийЭлементФормы.ИзменитьСтроку(); // Нужно делать, т.к. табличное поле выходит из режима редактирования строку при вызове команды и иногда установке текущей колонки
КонецЕсли;
Если ТекущийЭлементФормы.ТекущиеДанные <> Неопределено Тогда
Если ТипЗначения = Тип("Массив") Тогда
Значение = Значение[0];
КонецЕсли;
ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ЭлементУправления, Значение);
ИмяКолонкиДанных = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТекущийЭлементФормы);
Если ПродолжитьОбработку И ЗначениеЗаполнено(ИмяКолонкиДанных) Тогда
// Например ссылка таблицы внешнего источника в поле ввода не может быть установлена через оповещение выбора
Если ТипЗнч(ТекущийЭлементФормы.ТекущиеДанные) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
ИмяКолонкиДанных = ПервыйФрагментЛкс(ИмяКолонкиДанных, "Для");
КонецЕсли;
Попытка
ТекущийЭлементФормы.ТекущиеДанные[ИмяКолонкиДанных] = Значение;
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Параметры:
// ЭтаФорма - Форма - для управляемой формы можно не передавать, она определится автоматически
//
Функция БуферОбмена_КопироватьЛкс(Знач ЭтаФорма = Неопределено) Экспорт
Если ЭтаФорма = Неопределено Тогда
ЭтаФорма = ирОбщий.АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если ЭтаФорма = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Значение = Неопределено;
ЕстьСсылкиВТекущемПоле = ирОбщий.СсылкиИзТекущейКолонкиВыделенныхСтрокТаблицыЛкс(ЭтаФорма, Значение, Ложь).Количество() > 0;
Если Не ЕстьСсылкиВТекущемПоле Тогда
ТекущийЭлементФормы = ЭтаФорма.ТекущийЭлемент;
Если ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеВвода") Тогда
Значение = ДанныеЭлементаФормыЛкс(ТекущийЭлементФормы);
//Текст = "" + ТекущийЭлементФормы.ВыделенныйТекст;
Если ТипЗнч(Значение) = Тип("Строка") Тогда
Значение = Неопределено;
КонецЕсли;
ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле") Тогда
//:ТекущийЭлементФормы = Новый ("ТабличноеПоле")
Если Истина
И ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено
И ТекущийЭлементФормы.ТекущаяКолонка <> Неопределено
Тогда
Ячейка = ТекущийЭлементФормы.ОформлениеСтроки(ТекущийЭлементФормы.ТекущаяСтрока).Ячейки[ТекущийЭлементФормы.ТекущаяКолонка.Имя];
Значение = Ячейка.Значение;
Если ТипЗнч(Значение) = Тип("Строка") Тогда
Если ПустаяСтрока(Прав(Значение, 1)) Тогда
// https://www.hostedredmine.com/issues/910752
Массив = Новый Массив;
Массив.Добавить(ТекущийЭлементФормы.ТекущаяСтрока);
ПолноеИмяТаблицыБД = "";
ОбщийТипДанныхТабличногоПоляЛкс(ТекущийЭлементФормы,,, ПолноеИмяТаблицыБД);
Если ЗначениеЗаполнено(ПолноеИмяТаблицыБД) Тогда
ТаблицаЗначений = ПустаяТаблицаЗначенийИзТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Иначе
ТаблицаЗначений = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТекущийЭлементФормы, Массив);
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
Если ТаблицаЗначений <> Неопределено Тогда
КолонкаТаблицы = ТаблицаЗначений.Колонки.Найти(ПутьКДаннымКолонкиТабличногоПоляЛкс(ТекущийЭлементФормы));
Если Ложь
Или КолонкаТаблицы = Неопределено
Или КолонкаТаблицы.ТипЗначения.КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная
Тогда
ПоместитьТекстВБуферОбменаОСЛкс(Значение, "");
КонецЕсли;
КонецЕсли;
КонецЕсли;
ТипСтрокиТаблицы = ТипЗнч(ТекущийЭлементФормы.ТекущаяСтрока);
Если Ложь
Или ТипСтрокиТаблицы = Тип("ДоступноеПолеКомпоновкиДанных")
Или ТипСтрокиТаблицы = Тип("ДоступноеПолеОтбораКомпоновкиДанных")
Тогда
Значение = ТекущийЭлементФормы.ТекущаяСтрока.Поле;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеТабличногоДокумента") Тогда
#Если Сервер И Не Сервер Тогда
ТекущийЭлементФормы = Новый ТабличныйДокумент;
#КонецЕсли
Попытка
ДанныеРасшифровки = ЭтаФорма.ДанныеРасшифровки;
Исключение
ДанныеРасшифровки = Неопределено;
КонецПопытки;
Если ТекущийЭлементФормы.ТекущаяОбласть <> Неопределено Тогда
// Так будем терять оформление
//Значение = ТекущийЭлементФормы.ТекущаяОбласть.Текст;
//Если ПустаяСтрока(Прав(Значение, 1)) Тогда
// ПоместитьТекстВБуферОбменаОСЛкс(Значение, "");
//КонецЕсли;
Если Истина
И ТипЗнч(ДанныеРасшифровки) = Тип("ДанныеРасшифровкиКомпоновкиДанных")
И ТипЗнч(ТекущийЭлементФормы.ТекущаяОбласть.Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных")
Тогда
ЭлементРасшифровки = ДанныеРасшифровки.Элементы[ТекущийЭлементФормы.ТекущаяОбласть.Расшифровка];
Для каждого ЗначениеПоля Из ЭлементРасшифровки.ПолучитьПоля() Цикл
Если Не ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение, Ложь) Тогда
Продолжить;
КонецЕсли;
Значение = ЗначениеПоля.Значение;
Прервать;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Значение <> Неопределено Тогда
БуферОбмена_УстановитьЗначениеЛкс(Значение);
КонецЕсли;
КонецФункции
Функция ОткрытьРазличныеЗначенияКолонкиЛкс(Знач ТабличноеПоле, Знач НастройкиСписка = Неопределено, Знач АдресСхемыКомпоновки = Неопределено, ЭтаФорма = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Обработки.ирРазличныеЗначенияКолонки;
#КонецЕсли
Форма = ирОбщий.ПолучитьФормуЛкс("Обработка.ирРазличныеЗначенияКолонки.Форма",, ТабличноеПоле);
Форма.НастройкиСписка = НастройкиСписка;
Форма.АдресСхемыКомпоновки = АдресСхемыКомпоновки;
Форма.Форма = ЭтаФорма;
Форма.ОткрытьМодально();
КонецФункции
Функция ОткрытьГруппировкуТабличногоПоляЛкс(Знач ТабличноеПоле, Знач НастройкиСписка = Неопределено, ИменаКлючевыхКолонок = "") Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Форма = мПлатформа.ПолучитьФорму("ГруппировкаТаблицы", ТабличноеПоле);
Форма.НастройкиСписка = НастройкиСписка;
Форма.ПараметрИменаКлючевыхКолонок = ИменаКлючевыхКолонок;
Форма.Открыть();
КонецФункции
Процедура ПоказатьСсылкуНаМодульКонфигурацииЛкс(ПолноеИмяМодуля) Экспорт
Ссылка = СсылкаНаМодульКонфигурацииЛкс(ПолноеИмяМодуля);
Текст = //""
"
|" + Ссылка + "
|Запустите программу ClipAngel, скопируйте эту ссылку и откройте ее в конфигураторе через эту программу
|"
//""
;
Форма = ФормаПросмотраHTMLЛкс(Текст);
Форма.ОткрытьМодально();
КонецПроцедуры
Функция СсылкаНаМодульКонфигурацииЛкс(Знач ПолноеИмяМодуля) Экспорт
Возврат "{" + ПолноеИмяМодуля + "(1)}";
КонецФункции
Процедура СкрытьПоказатьОднозначныеКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, Знач Скрыть = Истина, Знач ИгнорироватьКолонки = Неопределено) Экспорт
ОставитьТолькоРазличающиесяКолонки = Ложь;
Если Скрыть Тогда
// Включаем видимость тех колонок реквизитов, в каких есть различия между элементами группы, а у остальных выключаем
Если ТабличноеПоле.Значение.Количество() > 1 Тогда
ОставитьТолькоРазличающиесяКолонки = Истина;
КонецЕсли;
КонецЕсли;
Для Каждого КолонкаТП Из ТабличноеПоле.Колонки Цикл
Если Ложь
Или (Истина
И ИгнорироватьКолонки <> Неопределено
И ЗначениеЗаполнено(КолонкаТП.Данные)
И ИгнорироватьКолонки.Свойство(КолонкаТП.Данные))
Или ТабличноеПоле.Значение.Колонки.Найти(КолонкаТП.Данные) = Неопределено
Тогда
Продолжить;
КонецЕсли;
Если ОставитьТолькоРазличающиесяКолонки Тогда
ПервоеЗначение = ТабличноеПоле.Значение[0][КолонкаТП.Данные];
Для Индекс = 1 По ТабличноеПоле.Значение.Количество() - 1 Цикл
ТекущееЗначение = ТабличноеПоле.Значение[Индекс][КолонкаТП.Данные];
Если ПервоеЗначение <> ТекущееЗначение Тогда
Прервать;
КонецЕсли;
КонецЦикла;
НоваяВидимость = ПервоеЗначение <> ТекущееЗначение;
Иначе
НоваяВидимость = Истина;
КонецЕсли;
КолонкаТП.Видимость = НоваяВидимость;
КонецЦикла;
КонецПроцедуры
Процедура Форма_ПриОткрытииЛкс(ЭтаФорма) Экспорт
ирКэш.СостояниеПодготовкиТаблицыВсехТаблицБДЛкс();
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
ЭтаФорма = ПолучитьОбщуюФорму();
#КонецЕсли
Если ЭтаФорма.МодальныйРежим Тогда
мПлатформа.СчетчикМодальныхФорм.Добавить(1);
КонецЕсли;
мПлатформа.ПодключитьПерехватКлавиатуры().ЗахватПервым = Ложь; // Используем не по назначению
Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда
ДобавитьВСписокОткрытыхФормЛкс(ЭтаФорма);
ДобавитьИнструментВИсториюРаботыЛкс(ЭтаФорма);
ЭтаФорма.УстановитьДействие("ВнешнееСобытие", Неопределено); // Будем вызывать напрямую, чтобы платформа не вызывала обновление всех форм
ЭтаФорма.УстановитьДействие("ОбработкаОповещения", Неопределено); // Будем вызывать напрямую, чтобы платформа не вызывала обновление всех форм
//Если СлужебныеДанныеФормы.ОбработчикиПриВыводеСтроки.Количество() > 0 Тогда
// ИмяОбработчика = "ТабличноеПолеПриПолученииДанных";
// Если Не МетодРеализованЛкс(ЭтаФорма, ИмяОбработчика) Тогда
// СообщитьЛкс("В модуле " + СлужебныеДанныеФормы.ИмяФормы + " отсутствует экспортный обработчик """ + ИмяОбработчика + """");
// Иначе
// Для Каждого КлючИЗначение Из СлужебныеДанныеФормы.ОбработчикиПриВыводеСтроки Цикл
// ИмяОбработчика = КлючИЗначение.Значение;
// Если Не МетодРеализованЛкс(ЭтаФорма, ИмяОбработчика) Тогда
// СообщитьЛкс("В модуле " + СлужебныеДанныеФормы.ИмяФормы + " отсутствует экспортный обработчик """ + ИмяОбработчика + """ для табличного поля """ + КлючИЗначение.Ключ + """");
// КонецЕсли;
// КонецЦикла;
// КонецЕсли;
//КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьВСписокОткрытыхФормЛкс(ЭтаФорма) Экспорт
ирКэш.ОткрытыеФормыЛкс().Добавить(ЭтаФорма);
СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
СлужебныеДанныеФормы.Вставить("ДатаОткрытия", ТекущееВремяВМиллисекундахЛкс());
КонецПроцедуры
Процедура Форма_ПриЗакрытииЛкс(ЭтаФорма, СохранитьНастройкуПоУмолчанию = Истина) Экспорт
// У некоторых из-за большого объема данных в настройках пользователя это вызывает большие задержки
//ПодключитьГлобальныйОбработчикОжиданияЛкс("СохранитьНастройкиПользователяОтложенноЛкс");
СохранитьНастройкуФормыЛкс(ЭтаФорма);
ЗаданияФормы = Неопределено;
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ЭтаФорма);
#Если Сервер И Не Сервер Тогда
СлужебныеДанные = Новый Структура;
#КонецЕсли
Для Каждого КлючИЗначение Из СлужебныеДанные.Задания Цикл
ОтменитьЗаданиеФормыЛкс(ЭтаФорма, КлючИЗначение.Значение, Истина);
КонецЦикла;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СчетчикМодальныхФорм = мПлатформа.СчетчикМодальныхФорм;
Если СчетчикМодальныхФорм.Количество() > 0 Тогда
КоличествоФормВТекущемМодальномПространстве = СчетчикМодальныхФорм[СчетчикМодальныхФорм.ВГраница()];
КоличествоФормВТекущемМодальномПространстве = КоличествоФормВТекущемМодальномПространстве - 1;
Если КоличествоФормВТекущемМодальномПространстве = 0 Тогда
СчетчикМодальныхФорм.Удалить(СчетчикМодальныхФорм.ВГраница());
Иначе
СчетчикМодальныхФорм[СчетчикМодальныхФорм.ВГраница()] = КоличествоФормВТекущемМодальномПространстве;
КонецЕсли;
КонецЕсли;
ОткрытыеФормы = ирКэш.ОткрытыеФормыЛкс();
Пока Истина Цикл
ПозицияОткрытой = ОткрытыеФормы.Найти(ЭтаФорма);
Если ПозицияОткрытой = Неопределено Тогда
Прервать;
КонецЕсли;
ОткрытыеФормы.Удалить(ПозицияОткрытой);
КонецЦикла;
КонецПроцедуры
Функция ОтменитьЗаданиеФормыЛкс(Знач ЭтаФорма, Знач ОписаниеЗадания, Знач ЗакрытьФормуЗадания = Ложь)
Если Не ЗначениеЗаполнено(ОписаниеЗадания.УникальныйИдентификатор) Тогда
Возврат Ложь;
КонецЕсли;
ЗаданияФормы = ирОбщий.СлужебныеДанныеФормыЛкс(ЭтаФорма).Задания;
#Если Сервер И Не Сервер Тогда
ЗаданияФормы = Новый Структура;
#КонецЕсли
ОтменитьФоновоеЗаданиеЛкс(ОписаниеЗадания.УникальныйИдентификатор);
ОбработатьЗавершениеЗаданияФормыЛкс(ОписаниеЗадания, ЭтаФорма,, Истина, ЗакрытьФормуЗадания);
ПроверитьЗавершениеФоновыхЗаданийФормыЛкс(ЭтаФорма);
Возврат Истина;
КонецФункции
Процедура УдалитьСсылкиНаЗакрытыеФормыЛкс(ЭтаФорма = Неопределено) Экспорт
УдалитьФормы = Новый Массив;
ОткрытыеФормы = Новый Массив;
Для Каждого Форма Из ОткрытыеФормы Цикл
Если ЭтаФорма = Форма Или Форма.Открыта() Тогда
Продолжить;
КонецЕсли;
УдалитьФормы.Добавить(Форма);
КонецЦикла;
Для Каждого Форма Из УдалитьФормы Цикл
ирОбщий.СообщитьЛкс("Удалена ссылка на закрытую ранее форму """ + Форма.Заголовок + """");
ОткрытыеФормы.Удалить(ОткрытыеФормы.Найти(Форма));
КонецЦикла;
КонецПроцедуры
Процедура ОповеститьФормыПодсистемыЛкс(ИмяСобытия = Неопределено, Параметр = Неопределено, Источник = Неопределено, Знач ЭтаФорма = Неопределено) Экспорт
Если ЭтаФорма = Неопределено Тогда
ЭтаФорма = Источник;
КонецЕсли;
УдалитьСсылкиНаЗакрытыеФормыЛкс(ЭтаФорма);
// Копируем, чтобы в процессе оповещения массив не менял состав
ОткрытыеФормы = СкопироватьУниверсальнуюКоллекциюЛкс(ирКэш.ОткрытыеФормыЛкс());
Для Каждого Форма Из ОткрытыеФормы Цикл
Если МетодРеализованЛкс(Форма, "ОбработкаОповещения") Тогда
Форма.ОбработкаОповещения(ИмяСобытия, Параметр, Источник);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма) Экспорт
Если ЭтаФорма.МодальныйРежим Тогда
Ответ = Вопрос("Хотите закрыть текущую форму, чтобы открыть новую форму немодально?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Да Тогда
ЭтаФорма.Закрыть();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ЗапроситьСохранениеДанныхФормыЛкс(ЭтаФорма) Экспорт
Если ЭтаФорма.Модифицированность Тогда
ПередОтображениемДиалогаПередЗакрытиемФормыЛкс(ЭтаФорма);
Ответ = Вопрос("Данные в форме были изменены. Сохранить изменения?", РежимДиалогаВопрос.ДаНетОтмена);
КонецЕсли;
Возврат Ответ;
КонецФункции
Функция ПериодОчисткиМенеджераВременныхТаблицЛкс() Экспорт
Период = ирОбщий.ВосстановитьЗначениеЛкс("ПредлагатьОчиститьМенеджерВременныхТаблицЧерезМинут");
Если Период = Неопределено Тогда
Период = 30;
ИначеЕсли Период < 20 Тогда
Период = 20;
ИначеЕсли Период > 120 Тогда
Период = 120;
КонецЕсли;
Возврат Период;
КонецФункции
Процедура ПередОтображениемДиалогаПередЗакрытиемФормыЛкс(Знач ЭтаФорма) Экспорт
#Если ТолстыйКлиентУправляемоеПриложение Тогда
ЭтаФорма.Открыть(); // http://www.hostedredmine.com/issues/881581
#КонецЕсли
КонецПроцедуры
Процедура КоманднаяПанельВставитьКнопкиГлобальныхКомандЛкс(Знач КоманднаяПанельПолеВвода)
КнопкаКопировать = КоманднаяПанельПолеВвода.Кнопки.Добавить("МакетФормы");
КнопкаКопировать.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
Попытка
КнопкаКопировать.Действие = Новый Действие("КлсКомандаНажатие");
Исключение
КоманднаяПанельПолеВвода.Кнопки.Удалить(КнопкаКопировать);
Возврат;
КонецПопытки;
КнопкаКопировать.Имя = "БуферОбмена_Копировать";
КнопкаКопировать.Текст = "Копировать значение";
КнопкаКопировать.Подсказка = "Копировать значение в буфер обмена";
КнопкаКопировать.Пояснение = КнопкаКопировать.Подсказка;
КнопкаКопировать.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.C, Истина, , Истина); // SHIFT+ALT+C
КнопкаКопировать.Картинка = ирКэш.КартинкаПоИмениЛкс("ирКопировать");
КнопкаВставить = КоманднаяПанельПолеВвода.Кнопки.Добавить();
КнопкаВставить.Имя = "БуферОбмена_Вставить";
КнопкаВставить.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
КнопкаВставить.Текст = "Вставить значение";
КнопкаВставить.Подсказка = "Вставить значение из буфера обмена";
КнопкаВставить.Пояснение = КнопкаВставить.Подсказка;
КнопкаВставить.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.V, Истина, , Истина); // SHIFT+ALT+V
КнопкаВставить.Действие = Новый Действие("КлсКомандаНажатие");
КнопкаВставить.Картинка = ирКэш.КартинкаПоИмениЛкс("ирВставить");
КнопкаВставить = КоманднаяПанельПолеВвода.Кнопки.Добавить();
КнопкаВставить.Имя = "ОткрытьГлобальноеМеню";
КнопкаВставить.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
КнопкаВставить.Текст = "Глобальное меню";
КнопкаВставить.Подсказка = "Открыть глобальное меню";
КнопкаВставить.Пояснение = КнопкаВставить.Подсказка;
КнопкаВставить.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.E, Истина, Истина); // CTRL+ALT+E
КнопкаВставить.Действие = Новый Действие("КлсКомандаНажатие");
КонецПроцедуры
Функция ЛиПерехватКлавиатурногоВводаЛкс() Экспорт
#Если ТолстыйКлиентОбычноеПриложение Тогда
Результат = ирОбщий.ЛиПерехватКлавиатурногоВводаВОбычномПриложенииЛкс();
#Иначе
Результат = Истина;
#КонецЕсли
Возврат Результат;
КонецФункции
Функция ЛиПерехватКлавиатурногоВводаВОбычномПриложенииЛкс() Экспорт
Результат = ирКэш.Получить().ПерехватКлавиатурногоВводаВОбычномПриложении;
Возврат Результат;
КонецФункции
Процедура УниверсальнаяКомандаФормыЛкс(ЭтаФорма, Кнопка, ИсточникДействий = Неопределено) Экспорт
СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
Если Кнопка.Имя = "БуферОбмена_Копировать" Тогда
БуферОбмена_КопироватьЛкс(ЭтаФорма);
ИначеЕсли Кнопка.Имя = "БуферОбмена_Вставить" Тогда
БуферОбмена_ВставитьЛкс(ЭтаФорма);
ИначеЕсли Кнопка.Имя = "ОткрытьГлобальноеМеню" Тогда
Если Не ЛиПерехватКлавиатурногоВводаЛкс() Тогда
ОткрытьГлобальноеМенюЛкс(ЭтаФорма);
КонецЕсли;
ИначеЕсли Кнопка.Имя = "ОПодсистеме" Тогда
ОткрытьСправкуПоПодсистемеЛкс(ЭтаФорма);
ИначеЕсли Кнопка.Имя = "СтруктураФормы" Тогда
ОткрытьСтруктуруФормыЛкс(ЭтаФорма);
ИначеЕсли Кнопка.Имя = "НовоеОкно" Тогда
ОткрытьНовоеОкноФормыЛкс(ЭтаФорма);
ИначеЕсли Кнопка.Имя = "ЗагрузитьНастройку" Тогда
ВыбратьИЗагрузитьНастройкуФормыЛкс(ЭтаФорма);
ИначеЕсли Кнопка.Имя = "СохранитьНастройку" Тогда
ВыбратьИСохранитьНастройкуФормыЛкс(ЭтаФорма);
ИначеЕсли Кнопка.Имя = "ЗагрузитьНастройкуИзФайла" Тогда
Если Не ПроверитьЗавершениеФоновыхЗаданийФормыЛкс(ЭтаФорма) Тогда
СообщитьЛкс("Нельзя выполнять загрузку настроек, пока форма выполняет фоновые задания");
Возврат;
КонецЕсли;
НастройкаФормы = ЗагрузитьЗначениеИзФайлаИнтерактивноЛкс(СлужебныеДанныеФормы.МенеджерСохраненияНастроек.РасширениеФайла, "Настройка """ + ПервыйФрагментЛкс(ЭтаФорма.Заголовок, ":") + """");
Если НастройкаФормы <> Неопределено Тогда
ирОбщий.ЗагрузитьНастройкуФормыЧерезОбработчикЛкс(ЭтаФорма, НастройкаФормы);
КонецЕсли;
ИначеЕсли Кнопка.Имя = "СохранитьНастройкуВФайл" Тогда
НастройкаФормы = ирОбщий.СохраняемаяНастройкаФормыЛкс(ЭтаФорма);
Если НастройкаФормы <> Неопределено Тогда
СохранитьЗначениеВФайлИнтерактивноЛкс(НастройкаФормы, СлужебныеДанныеФормы.МенеджерСохраненияНастроек.РасширениеФайла, "Настройка """ + ПервыйФрагментЛкс(ЭтаФорма.Заголовок, ":") + """");
КонецЕсли;
Иначе
Если ИсточникДействий = Неопределено Тогда
ИсточникДействий = КоманднаяПанельКнопкиЛкс(ЭтаФорма, Кнопка).ИсточникДействий;
КонецЕсли;
Если ИсточникДействий = Неопределено Тогда
ИсточникДействий = ЭтаФорма.ТекущийЭлемент;
КонецЕсли;
Если ТипЗнч(ИсточникДействий) = Тип("ТабличноеПоле") Тогда
#Если Сервер И Не Сервер Тогда
ИсточникДействий = Новый ТабличноеПоле;
#КонецЕсли
Если Кнопка.Имя = "ПереместитьВверх" Тогда
ТабличноеПолеСдвинутьВыделенныеСтрокиЛкс(ИсточникДействий, -1);
ИначеЕсли Кнопка.Имя = "ПереместитьВниз" Тогда
ТабличноеПолеСдвинутьВыделенныеСтрокиЛкс(ИсточникДействий, +1);
ИначеЕсли Кнопка.Имя = "СортироватьПоВозрастанию" Тогда
ТабличноеПолеСортироватьЛкс(ЭтаФорма, ИсточникДействий, Истина);
ИначеЕсли Кнопка.Имя = "СортироватьПоУбыванию" Тогда
ТабличноеПолеСортироватьЛкс(ЭтаФорма, ИсточникДействий, Ложь);
ИначеЕсли Кнопка.Имя = "ПоказыватьИтоги" Тогда
ТабличноеПолеКнопкаОтображенияИтоговНажатиеЛкс(ИсточникДействий, Кнопка);
ИначеЕсли Кнопка.Имя = "Идентификаторы" Тогда
КнопкаОтображатьПустыеИИдентификаторыНажатиеЛкс(Кнопка);
ИсточникДействий.ОбновитьСтроки();
ИначеЕсли Кнопка.Имя = "СжатьКолонки" Тогда
СжатьКолонкиТабличногоПоляЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "ШиринаКолонок" Тогда
РасширитьКолонкиТабличногоПоляЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "ГруппировкаТаблицы" Тогда
ирОбщий.ОткрытьГруппировкуТабличногоПоляЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "МенеджерТабличногоПоля" Тогда
ОткрытьМенеджерТабличногоПоляЛкс(ИсточникДействий, ЭтаФорма);
ИначеЕсли Кнопка.Имя = "УстановитьЗначениеВКолонке" Тогда
ОткрытьМенеджерТабличногоПоляЛкс(ИсточникДействий, ЭтаФорма, "Обработка");
ИначеЕсли Кнопка.Имя = "РазличныеЗначенияКолонки" Тогда
ОткрытьРазличныеЗначенияКолонкиЛкс(ИсточникДействий,,, ЭтаФорма);
ИначеЕсли Кнопка.Имя = "РедакторОбъектаБД" Тогда
ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма);
ОткрытьСсылкуЯчейкиВРедактореОбъектаБДЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "КонсольОбработки" Тогда
ОткрытьОбъектыИзВыделенныхЯчеекВПодбореИОбработкеОбъектовЛкс(ИсточникДействий,, ЭтаФорма);
ИначеЕсли Кнопка.Имя = "ОбработатьОбъекты" Тогда
ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма);
ОткрытьПодборИОбработкуОбъектовИзТабличногоПоляДинамическогоСпискаЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "ВывестиСтроки" Тогда
ВывестиСтрокиТабличногоПоляИПоказатьЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "КонсольКомпоновки" Тогда
ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма);
КонсольКомпоновокДанных = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольКомпоновокДанных");
#Если Сервер И Не Сервер Тогда
КонсольКомпоновокДанных = Обработки.ирКонсольКомпоновокДанных.Создать();
#КонецЕсли
КопияКоллекции = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ИсточникДействий);
КонсольКомпоновокДанных.ОткрытьПоТаблицеЗначений(КопияКоллекции);
ИначеЕсли Кнопка.Имя = "Сравнить" Тогда
СравнитьСодержимоеЭлементаУправленияЛкс(ЭтаФорма, ИсточникДействий);
ИначеЕсли Кнопка.Имя = "ЗаполнитьГруппыДублейДляЗамены" Тогда
ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма);
ОткрытьФормуЗаменыСсылокИзТабличногоПоляЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "ОткрытьКоллекцию" Тогда
ОткрытьЗначениеЛкс(ИсточникДействий.Значение,,,, Ложь,, ИсточникДействий);
ИначеЕсли Кнопка.Имя = "ОткрытьКопиюКоллекции" Тогда
КопияКоллекции = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ИсточникДействий,,, Ложь);
ОткрытьЗначениеЛкс(КопияКоллекции,,,, Ложь,, ИсточникДействий);
ИначеЕсли Кнопка.Имя = "СвернутьДерево" Тогда
ДеревоЗначенийСвернутьРазвернутьЛкс(ИсточникДействий, Истина);
ИначеЕсли Кнопка.Имя = "РазвернутьДерево" Тогда
ДеревоЗначенийСвернутьРазвернутьЛкс(ИсточникДействий, Ложь);
ИначеЕсли Кнопка.Имя = "ДеревоСвернутьОстальные" Тогда
ТабличноеПолеДеревоЗначений_СвернутьВсеСтрокиЛкс(ИсточникДействий, Истина);
ИначеЕсли Кнопка.Имя = "Очистить" Тогда
ИсточникДействий.Значение.Очистить();
ИначеЕсли Кнопка.Имя = "ОтборБезЗначенияВТекущейКолонке" Тогда
ТабличноеПолеОтборБезЗначенияВТекущейКолонке_КнопкаЛкс(ИсточникДействий);
ИначеЕсли Кнопка.Имя = "УстановитьФлажки" Тогда
ИзменитьПометкиВыделенныхИлиОтобранныхСтрокЛкс(ИсточникДействий,, Истина,,,, Истина);
ИначеЕсли Кнопка.Имя = "СнятьФлажки" Тогда
ИзменитьПометкиВыделенныхИлиОтобранныхСтрокЛкс(ИсточникДействий,, Ложь,,,, Истина);
ИначеЕсли Кнопка.Имя = "СколькоСтрок" Тогда
ТабличноеПолеИлиТаблицаФормы_СколькоСтрокЛкс(ИсточникДействий);
Иначе
ВызватьИсключение "Неизвестное имя команды (" + Кнопка.Имя + ")";
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Родственник ВернутьПостоянныйПарольПользователяЛкс
// Пароль устанавливается временный и опционально роль ирРазработчик
Функция УстановитьВременныеСвойстваПользователюИБЛкс(ПользовательИБ, ПодменитьПарольНаВремяЗапуска = Истина, ВременноПредоставитьПравоРазработчикИР = Истина,
ОтключитьЗащитуОтОпасныхДействийНаВремяЗапуска = Истина, ЯзыкКонфигурации = "") Экспорт
#Если Сервер И Не Сервер Тогда
ПользовательИБ = ПользователиИнформационнойБазы.СоздатьПользователя();
#КонецЕсли
мПлатформа = ирКэш.Получить();
НужноВернутьАутентификациюОС = Ложь;
НужноВернутьАутентификациюПаролем = Ложь;
НужноВернутьПароль = Ложь;
НужноВернутьЗащитуОтОпасныхДействий = Ложь;
НужноВернутьЯзыкКонфигурации = Ложь;
УдалитьРольРазработчикИР = Ложь;
Если ПодменитьПарольНаВремяЗапуска Тогда
Если СтрокиРавныЛкс(ПользовательИБ.Имя, ИмяПользователя()) Тогда
СообщитьЛкс("Назначение временного пароля собственному пользователю не допускается");
Возврат Неопределено;
КонецЕсли;
мhash = ПользовательИБ.СохраняемоеЗначениеПароля;
Если ПользовательИБ.АутентификацияОС = Истина Тогда
ПользовательИБ.АутентификацияОС = Ложь;
НужноВернутьАутентификациюОС = Истина;
КонецЕсли;
Если ПользовательИБ.АутентификацияСтандартная = Ложь Тогда
ПользовательИБ.АутентификацияСтандартная = Истина;
НужноВернутьАутентификациюПаролем = Истина;
КонецЕсли;
Пароль = Формат(ТекущаяДата(), "ДФ=HHmmss") + XMLСтрока(НомерСеансаИнформационнойБазы()) + "!_qQ";
ПользовательИБ.Пароль = Пароль;
НужноВернутьПароль = Истина;
КонецЕсли;
Если ВременноПредоставитьПравоРазработчикИР И Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПользовательИБ.Роли.Содержит(Метаданные.Роли.ирРазработчик) Тогда
УдалитьРольРазработчикИР = Истина;
ПользовательИБ.Роли.Добавить(Метаданные.Роли.ирРазработчик);
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(ЯзыкКонфигурации) Тогда
НужноВернутьЯзыкКонфигурации = Истина;
СтарыйЯзыкКонфигурации = ПользовательИБ.Язык;
Если СтарыйЯзыкКонфигурации <> Неопределено Тогда
СтарыйЯзыкКонфигурации = СтарыйЯзыкКонфигурации.Имя;
КонецЕсли;
ПользовательИБ.Язык = Метаданные.Языки[ЯзыкКонфигурации];
КонецЕсли;
Если ОтключитьЗащитуОтОпасныхДействийНаВремяЗапуска Тогда
Если ирКэш.ДоступнаЗащитаОтОпасныхДействийЛкс() И ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях Тогда
ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Ложь;
НужноВернутьЗащитуОтОпасныхДействий = Истина;
КонецЕсли;
КонецЕсли;
ПользовательИБ.Записать();
НаборПараметров = Новый Структура();
НаборПараметров.Вставить("mHash", мhash);
НаборПараметров.Вставить("НужноВернутьАутентификациюПаролем", НужноВернутьАутентификациюПаролем);
НаборПараметров.Вставить("НужноВернутьАутентификациюОС", НужноВернутьАутентификациюОС);
НаборПараметров.Вставить("ПользовательИБ", ПользовательИБ);
НаборПараметров.Вставить("НужноВернутьПароль", НужноВернутьПароль);
НаборПараметров.Вставить("НужноВернутьЗащитуОтОпасныхДействий", НужноВернутьЗащитуОтОпасныхДействий);
НаборПараметров.Вставить("УдалитьРольРазработчикИР", УдалитьРольРазработчикИР);
НаборПараметров.Вставить("Имя", ПользовательИБ.Имя);
НаборПараметров.Вставить("Пароль", Пароль);
НаборПараметров.Вставить("НужноВернутьЯзыкКонфигурации", НужноВернутьЯзыкКонфигурации);
НаборПараметров.Вставить("ЯзыкКонфигурации", СтарыйЯзыкКонфигурации);
Возврат НаборПараметров;
КонецФункции
// Родственник УстановитьВременныеСвойстваПользователюИБЛкс
Процедура ВернутьПостоянныеСвойстваПользователюИБЛкс(НаборПараметров = Неопределено) Экспорт;
//УстановитьПривилегированныйРежим(Истина);
Если НаборПараметров <> Неопределено Тогда
мhash = НаборПараметров.mhash;
ЯзыкКонфигурации = НаборПараметров.ЯзыкКонфигурации;
НужноВернутьАутентификациюПаролем = НаборПараметров.НужноВернутьАутентификациюПаролем;
НужноВернутьАутентификациюОС = НаборПараметров.НужноВернутьАутентификациюОС;
НужноВернутьПароль = НаборПараметров.НужноВернутьПароль;
НужноВернутьЗащитуОтОпасныхДействий = НаборПараметров.НужноВернутьЗащитуОтОпасныхДействий;
НужноВернутьЯзыкКонфигурации = НаборПараметров.НужноВернутьЯзыкКонфигурации;
ПользовательИБ = НаборПараметров.ПользовательИБ;
УдалитьРольРазработчикИР = НаборПараметров.УдалитьРольРазработчикИР;
Иначе
Возврат;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
#КонецЕсли
Если НужноВернутьПароль Тогда
ПользовательИБ.СохраняемоеЗначениеПароля = мHash;
КонецЕсли;
Если НужноВернутьАутентификациюПаролем Тогда
ПользовательИБ.АутентификацияСтандартная = Ложь;
КонецЕсли;
Если НужноВернутьАутентификациюОС Тогда
ПользовательИБ.АутентификацияОС = Истина;
КонецЕсли;
Если НужноВернутьЗащитуОтОпасныхДействий И ирКэш.ДоступнаЗащитаОтОпасныхДействийЛкс() Тогда
ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Истина;
КонецЕсли;
Если УдалитьРольРазработчикИР Тогда
ПользовательИБ.Роли.Удалить(Метаданные.Роли.ирРазработчик);
КонецЕсли;
Если НужноВернутьЯзыкКонфигурации Тогда
ПользовательИБ.Язык = ЯзыкКонфигурации;
КонецЕсли;
ПользовательИБ.Записать();
КонецПроцедуры
Процедура НастроитьПоляВводаПараметровПотоковЛкс(ЭтаФорма) Экспорт
ЭлементыФормы = ЭтаФорма.ЭлементыФормы;
СписокВыбора = ЭлементыФормы.КоличествоОбъектовВПорции.СписокВыбора;
СписокВыбора.Добавить(1);
СписокВыбора.Добавить(2);
СписокВыбора.Добавить(5);
СписокВыбора.Добавить(10);
СписокВыбора.Добавить(20);
СписокВыбора.Добавить(50);
СписокВыбора.Добавить(100);
СписокВыбора.Добавить(200);
СписокВыбора = ЭлементыФормы.КоличествоПотоков.СписокВыбора;
СписокВыбора.Добавить(1);
СписокВыбора.Добавить(4);
СписокВыбора.Добавить(8);
СписокВыбора.Добавить(12);
СписокВыбора.Добавить(16);
КонецПроцедуры
Функция ОткрытьМенеджерТабличногоПоляЛкс(ТабличноеПоле = Неопределено, ЭтаФорма, АктивизироватьСтраницу = "") Экспорт
Если ТабличноеПоле = Неопределено Тогда
ТабличноеПоле = ЭтаФорма.ТекущийЭлемент;
КонецЕсли;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаМенеджера = мПлатформа.ПолучитьФорму("МенеджерТабличногоПоля", ЭтаФорма);
ФормаМенеджера.УстановитьСвязь(ТабличноеПоле, , АктивизироватьСтраницу);
Возврат ФормаМенеджера;
КонецФункции
Процедура ОткрытьСвязанныйСеансТонкогоКлиентаЛкс() Экспорт
Результат = ирКэш.ПолучитьСеансТонкогоКлиентаЛкс();
Если Результат = Неопределено Тогда
Возврат;
КонецЕсли;
Результат.Visible = Истина;
Окна = Результат.ПолучитьОкна();
СписокОткрытыхОбъектов = Новый СписокЗначений;
Для Каждого Окно Из Окна Цикл
Попытка
Содержимое = Окно.Содержимое;
Исключение
// В 8.2 нет такого свойства
Продолжить;
КонецПопытки;
Для Каждого Форма Из Содержимое Цикл
Попытка
СсылкаCOM = Форма.Parameters.Key;
Исключение
СсылкаCOM = Неопределено;
КонецПопытки;
Если СсылкаCOM <> Неопределено Тогда
ФрагментыИмениТипа = ирОбщий.СтрРазделитьЛкс(Форма.FormName);
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(Новый УникальныйИдентификатор(Результат.String(СсылкаCOM.УникальныйИдентификатор())));
Ссылка = Новый (Тип(ФрагментыИмениТипа[0] + "Ссылка." + ФрагментыИмениТипа[1]), МассивПараметров);
СписокОткрытыхОбъектов.Добавить(Ссылка, ФрагментыИмениТипа[0] + "." + ФрагментыИмениТипа[1] + " - " + Ссылка);
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если СписокОткрытыхОбъектов.Количество() > 0 Тогда
СписокОткрытыхОбъектов.СортироватьПоПредставлению();
ВыбранныйЭлемент = СписокОткрытыхОбъектов.ВыбратьЭлемент("Выберите объект для открытия в редакторе объекта БД");
Если ВыбранныйЭлемент <> Неопределено Тогда
ОткрытьСсылкуВРедактореОбъектаБДЛкс(ВыбранныйЭлемент.Значение);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ОповеститьОЗаписиОбъектаЛкс(ТипОбъекта, Источник = Неопределено) Экспорт
ирОбщий.ОповеститьФормыПодсистемыЛкс("ЗаписанОбъект", ТипОбъекта, Источник);
ОповеститьОбИзменении(ТипОбъекта);
КонецПроцедуры
// Для оповещения об изменениях объектов в памяти клиентского приложения
Процедура ОповеститьОбИзмененииОбъектаЛкс(Объект, Источник = Неопределено) Экспорт
ирОбщий.ОповеститьФормыПодсистемыЛкс("ИзмененОбъект", Объект, Источник);
КонецПроцедуры
Функция ЭтоНеудобнаяСсылкаДляОбработкиВыбораЛкс(Знач ВыбранноеЗначение) Экспорт
// Почему то для ссылок внешних источников данных оповещение о выборе устанавливает строковое значение
XMLТип = XMLТипЗнч(ВыбранноеЗначение);
Если Истина
И XMLТип <> Неопределено
И (Ложь
Или Найти(XMLТип.ИмяТипа, "ExternalDataSourceTableRef.") > 0
Или (Истина
И ВыбранноеЗначение <> Неопределено
И Метаданные.НайтиПоТипу(ТипЗнч(ВыбранноеЗначение)) <> Неопределено
И ВыбранноеЗначение.Метаданные().РасширениеКонфигурации() <> Неопределено))
Тогда
ЭтоНеудобнаяСсылка = Истина;
Иначе
ЭтоНеудобнаяСсылка = Ложь;
КонецЕсли;
Возврат ЭтоНеудобнаяСсылка;
КонецФункции
Функция ОткрытьОбъектМетаданныхЛкс(ОбъектИлиПолноеИмяМД) Экспорт
Если ТипЗнч(ОбъектИлиПолноеИмяМД) = Тип("ОбъектМетаданных") Тогда
ОбъектМД = ОбъектИлиПолноеИмяМД;
Иначе
ОбъектМД = ПолучитьМетаданныеЛкс(ОбъектИлиПолноеИмяМД);
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.НайтиПоТипу();
#КонецЕсли
Если ОбъектМД = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
Фрагменты = ирОбщий.СтрРазделитьЛкс(ПолноеИмяМД);
Если Истина
И Фрагменты.Количество() = 4
И Не ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(Фрагменты[0])
Тогда
// Для табличной части берем родителя
ПолноеИмяМД = ОбъектМД.Родитель().ПолноеИмя();
КонецЕсли;
Форма = ПолучитьФормуЛкс("Обработка.ирИнтерфейснаяПанель.Форма");
Форма.ПараметрИмяОбъектаМетаданных = ПолноеИмяМД;
Форма.ПрименитьПараметрыФормы();
Возврат Форма;
КонецФункции
Функция ОткрытьПользователяИБЛкс(Пользователь) Экспорт
ФормаПользователя = ирОбщий.ПолучитьФормуЛкс("Обработка.ирРедакторПользователей.Форма.ПользовательИнфобазы",,, Пользователь);
ФормаПользователя.ПользовательБД = ПользователиИнформационнойБазы.НайтиПоИмени(Пользователь);
ФормаПользователя.Открыть();
Возврат ФормаПользователя;
КонецФункции
Функция ОбработкаОбъектИзФормыЛкс(ЭтаФорма) Экспорт
Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда
ОбработкаОбъект = ЭтаФорма;
Иначе
//ОбработкаОбъект = ЭтаФорма.РеквизитФормыВЗначение("фОбъект");
Фрагменты = СтрРазделитьЛкс(ЭтаФорма.ИмяФормы);
ОбработкаОбъект = ДанныеФормыВЗначение(ЭтаФорма.фОбъект, Тип("ОбработкаОбъект." + Фрагменты[1]));
КонецЕсли;
Возврат ОбработкаОбъект;
КонецФункции
Процедура ПроверитьЗакрытьФормуПриОтказеЛкс(ЭтаФорма, Знач Отказ) Экспорт
// Антибаг платформы 8.3.11-12 Не работает установка параметра Отказ перед открытием обычной формы в управляемом приложении
// https://partners.v8.1c.ru/forum/t/1713475/m/1713475
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если Отказ И Не ЭтаФорма.МодальныйРежим Тогда
ЭтаФорма.Закрыть();
КонецЕсли;
#КонецЕсли
КонецПроцедуры
Функция КлючиСтрокБДИзТаблицыФормыЛкс(Форма = Неопределено, выхКлючТекущейСтроки = Неопределено, выхТаблицаФормыДинамическогоСписка = Неопределено, Знач НуженВидимыйПорядок = Истина) Экспорт
Результат = Новый Массив;
Если Форма = Неопределено Тогда
Форма = АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если Ложь
Или ТипЗнч(Форма.ТекущийЭлемент) = Тип("ТаблицаФормы")
Или ТипЗнч(Форма.ТекущийЭлемент) = Тип("ТабличноеПоле")
Тогда
ТаблицаФормы = Форма.ТекущийЭлемент;
Если ЛиКлючСсылкиИлиРегистраЛкс(ТаблицаФормы.ТекущаяСтрока) Тогда
выхКлючТекущейСтроки = ТаблицаФормы.ТекущаяСтрока;
КонецЕсли;
Ссылка = ТаблицаФормы.ТекущаяСтрока;
ВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТаблицаФормы, НуженВидимыйПорядок);
Если ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда
выхТаблицаФормыДинамическогоСписка = ТаблицаФормы;
Возврат ВыделенныеСтроки;
КонецЕсли;
Структура = Новый Структура("Ссылка, Data");
Для Каждого ВыделеннаяСтрока Из ВыделенныеСтроки Цикл
ДанныеСтроки = ДанныеСтрокиТабличногоПоляЛкс(ТаблицаФормы, ВыделеннаяСтрока);
ЗаполнитьЗначенияСвойств(Структура, ДанныеСтроки);
Ссылка = Структура["Ссылка"];
Если ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда
Результат.Добавить(Ссылка);
КонецЕсли;
Ссылка = Структура["Data"];
Если ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда
Результат.Добавить(Ссылка);
Если ВыделеннаяСтрока = ТаблицаФормы.ТекущаяСтрока Тогда
выхКлючТекущейСтроки = Ссылка;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция КлючОсновногоОбъектаУправляемойФормыЛкс(Форма = Неопределено) Экспорт
Результат = Новый Массив;
Если Форма = Неопределено Тогда
Форма = АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если ТипЗнч(Форма) = Тип("УправляемаяФорма") Тогда
Ссылка = ирОбщий.СсылкаОсновногоОбъектаФормыЛкс(Форма);
Если Не ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда
Попытка
Ссылка = Форма.Параметры.Ключ;
Исключение
КонецПопытки;
КонецЕсли;
Если Не ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда
Ссылка = Неопределено;
КонецЕсли;
КонецЕсли;
Возврат Ссылка;
КонецФункции
Функция СсылкиИзТекущейКолонкиВыделенныхСтрокТаблицыЛкс(Форма = Неопределено, выхКлючТекущейСтроки = Неопределено, НуженВидимыйПорядок = Истина) Экспорт
Результат = Новый Массив;
Если Форма = Неопределено Тогда
Форма = АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если ТипЗнч(Форма.ТекущийЭлемент) = Тип("ТаблицаФормы") Тогда
ТаблицаФормы = Форма.ТекущийЭлемент;
ТекущееПоле = ТаблицаФормы.ТекущийЭлемент;
ПолноеИмяПоля = ТекущееПоле.Имя;
ПутьКДанным = Null;
ВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТаблицаФормы, НуженВидимыйПорядок);
Для Каждого ВыделеннаяСтрока Из ВыделенныеСтроки Цикл
ДанныеСтроки = ДанныеСтрокиТабличногоПоляЛкс(ТаблицаФормы, ВыделеннаяСтрока);
Если ПутьКДанным = Null Тогда
ПутьКДанным = НайтиПутьКДаннымПоляТаблицыФормыЛкс(ДанныеСтроки, ПолноеИмяПоля);
КонецЕсли;
ЗначениеПоля = Неопределено;
Если ЗначениеЗаполнено(ПутьКДанным) Тогда
ЗначениеПоля = ДанныеСтроки[ПервыйФрагментЛкс(ПутьКДанным)];
КонецЕсли;
Если ЛиКлючСсылкиИлиРегистраЛкс(ЗначениеПоля) Тогда
Результат.Добавить(ЗначениеПоля);
Если ВыделеннаяСтрока = ТаблицаФормы.ТекущаяСтрока Тогда
выхКлючТекущейСтроки = ЗначениеПоля;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Найти(ПутьКДанным, ".") > 0 И Результат.Количество() > 0 Тогда
Результат = ПрочитатьРеквизитПоМассивуСсылокЛкс(Результат, ПоследнийФрагментЛкс(ПутьКДанным));
КонецЕсли;
ИначеЕсли ТипЗнч(Форма.ТекущийЭлемент) = Тип("ТабличноеПоле") Тогда
ТабличноеПоле = Форма.ТекущийЭлемент;
ПутьКДанным = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Если ЗначениеЗаполнено(ПутьКДанным) Тогда
ВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТабличноеПоле, НуженВидимыйПорядок);
Для Каждого ВыделеннаяСтрока Из ВыделенныеСтроки Цикл
ДанныеСтроки = ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле, ВыделеннаяСтрока);
ЗначениеПоля = Неопределено;
Если ЗначениеЗаполнено(ПутьКДанным) Тогда
ЗначениеПоля = ДанныеСтроки[ПоследнийФрагментЛкс(ПутьКДанным)];
КонецЕсли;
Если ЛиКлючСсылкиИлиРегистраЛкс(ЗначениеПоля) Тогда
Результат.Добавить(ЗначениеПоля);
Если ВыделеннаяСтрока = ТабличноеПоле.ТекущаяСтрока Тогда
выхКлючТекущейСтроки = ЗначениеПоля;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ИначеЕсли ТипЗнч(Форма.ТекущийЭлемент) = Тип("ПолеФормы") Тогда
ПолеФормы = Форма.ТекущийЭлемент;
Если ПолеФормы.Вид = ВидПоляФормы.ПолеВвода Тогда
ЗначениеПоля = ДанныеЭлементаФормыЛкс(Форма.ТекущийЭлемент);
Если ЛиКлючСсылкиИлиРегистраЛкс(ЗначениеПоля) Тогда
Результат.Добавить(ЗначениеПоля);
выхКлючТекущейСтроки = ЗначениеПоля;
КонецЕсли;
ИначеЕсли ПолеФормы.Вид = ВидПоляФормы.ПолеТабличногоДокумента Тогда
ДанныеРасшифровки = ДанныеРасшифровкиУправляемойФормыОтчетаЛкс(Форма);
ТабличныйДокумент = ДанныеЭлементаФормыЛкс(ПолеФормы);
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
Если ТабличныйДокумент = Неопределено Тогда
Возврат Результат;
КонецЕсли;
КлючТекущейСтроки = Неопределено;
ТаблицаЗначений = ПолучитьТаблицуКлючейИзТабличногоДокументаЛкс(ТабличныйДокумент, ДанныеРасшифровки,,, КлючТекущейСтроки);
Если ТаблицаЗначений.Колонки.Количество() > 0 Тогда
Для Каждого ЗначениеПоля Из ТаблицаЗначений.ВыгрузитьКолонку(0) Цикл
Если ЛиКлючСсылкиИлиРегистраЛкс(ЗначениеПоля) Тогда
Результат.Добавить(ЗначениеПоля);
КонецЕсли;
КонецЦикла;
Если КлючТекущейСтроки <> Неопределено И ЛиКлючСсылкиИлиРегистраЛкс(КлючТекущейСтроки[0]) Тогда
выхКлючТекущейСтроки = КлючТекущейСтроки[0];
КонецЕсли;
КонецЕсли;
Если выхКлючТекущейСтроки = Неопределено И Результат.Количество() > 0 Тогда
выхКлючТекущейСтроки = Результат[0];
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПрочитатьРеквизитПоМассивуСсылокЛкс(Знач Ссылки, Знач ИмяРеквизита) Экспорт
#Если Сервер И Не Сервер Тогда
Ссылки = Новый Массив;
#КонецЕсли
Результат = Новый Массив;
Если Ссылки.Количество() > 0 Тогда
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Т." + ИмяРеквизита + " ИЗ " + Ссылки[0].Метаданные().ПолноеИмя() + " КАК Т ГДЕ Т.Ссылка В (&Ссылки)";
Запрос.УстановитьПараметр("Ссылки", Ссылки);
Результат = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(0);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЭтоУправляемаяФормаОтчетаЛкс(Знач АктивнаяФорма, РазрешитьВнешнийОтчет = Ложь) Экспорт
Возврат Истина
И ТипЗнч(АктивнаяФорма) <> Тип("Форма")
И (Ложь
Или Найти(АктивнаяФорма.ИмяФормы, ирОбщий.ПеревестиСтроку("Отчет") + ".") = 1
Или РазрешитьВнешнийОтчет И Найти(АктивнаяФорма.ИмяФормы, ирОбщий.ПеревестиСтроку("ВнешнийОтчет") + ".") = 1);
КонецФункции
Функция ТекущийЭлементАктивнойФормыЛкс(АктивнаяФорма = Неопределено) Экспорт
Если АктивнаяФорма = Неопределено Тогда
АктивнаяФорма = АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
ТекущийЭлемент = АктивнаяФорма.ТекущийЭлемент;
Если ТипЗнч(АктивнаяФорма) = Тип("УправляемаяФорма") Тогда
Если ТипЗнч(ТекущийЭлемент) = Тип("ОсновнойЭлементФормы") Тогда
// http://www.hostedredmine.com/issues/880476
ТекущийЭлемент = Неопределено;
КонецЕсли;
КонецЕсли;
Возврат ТекущийЭлемент;
КонецФункции
Процедура СравнитьТаблицуИзАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма);
Если Истина
И ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы")
И ТипЗнч(ТекущийЭлемент) <> Тип("ТабличноеПоле")
И ТипЗнч(ТекущийЭлемент) <> Тип("ПолеТабличногоДокумента")
И Не (Истина
И ТипЗнч(ТекущийЭлемент) = Тип("ПолеФормы")
И ТекущийЭлемент.Вид = ВидПоляФормы.ПолеТабличногоДокумента)
Тогда
Возврат;
КонецЕсли;
ирОбщий.СравнитьСодержимоеЭлементаУправленияЛкс(Форма, ТекущийЭлемент);
КонецПроцедуры
Процедура ОткрытьТаблицуЗначенийИзАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма);
Если Ложь
Или ТипЗнч(ТекущийЭлемент) = Тип("ТаблицаФормы")
Или ТипЗнч(ТекущийЭлемент) = Тип("ТабличноеПоле")
Тогда
Результат = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ТекущийЭлемент,,, Ложь);
ИначеЕсли Ложь
Или ТипЗнч(ТекущийЭлемент) = Тип("ПолеТабличногоДокумента")
Или (Истина
И ТипЗнч(ТекущийЭлемент) = Тип("ПолеФормы")
И ТекущийЭлемент.Вид = ВидПоляФормы.ПолеТабличногоДокумента)
Тогда
ДанныеРасшифровки = ДанныеРасшифровкиУправляемойФормыОтчетаЛкс(Форма);
ТабличныйДокумент = ДанныеЭлементаФормыЛкс(ТекущийЭлемент);
Если ТабличныйДокумент = Неопределено Тогда
Возврат;
КонецЕсли;
Результат = ирОбщий.ПолучитьТаблицуКлючейИзТабличногоДокументаЛкс(ТабличныйДокумент, ДанныеРасшифровки);
#Если Сервер И Не Сервер Тогда
Результат = Новый ТаблицаЗначений;
#КонецЕсли
Если Результат.Колонки.Количество() = 0 Тогда
Ответ = Вопрос("Ячейки не содержат расшифровки. Хотите назначить имена колонкам из первой строки выделенной области?", РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Нет);
ЛиПерваяСтрокаСодержитИменаКолонок = Ответ = КодВозвратаДиалога.Да;
Результат = ТаблицаЗначенийИзТабличногоДокументаЛкс(ТабличныйДокумент, ЛиПерваяСтрокаСодержитИменаКолонок,,,, Истина);
КонецЕсли;
Результат = ТаблицаСМинимальнымиТипамиКолонокЛкс(Результат);
ТекущийЭлемент = Неопределено;
Иначе
Возврат;
КонецЕсли;
Если Результат <> Неопределено Тогда
ОткрытьЗначениеЛкс(Результат,,,, Ложь,, ТекущийЭлемент);
Иначе // ДинамическийСписок
ирОбщий.ВывестиСтрокиТабличногоПоляИПоказатьЛкс(ТекущийЭлемент);
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьТабличныйДокументИзАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма);
Если Ложь
Или ТипЗнч(ТекущийЭлемент) = Тип("ПолеТабличногоДокумента")
Или (Истина
И ТипЗнч(ТекущийЭлемент) = Тип("ПолеФормы")
И ТекущийЭлемент.Вид = ВидПоляФормы.ПолеТабличногоДокумента)
Тогда
Результат = ДанныеЭлементаФормыЛкс(ТекущийЭлемент);
ДанныеРасшифровки = ДанныеРасшифровкиУправляемойФормыОтчетаЛкс(Форма);
КонецЕсли;
Если Результат <> Неопределено Тогда
ОткрытьТабличныйДокументРезультатаКомпоновкиЛкс(Результат, ДанныеРасшифровки);
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьТабличныйДокументРезультатаКомпоновкиЛкс(Знач ПолеТабличногоДокумента, Знач ДанныеРасшифровки = Неопределено, Знач ИмяСохраненияПоложенияОкна = "") Экспорт
//ТабличныйДокумент = Новый ТабличныйДокумент;
//ТабличныйДокумент.Вывести(ПолеТабличногоДокумента);
ТабличныйДокумент = ПолучитьОбластьТабличногоДокументаИнтерактивноЛкс(ПолеТабличногоДокумента);
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
ТабличныйДокумент.ИмяСохраненияПоложенияОкна = ИмяСохраненияПоложенияОкна;
Если ДанныеРасшифровки <> Неопределено Тогда
УпроститьРасшифровкиТабличногоДокументаКомпоновкиЛкс(ТабличныйДокумент, ДанныеРасшифровки);
КонецЕсли;
ОткрытьЗначениеЛкс(ТабличныйДокумент,,,, Ложь,, ПолеТабличногоДокумента);
КонецПроцедуры
Функция ДанныеРасшифровкиУправляемойФормыОтчетаЛкс(Знач Форма) Экспорт
ВозможныеИменаРеквизитов = Новый Массив;
ВозможныеИменаРеквизитов.Добавить("ДанныеРасшифровки");
ВозможныеИменаРеквизитов.Добавить("ОтчетДанныеРасшифровки");
Для Каждого ИмяРеквизита Из ВозможныеИменаРеквизитов Цикл
Попытка
АдресРасшифровки = Форма[ИмяРеквизита];
Прервать;
Исключение
АдресРасшифровки = Неопределено;
КонецПопытки;
КонецЦикла;
Если ЗначениеЗаполнено(АдресРасшифровки) Тогда
ДанныеРасшифровки = ПолучитьИзВременногоХранилища(АдресРасшифровки);
КонецЕсли;
Возврат ДанныеРасшифровки;
КонецФункции
Процедура ОткрытьРазличныеЗначенияКолонкиАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма);
Если Истина
И ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы")
И ТипЗнч(ТекущийЭлемент) <> Тип("ТабличноеПоле")
Тогда
Возврат;
КонецЕсли;
ирОбщий.ОткрытьРазличныеЗначенияКолонкиЛкс(ТекущийЭлемент,,, Форма);
КонецПроцедуры
Процедура ОтладитьКомпоновкуДанныхАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт
Если Форма = Неопределено Тогда
Форма = АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если ТипЗнч(Форма) <> Тип("УправляемаяФорма") Тогда
Возврат;
КонецЕсли;
Попытка
НастройкиОтчета = Форма.НастройкиОтчета;
Исключение
НастройкиОтчета = Неопределено;
КонецПопытки;
Если НастройкиОтчета <> Неопределено И НастройкиОтчета.СхемаМодифицирована Тогда
// Стандартная форма отчета БСП
СхемаКомпоновки = ПолучитьИзВременногоХранилища(НастройкиОтчета.АдресСхемы);
Иначе
Фрагменты = СтрРазделитьЛкс(Форма.ИмяФормы);
Если Фрагменты[0] = ирОбщий.ПеревестиСтроку("Отчет") Тогда
ОтчетОбъект = Отчеты[Фрагменты[1]].Создать();
#Если Сервер И Не Сервер Тогда
ОтчетОбъект = Обработки.ирКонсольКомпоновокДанных.Создать();
#КонецЕсли
СхемаКомпоновки = ОтчетОбъект.СхемаКомпоновкиДанных;
//ИначеЕсли Фрагменты[0] = ирОбщий.ПеревестиСтроку("ВнешнийОтчет") Тогда
// // https://forum.mista.ru/topic.php?id=857116
// ОтчетОбъект = ВнешниеОтчеты.Создать(Фрагменты[1]);
// #Если Сервер И Не Сервер Тогда
// ОтчетОбъект = ВнешниеОтчеты.Создать();
// #КонецЕсли
// СхемаКомпоновки = ОтчетОбъект.СхемаКомпоновкиДанных;
Иначе
СообщитьЛкс("Не поддерживаемый тип метаданных отчета - " + Фрагменты[0]);
Возврат;
КонецЕсли;
КонецЕсли;
ОтладитьЛкс(СхемаКомпоновки,, Форма.Отчет.КомпоновщикНастроек.ПолучитьНастройки());
КонецПроцедуры
Процедура НастроитьДинамическийСписокАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма);
Если ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы") Тогда
Возврат;
КонецЕсли;
ДанныеЭлемента = ДанныеЭлементаФормыЛкс(ТекущийЭлемент);
Если ТипЗнч(ДанныеЭлемента) <> Тип("ДинамическийСписок") Тогда
Возврат;
КонецЕсли;
Параметры = Новый Структура("Настройки, ПользовательскиеНастройки, ФиксированныеНастройки, ИсточникДоступныхНастроек");
ЗаполнитьЗначенияСвойств(Параметры, ДанныеЭлемента.КомпоновщикНастроек);
Параметры.ИсточникДоступныхНастроек = ДанныеЭлемента.КомпоновщикНастроек.ПолучитьИсточникДоступныхНастроек();
Если ирКэш.НомерВерсииПлатформыЛкс() > 803001 Тогда
Выполнить("ОткрытьФорму(""Обработка.ирДинамическийСписок.Форма.НастройкиСпискаУпр"", Параметры, ТекущийЭлемент,,,,, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца)");
Иначе
ОткрытьФормуМодально("Обработка.ирДинамическийСписок.Форма.НастройкиСпискаУпр", Параметры, ТекущийЭлемент);
КонецЕсли;
КонецПроцедуры
Процедура ОтборБезЗначенияВТекущейКолонкеАктивнойФормыЛкс(Параметры) Экспорт
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Параметры.Форма);
Если Истина
И ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы")
И ТипЗнч(ТекущийЭлемент) <> Тип("ТабличноеПоле")
Тогда
Возврат;
КонецЕсли;
ОбщийТипДанныхТаблицы = ОбщийТипДанныхТабличногоПоляЛкс(ТекущийЭлемент);
Если Истина
И ОбщийТипДанныхТаблицы <> "Список"
И ОбщийТипДанныхТаблицы <> "ТабличнаяЧасть"
И ОбщийТипДанныхТаблицы <> "НаборЗаписей"
Тогда
Возврат;
КонецЕсли;
ТабличноеПолеОтборБезЗначенияВТекущейКолонке_КнопкаЛкс(ТекущийЭлемент);
КонецПроцедуры
Процедура НайтиВыбратьСсылкуВДинамическомСпискеАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт
ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма);
Если ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы") Тогда
Возврат;
КонецЕсли;
ИмяТаблицыБД = ирОбщий.ИмяТаблицыБДДинамическогоСпискаЛкс(ТекущийЭлемент);
Если Не ЗначениеЗаполнено(ИмяТаблицыБД) Тогда
Возврат;
КонецЕсли;
НайтиВыбратьСсылкуВДинамическомСпискеПоIDЛкс(ТекущийЭлемент);
КонецПроцедуры
Процедура НайтиВыбратьСсылкуВДинамическомСпискеПоIDЛкс(Знач ТабличноеПоле, Форма = Неопределено) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаВводаИдентификатора = мПлатформа.ПолучитьФорму("УникальныйИдентификатор");
НовыйИдентификатор = ФормаВводаИдентификатора.ОткрытьМодально();
Если НовыйИдентификатор = Неопределено Тогда
Возврат;
КонецЕсли;
Ссылка = ирОбщий.ПолучитьМенеджерЛкс(ирОбщий.ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле)).ПолучитьСсылку(НовыйИдентификатор);
ТабличноеПоле.ТекущаяСтрока = Ссылка;
Если ТабличноеПоле.ТекущаяСтрока = Ссылка Тогда
СообщитьЛкс("Объект найден и установлен текущей строкой");
Иначе
Если Форма = Неопределено Тогда
Форма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле);
КонецЕсли;
Если Не ирОбщий.ЛиСуществуетОбъектПоСсылкеЛкс(Ссылка) Тогда
Если ТабличноеПоле.РежимВыбора Тогда
Ответ = Вопрос("Объект не найден в таблице. Выбрать ссылку?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
Форма.ОповеститьОВыборе(Ссылка);
КонецЕсли;
Иначе
СообщитьЛкс("Объект не найден в таблице");
КонецЕсли;
Иначе
Если ТабличноеПоле.РежимВыбора Тогда
Ответ = Вопрос("Объект найден в таблице, но не отвечает текущему отбору. Выбрать ссылку?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
Форма.ОповеститьОВыборе(Ссылка);
КонецЕсли;
Иначе
СообщитьЛкс("Объект найден в таблице, но не отвечает текущему отбору");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьКолонкиГруппыФормыВТаблицуЗначений(Знач КолонкиИсточника, Знач Результат, Знач СтрокаИлиКоллекция)
Для Каждого ПолеТаблицыФормы Из КолонкиИсточника Цикл
Если ТипЗнч(ПолеТаблицыФормы) = Тип("ГруппаФормы") Тогда
ДобавитьКолонкиГруппыФормыВТаблицуЗначений(ПолеТаблицыФормы.ПодчиненныеЭлементы, Результат, СтрокаИлиКоллекция);
Продолжить;
КонецЕсли;
ПолноеИмяПоля = ПолеТаблицыФормы.Имя;
ПутьКДанным = НайтиПутьКДаннымПоляТаблицыФормыЛкс(СтрокаИлиКоллекция, ПолноеИмяПоля);
Если ЗначениеЗаполнено(ПутьКДанным) Тогда
Результат.Колонки.Добавить(СтрЗаменить(ПутьКДанным, ".", "_"),, ПутьКДанным);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ОткрытьСтатистикаMSSQLПоПоследнимЗапросамЛкс(ДатаНачала, ДатаКонца) Экспорт
ОтчетОбъект = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Отчет.ирСтатистикаПоЗапросамСУБД");
#Если Сервер И Не Сервер Тогда
ОтчетОбъект = Отчеты.ирСтатистикаПоЗапросамСУБД.Создать();
#КонецЕсли
КлючВарианта = "Последние";
ФормаОтчета = ОтчетОбъект.ПолучитьФорму(,, КлючВарианта);
ФормаОтчета.ПараметрКлючВарианта = КлючВарианта;
ФормаОтчета.Открыть();
НастройкиОтчета = ФормаОтчета.КомпоновщикНастроек.Настройки;
#Если Сервер И Не Сервер Тогда
НастройкиОтчета = Компоновщик.Настройки;
#КонецЕсли
НастройкиОтчета.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ПопавшиеВПоследниеМинут")).Использование = Ложь;
НастройкиОтчета.ПараметрыДанных.УстановитьЗначениеПараметра("НачалоИнтервала", ДатаНачала);
НастройкиОтчета.ПараметрыДанных.УстановитьЗначениеПараметра("КонецИнтервала", ДатаКонца);
ФормаОтчета.ДействияФормыСформировать();
КонецФункции
#КонецЕсли
#Если Клиент Тогда
// Эта обертка нужно для возможности привязать ее к команде панели инструментов
Процедура ОтладитьОтложенныйОбъектБезПараметровЛкс() Экспорт
Если Не ЛиДоступноВТолстомКлиентеЛкс() Тогда
Возврат;
КонецЕсли;
#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
ОтладитьОтложенныйОбъектЛкс();
#КонецЕсли
КонецПроцедуры
Процедура УстановитьПрикреплениеФормыВУправляемомПриложенииЛкс(Этаформа, ПроверитьДоступностьВвода = Ложь, ПоложениеПрикрепленногоОкна = Неопределено) Экспорт
#Если ТолстыйКлиентУправляемоеПриложение Тогда
// 8.3.17 здесь почему то не проверяет синтаксический контроль!
Если ПроверитьДоступностьВвода И Не Этаформа.ВводДоступен() Тогда // При открытии формы ВводДоступен() всегда равно Ложь
Возврат;
КонецЕсли;
Если ПоложениеПрикрепленногоОкна = Неопределено Тогда
Если ЭтаФорма.СостояниеОкна = ВариантСостоянияОкна.Прикрепленное Тогда
ПоложениеПрикрепленногоОкна = ЭтаФорма.ПоложениеПрикрепленногоОкна;
КонецЕсли;
КонецЕсли;
Если ПоложениеПрикрепленногоОкна <> Неопределено Тогда
ОжидатьЗавершения = Ложь; // Вроде не играет роли
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803017 Тогда
Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда
КомандаАктивацииПунктаОкна = "{UP 2}";
Иначе
КомандаАктивацииПунктаОкна = "{UP 4}";
КонецЕсли;
ОтправитьНажатияКлавишЛкс("%-", ОжидатьЗавершения); // Такой вызов меню окна не работает в 8.3.15-16
ОтправитьНажатияКлавишЛкс(КомандаАктивацииПунктаОкна, ОжидатьЗавершения);
ОтправитьНажатияКлавишЛкс("{ENTER}", ОжидатьЗавершения);
// Снизу может находиться пункт меню "Сообщения", если было выведено хотя бы одно сообщение
//Если ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Верх Тогда
// ОтправитьНажатияКлавишЛкс("{UP 3}", ОжидатьЗавершения);
//ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Низ Тогда
// ОтправитьНажатияКлавишЛкс("{UP 2}", ОжидатьЗавершения);
//ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Лево Тогда
// ОтправитьНажатияКлавишЛкс("{UP 5}", ОжидатьЗавершения);
//ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Право Тогда
// ОтправитьНажатияКлавишЛкс("{UP 4}", ОжидатьЗавершения);
//КонецЕсли;
Если ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Верх Тогда
ОтправитьНажатияКлавишЛкс("{Down 4}", ОжидатьЗавершения);
ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Низ Тогда
ОтправитьНажатияКлавишЛкс("{Down 5}", ОжидатьЗавершения);
ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Лево Тогда
ОтправитьНажатияКлавишЛкс("{Down 2}", ОжидатьЗавершения);
ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Право Тогда
ОтправитьНажатияКлавишЛкс("{Down 3}", ОжидатьЗавершения);
КонецЕсли;
ОтправитьНажатияКлавишЛкс("{ENTER}", ОжидатьЗавершения);
ИначеЕсли ирКэш.НомерВерсииПлатформыЛкс() >= 803015 Тогда
// ОтправитьНажатияКлавишЛкс("%-"); // Такой вызов меню окна не работает в 8.3.15-16
Иначе
ОтправитьНажатияКлавишЛкс("%", ОжидатьЗавершения);
ОтправитьНажатияКлавишЛкс("{Down 1}", ОжидатьЗавершения);
ОтправитьНажатияКлавишЛкс("{О}", ОжидатьЗавершения);
Если ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Верх Тогда
ОтправитьНажатияКлавишЛкс("{UP 4}", ОжидатьЗавершения);
ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Низ Тогда
ОтправитьНажатияКлавишЛкс("{UP 3}", ОжидатьЗавершения);
ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Лево Тогда
ОтправитьНажатияКлавишЛкс("{UP 6}", ОжидатьЗавершения);
ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Право Тогда
ОтправитьНажатияКлавишЛкс("{UP 5}", ОжидатьЗавершения);
КонецЕсли;
ОтправитьНажатияКлавишЛкс("{ENTER}", ОжидатьЗавершения);
КонецЕсли;
КонецЕсли;
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьСписокИнструментовЛкс() Экспорт
ОткрытьПанельИнструментовЛкс(Истина);
КонецПроцедуры
Процедура ОткрытьПанельИнструментовЛкс(ТолькоОткрытьНастройки = Ложь) Экспорт
#Если ВебКлиент Или МобильныйКлиент Тогда
СообщитьЛкс("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#Иначе
ФормаСпискаИнструментов = ПолучитьФормуЛкс("Обработка.ирПортативный.Форма.Форма");
ФормаСпискаИнструментов.ПараметрТолькоОткрытьНастройки = ТолькоОткрытьНастройки;
ФормаСпискаИнструментов.Открыть();
#КонецЕсли
КонецПроцедуры
Процедура СохранитьНастройкиПользователяЛкс() Экспорт
#Если ВебКлиент Или МобильныйКлиент Тогда
СообщитьЛкс("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#Иначе
СохранитьНастройкиПользователя();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьНастройкиАлгоритмовЛкс() Экспорт
#Если ВебКлиент Или МобильныйКлиент Тогда
СообщитьЛкс("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#Иначе
Если ирКэш.ЛиЭтоРасширениеКонфигурацииЛкс() Тогда
СообщитьЛкс("Команда недоступна в варианте Расширение");
Возврат;
КонецЕсли;
Форма = ирКэш.Получить().ПолучитьФорму("НастройкиАлгоритмов");
Форма.Открыть();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьРегистрацияCOMКомпонентЛкс() Экспорт
#Если ВебКлиент Тогда
СообщитьЛкс("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#Иначе
Форма = ирКэш.Получить().ПолучитьФорму("РегистрацияCOMКомпонент");
Форма.Открыть();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьОбработкаМодулейМетаданныхЛкс() Экспорт
#Если ВебКлиент Тогда
СообщитьЛкс("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#Иначе
Форма = ирКэш.Получить().ПолучитьФорму("ОбработкаМодулейМетаданных");
Форма.Открыть();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьПодключениеВнешнихИсточниковДанныхЛкс() Экспорт
#Если ВебКлиент Тогда
СообщитьЛкс("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#Иначе
Форма = ирКэш.Получить().ПолучитьФорму("ПодключениеВнешнихИсточниковДанных");
Форма.Открыть();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьГлобальноеМенюЛкс(АктивнаяФорма = Неопределено) Экспорт
#Если ВебКлиент Тогда
Сообщить("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#Иначе
Если АктивнаяФорма = Неопределено Тогда
АктивнаяФорма = АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если АктивнаяФорма = Неопределено Тогда
Возврат;
КонецЕсли;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Форма = мПлатформа.ПолучитьФорму("ГлобальноеМеню");
Если Не Форма.Открыта() Тогда
Форма.АктивнаяФорма = АктивнаяФорма;
Форма.ОткрытьМодально();
КонецЕсли;
#КонецЕсли
КонецПроцедуры
// Открывает справку по первой подсистеме метаданных переданного объекта
//
// Параметры:
// Объект - любой объект, имеющий метаданные.
//
Процедура ОткрытьСправкуПоПодсистемеЛкс(Объект = Неопределено) Экспорт
#Если ВебКлиент Тогда
Сообщить("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#Иначе
Если Ложь
Или ТипЗнч(Объект) = Тип("Неопределено")
Или ТипЗнч(Объект) = Тип("ОкноКлиентскогоПриложения")
Тогда
//
ИначеЕсли ТипЗнч(Объект) = Тип("Форма") Тогда
ПолноеИмяМД = СлужебныеДанныеФормыЛкс(Объект).ИмяФормы;
ИначеЕсли ТипЗнч(Объект) = Тип("УправляемаяФорма") Тогда
ПолноеИмяМД = Объект.ИмяФормы;
Иначе
Если ТипЗнч(Объект) = Тип("Тип") Тогда
ОбъектМД = Метаданные.НайтиПоТипу(Объект);
Иначе
ОбъектМД = Объект.Метаданные();
КонецЕсли;
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ПолноеИмяМД = СтрЗаменить(ПолноеИмяМД, "ВнешняяОбработка.", "Обработка.");
ПолноеИмяМД = СтрЗаменить(ПолноеИмяМД, "ВнешнийОтчет.", "Отчет.");
КонецЕсли;
Форма = ирКэш.Получить().ПолучитьФорму("ОПодсистеме",, ПолноеИмяМД);
Форма.Открыть();
#КонецЕсли
КонецПроцедуры // ОткрытьСправкуПоПодсистемеЛкс()
Функция ОткрытьФормуЛкс(ПолноеИмяФормы, Параметры = Неопределено, Владелец = Неопределено, Уникальность = Неопределено, Окно = Неопределено) Экспорт
#Если ТонкийКлиент Или ВебКлиент Тогда
Форма = ПолучитьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая", Параметры, Владелец, Уникальность, Окно);
#Иначе
Форма = ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
#КонецЕсли
Форма.Открыть();
Возврат Форма;
КонецФункции
#КонецЕсли
// Получает первый фрагмент, отделяемый разделителем от строки.
// Написана для оптимизации по скорости.
//
// Параметры:
// пСтрока - Строка - которую разбиваем;
// *пРазделитель - Строка, "." - символ-разделитель;
// *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина.
//
// Возвращаемое значение:
// - Строка - первый фрагмент строки;
// Неопределено - в строке не обнаружен разделитель.
//
Функция ПервыйФрагментЛкс(пСтрока, Разделитель = ".", ЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина) Экспорт
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Позиция = Найти(пСтрока, Разделитель);
Если Позиция > 0 Тогда
Возврат Лев(пСтрока, Позиция - 1);
Иначе
Если ЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда
Возврат пСтрока;
Иначе
Возврат "";
КонецЕсли;
КонецЕсли;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Позиция = Найти(пСтрока, Разделитель); Если Позиция > 0 Тогда Возврат Лев(пСтрока, Позиция - 1); Иначе Если ЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда Возврат пСтрока; Иначе Возврат ""; КонецЕсли; КонецЕсли;
КонецФункции // ПервыйФрагментЛкс()
Функция СтрКончаетсяНаЛкс(ПерваяСтрока, ВтораяСтрока, СУчетомРегистра = Ложь) Экспорт
КонецСтроки = Прав(ПерваяСтрока, СтрДлина(ВтораяСтрока));
Если СУчетомРегистра Тогда
Результат = КонецСтроки = ВтораяСтрока;
Иначе
Результат = НРег(КонецСтроки) = НРег(ВтораяСтрока);
КонецЕсли;
Возврат Результат;
КонецФункции
// Получает последний фрагмент, отделяемый разделителем от строки.
//
// Параметры:
// пСтрока - Строка - в которой ищем;
// *пМаркер – Строка, "." – отсекающий маркер;
// *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина - разрешение использования границ строки
// в случае, если маркер не найден.
//
// Возвращаемое значение:
// Неопределено - маркер не найден;
// – Число – позиция маркера.
//
Функция ПоследнийФрагментЛкс(пСтрока, пМаркер = ".", пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина) Экспорт
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Подстрока = пСтрока;
МаркерНайден = Ложь;
Пока пМаркер <> "" Цикл
Позиция = Найти(Подстрока, пМаркер);
Если Позиция = 0 Тогда
Прервать;
КонецЕсли;
МаркерНайден = Истина;
Подстрока = Сред(Подстрока, Позиция + СтрДлина(пМаркер));
КонецЦикла;
Если Истина
И Не МаркерНайден
И пЛиИспользоватьГраницуЕслиМаркерНеНайден
Тогда
Возврат пСтрока;
ИначеЕсли МаркерНайден Тогда
Возврат Подстрока;
Иначе
Возврат "";
КонецЕсли;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Подстрока = пСтрока; МаркерНайден = Ложь; Пока пМаркер <> "" Цикл Позиция = Найти(Подстрока, пМаркер); Если Позиция = 0 Тогда Прервать; КонецЕсли; МаркерНайден = Истина; Подстрока = Сред(Подстрока, Позиция + СтрДлина(пМаркер)); КонецЦикла; Если Истина И Не МаркерНайден И пЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда Возврат пСтрока; ИначеЕсли МаркерНайден Тогда Возврат Подстрока; Иначе Возврат ""; КонецЕсли;
КонецФункции // ПоследнийФрагментЛкс()
Функция ИменительныйПадежПериодаЛкс(Знач ЛюбойПадеж) Экспорт
ЛюбойПадеж = Нрег(ЛюбойПадеж);
Если ЛюбойПадеж = "года" Тогда
Результат = "год";
ИначеЕсли ЛюбойПадеж = "полугодия" Тогда
Результат = "полугодие";
ИначеЕсли ЛюбойПадеж = "квартала" Тогда
Результат = "квартал";
ИначеЕсли ЛюбойПадеж = "месяца" Тогда
Результат = "месяц";
ИначеЕсли ЛюбойПадеж = "декады" Тогда
Результат = "декада";
ИначеЕсли ЛюбойПадеж = "недели" Тогда
Результат = "неделя";
ИначеЕсли ЛюбойПадеж = "дня" Тогда
Результат = "день";
ИначеЕсли ЛюбойПадеж = "часа" Тогда
Результат = "час";
ИначеЕсли ЛюбойПадеж = "минуты" Тогда
Результат = "минута";
ИначеЕсли ЛюбойПадеж = "секунды" Тогда
Результат = "секунда";
Иначе
ВызватьИсключение "Период не опознан """ + ЛюбойПадеж + """";
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ДобавитьЕслиНужноПравыйСлешВФайловыйПутьЛкс(КаталогИсполняемыхФайлов) Экспорт
Если Прав(КаталогИсполняемыхФайлов, 1) <> "\" Тогда
КаталогИсполняемыхФайлов = КаталогИсполняемыхФайлов + "\";
КонецЕсли;
КонецПроцедуры
// Проверяет правильность заполнения реквизитов объекта
// Параметры:
// Объект -
// ОбязательныеПоля - Строка(0,П), Массив
// Отказ - Булево
// Заголовок - Строка(0,П)
//
// Возвращаемое значение: Булево - истина, если проверка пройдена успешно
Функция ПроверитьЗаполнениеРеквизитовОбъектаЛкс(Знач Объект, Знач ОбязательныеПоля = "", Отказ = Ложь) Экспорт
Результат = Истина;
Попытка
ОбменДаннымиЗагрузка = Объект.ОбменДанными.Загрузка;
Исключение
ОбменДаннымиЗагрузка = Ложь;
КонецПопытки;
Если ОбменДаннымиЗагрузка Тогда
Возврат Результат;
КонецЕсли;
Если ТипЗнч(ОбязательныеПоля) = Тип("Строка") Тогда
МассивПолей = СтрРазделитьЛкс(ОбязательныеПоля, ",", Истина);
ОбязательныеПоля = Новый Соответствие;
Для каждого Значение Из МассивПолей Цикл
ОбязательныеПоля[Значение] = "";
КонецЦикла;
//ОбязательныеПоля = Новый Структура(ОбязательныеПоля);
КонецЕсли;
РеквизитыМД = Объект.Метаданные().Реквизиты;
Для каждого КлючЗначение Из ОбязательныеПоля Цикл
ПутьКДанным = КлючЗначение.Ключ;
Значение = Вычислить("Объект." + ПутьКДанным);
Если Не ЗначениеЗаполнено(Значение) Тогда // надо ругаться
Если Не ЗначениеЗаполнено(КлючЗначение.Значение) Тогда
Фрагменты = СтрРазделитьЛкс(ПутьКДанным);
ИндексСтрокиТЧ = Неопределено;
Если Фрагменты.Количество() > 1 Тогда
ИндексСтрокиТЧ = СтрокаМеждуМаркерамиЛкс(Фрагменты[0], "[", "]", Ложь);
Если ИндексСтрокиТЧ <> Неопределено Тогда
ИндексСтрокиТЧ = Число(ИндексСтрокиТЧ);
//ИмяТЧ = ПолучитьПервыйФрагментИис(Фрагменты[0], "[");
КонецЕсли;
КонецЕсли;
//ПредставлениеРеквизита = РеквизитыМД[КлючЗначение.Ключ].Представление();
ПредставлениеРеквизита = СокрЛП(Фрагменты[Фрагменты.ВГраница()]);
СтрокаСообщения = "Не заполнено значение реквизита """ + ПредставлениеРеквизита + """";
Если ИндексСтрокиТЧ <> Неопределено Тогда
СтрокаСообщения = СтрокаСообщения + " в строке №" + Формат(ИндексСтрокиТЧ + 1, "ЧГ=") + " таблицы """ + СокрЛП(ирОбщий.ПервыйФрагментЛкс(Фрагменты[0], "[")) + """";
КонецЕсли;
Иначе
СтрокаСообщения = КлючЗначение.Значение;
КонецЕсли;
Отказ = Истина;
СообщитьЛкс(СтрокаСообщения, СтатусСообщения.Внимание);
Результат = Ложь;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ОписанияТиповПересекаютсяЛкс(ОписаниеТипов1, ОписаниеТипов2, ИсключаяПримитивныеТипы = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов1 = Новый ОписаниеТипов;
ОписаниеТипов2 = Новый ОписаниеТипов;
#КонецЕсли
Для Каждого Тип Из ОписаниеТипов1.Типы() Цикл
Если Истина
И ИсключаяПримитивныеТипы
И (Ложь
Или Тип = Тип("Булево")
Или Тип = Тип("Строка")
Или Тип = Тип("Число")
Или Тип = Тип("Дата"))
Тогда
Продолжить;
КонецЕсли;
Если ОписаниеТипов2.СодержитТип(Тип) Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
//
// Параметры:
// ВариантКвалификаторов - Число - 0 - пересекать, 1 - брать от ОписаниеТипов1, 2 - брать от ОписаниеТипов2
Функция ПересечьОписанияТиповЛкс(ОписаниеТипов1, ОписаниеТипов2, ИсключаяПримитивныеТипы = Ложь, ВариантКвалификаторов = 0) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов1 = Новый ОписаниеТипов;
ОписаниеТипов2 = Новый ОписаниеТипов;
#КонецЕсли
Если ВариантКвалификаторов = 1 Тогда
КвалификаторыЧисла = ОписаниеТипов1.КвалификаторыЧисла;
КвалификаторыСтроки = ОписаниеТипов1.КвалификаторыСтроки;
КвалификаторыДаты = ОписаниеТипов1.КвалификаторыДаты;
Иначе
КвалификаторыЧисла = ОписаниеТипов2.КвалификаторыЧисла;
КвалификаторыСтроки = ОписаниеТипов2.КвалификаторыСтроки;
КвалификаторыДаты = ОписаниеТипов2.КвалификаторыДаты;
Если ВариантКвалификаторов = 0 Тогда
Если КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная И ОписаниеТипов1.КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная Тогда
ДопустимаяДлинаНовая = ДопустимаяДлина.Переменная;
Иначе
ДопустимаяДлинаНовая = ДопустимаяДлина.Фиксированная;
КонецЕсли;
КвалификаторыСтроки = Новый КвалификаторыСтроки(
Мин(КвалификаторыСтроки.Длина, ОписаниеТипов1.КвалификаторыСтроки.Длина),
ДопустимаяДлинаНовая);
КвалификаторыЧисла = Новый КвалификаторыЧисла(
Мин(КвалификаторыЧисла.Разрядность, ОписаниеТипов1.КвалификаторыЧисла.Разрядность),
Мин(КвалификаторыЧисла.РазрядностьДробнойЧасти, ОписаниеТипов1.КвалификаторыЧисла.РазрядностьДробнойЧасти),
?(КвалификаторыЧисла.ДопустимыйЗнак = ДопустимыйЗнак.Неотрицательный, КвалификаторыЧисла.ДопустимыйЗнак, ОписаниеТипов1.КвалификаторыЧисла.ДопустимыйЗнак));
Если КвалификаторыДаты.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда
ЧастиДатыНовая = ОписаниеТипов1.КвалификаторыДаты.ЧастиДаты;
ИначеЕсли КвалификаторыДаты.ЧастиДаты <> ОписаниеТипов1.КвалификаторыДаты.ЧастиДаты И ОписаниеТипов1.КвалификаторыДаты.ЧастиДаты <> ЧастиДаты.ДатаВремя Тогда
ЧастиДатыНовая = ЧастиДаты.ДатаВремя;
Иначе
ЧастиДатыНовая = КвалификаторыДаты.ЧастиДаты;
КонецЕсли;
КвалификаторыДаты = Новый КвалификаторыДаты(ЧастиДатыНовая);
КонецЕсли;
КонецЕсли;
МассивОбщихТипов = Новый Массив;
Для Каждого Тип Из ОписаниеТипов1.Типы() Цикл
Если Истина
И ИсключаяПримитивныеТипы
И (Ложь
Или Тип = Тип("Булево")
Или Тип = Тип("Строка")
Или Тип = Тип("Число")
Или Тип = Тип("Дата"))
Тогда
Продолжить;
КонецЕсли;
Если ОписаниеТипов2.СодержитТип(Тип) Тогда
МассивОбщихТипов.Добавить(Тип);
КонецЕсли;
КонецЦикла;
Результат = Новый ОписаниеТипов(МассивОбщихТипов,,, КвалификаторыЧисла, КвалификаторыСтроки, КвалификаторыДаты);
Возврат Результат;
КонецФункции
Функция ОбъединитьОписанияТиповЛкс(ОписаниеТипов1, ОписаниеТипов2) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов1 = Новый ОписаниеТипов;
ОписаниеТипов2 = Новый ОписаниеТипов;
#КонецЕсли
КвалификаторыСтроки = ОписаниеТипов2.КвалификаторыСтроки;
Если КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная Или ОписаниеТипов1.КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная Тогда
ДопустимаяДлинаНовая = ДопустимаяДлина.Переменная;
Иначе
ДопустимаяДлинаНовая = ДопустимаяДлина.Фиксированная;
КонецЕсли;
КвалификаторыСтроки = Новый КвалификаторыСтроки(
Макс(КвалификаторыСтроки.Длина, ОписаниеТипов1.КвалификаторыСтроки.Длина),
ДопустимаяДлинаНовая);
КвалификаторыЧисла = ОписаниеТипов2.КвалификаторыЧисла;
КвалификаторыЧисла = Новый КвалификаторыЧисла(
Макс(КвалификаторыЧисла.Разрядность, ОписаниеТипов1.КвалификаторыЧисла.Разрядность),
Макс(КвалификаторыЧисла.РазрядностьДробнойЧасти, ОписаниеТипов1.КвалификаторыЧисла.РазрядностьДробнойЧасти),
?(КвалификаторыЧисла.ДопустимыйЗнак = ДопустимыйЗнак.Любой, КвалификаторыЧисла.ДопустимыйЗнак, ОписаниеТипов1.КвалификаторыЧисла.ДопустимыйЗнак));
КвалификаторыДаты = ОписаниеТипов2.КвалификаторыДаты;
Если КвалификаторыДаты.ЧастиДаты = ОписаниеТипов1.КвалификаторыДаты.ЧастиДаты Тогда
ЧастиДатыНовая = КвалификаторыДаты.ЧастиДаты;
Иначе
ЧастиДатыНовая = ЧастиДаты.ДатаВремя;
КонецЕсли;
КвалификаторыДаты = Новый КвалификаторыДаты(ЧастиДатыНовая);
МассивОбщихТипов = ОписаниеТипов1.Типы();
Для Каждого Тип Из ОписаниеТипов2.Типы() Цикл
МассивОбщихТипов.Добавить(Тип);
КонецЦикла;
Результат = Новый ОписаниеТипов(МассивОбщихТипов,,, КвалификаторыЧисла, КвалификаторыСтроки, КвалификаторыДаты);
Возврат Результат;
КонецФункции
// Проверяет, отвечает ли строка правилам формирования имен переменных встроенного языка.
//
// Параметры:
// Строка – Строка.
//
// Возвращаемое значение:
// Булево.
//
Функция ЛиИмяПеременнойЛкс(Строка) Экспорт
Если ПустаяСтрока(Строка) Тогда
Возврат Ложь;
КонецЕсли;
Пустышка = Новый Структура;
Попытка
Пустышка.Вставить(Строка);
Возврат Истина;
Исключение
Возврат Ложь;
КонецПопытки;
КонецФункции // ЛиИмяПеременнойЛкс()
// Пространство имен текущей конфигурации.
// Возвращаемое значение:
//
Функция ПространствоИменТекущейКонфигурацииЛкс() Экспорт
Возврат "http://v8.1c.ru/8.1/data/enterprise/current-config";
КонецФункции
Функция БезопасноПолучитьЗначениеСвойстваЛкс(ЭлементФормы, Знач ИмяСвойстваЗаголовка) Экспорт
СтруктураЗначений = Новый Структура(ИмяСвойстваЗаголовка);
ЗаполнитьЗначенияСвойств(СтруктураЗначений, ЭлементФормы);
ЗаголовокЭлемента = СтруктураЗначений[ИмяСвойстваЗаголовка];
Возврат ЗаголовокЭлемента;
КонецФункции
// Функция - Восстановить текущую строку таблицы формы лкс
//
// Параметры:
// ТабличноеПоле - ТабличноеПоле, ТаблицаФормы -
// КлючТекущейСтроки - Структура -
// ДанныеТаблицы - -
//
// Возвращаемое значение:
// - Булево - успешность установки текущей строки
//
Функция ТабличноеПолеВосстановитьТекущуюСтрокуЛкс(ТабличноеПоле, Знач КлючТекущейСтроки, Знач ДанныеТаблицы = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
Если КлючТекущейСтроки <> Неопределено Тогда
Если ДанныеТаблицы = Неопределено Тогда
ДанныеТаблицы = ТабличноеПоле.Значение;
КонецЕсли;
Строка = СтрокаТабличнойКоллекцииПоКлючуЛкс(ДанныеТаблицы, КлючТекущейСтроки);
Если Строка <> Неопределено Тогда
Попытка
ИдентификаторСтроки = Строка.ПолучитьИдентификатор();
Исключение
ИдентификаторСтроки = Строка;
КонецПопытки;
ТабличноеПоле.ТекущаяСтрока = ИдентификаторСтроки;
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ТабличноеПолеВосстановитьВыделенныеСтрокиЛкс(ТабличноеПоле, Знач КлючиВыделенныхСтрок, Знач ДанныеТаблицы = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличноеПоле = Новый ТабличноеПоле;
#КонецЕсли
Если КлючиВыделенныхСтрок.Количество() > 0 Тогда
ТабличноеПоле.ВыделенныеСтроки.Очистить();
КонецЕсли;
Для Каждого КлючВыделеннойСтроки Из КлючиВыделенныхСтрок Цикл
Если ДанныеТаблицы = Неопределено Тогда
ДанныеТаблицы = ТабличноеПоле.Значение;
КонецЕсли;
Строка = СтрокаТабличнойКоллекцииПоКлючуЛкс(ДанныеТаблицы, КлючВыделеннойСтроки);
Если Строка <> Неопределено Тогда
Попытка
ИдентификаторСтроки = Строка.ПолучитьИдентификатор();
Исключение
ИдентификаторСтроки = Строка;
КонецПопытки;
ТабличноеПоле.ВыделенныеСтроки.Добавить(ИдентификаторСтроки);
КонецЕсли;
КонецЦикла;
КонецФункции
Функция ТабличноеПолеВосстановитьСостояниеСтрокЛкс(Знач ТабличноеПоле, Знач СтруктураСостояния) Экспорт
ТекущаяСтрокаУстановлена = ТабличноеПолеВосстановитьТекущуюСтрокуЛкс(ТабличноеПоле, СтруктураСостояния.ТекущаяСтрока);
ТабличноеПолеВосстановитьВыделенныеСтрокиЛкс(ТабличноеПоле, СтруктураСостояния.ВыделенныеСтроки);
Возврат ТекущаяСтрокаУстановлена;
КонецФункции
Функция СтрокаТабличнойКоллекцииПоКлючуЛкс(Знач ТабличнаяКоллекция, Знач КлючТекущейСтроки) Экспорт
Если ТипЗнч(КлючТекущейСтроки) = Тип("Структура") Тогда
Если ТипЗнч(ТабличнаяКоллекция) = Тип("ДеревоЗначений") Тогда
НайденныеСтроки = ТабличнаяКоллекция.Строки.НайтиСтроки(КлючТекущейСтроки, Истина);
Иначе
НайденныеСтроки = ТабличнаяКоллекция.НайтиСтроки(КлючТекущейСтроки);
КонецЕсли;
Если НайденныеСтроки.Количество() > 0 Тогда
Строка = НайденныеСтроки[0];
КонецЕсли;
Иначе
Если ТабличнаяКоллекция.Количество() > КлючТекущейСтроки Тогда
Строка = ТабличнаяКоллекция[КлючТекущейСтроки];
КонецЕсли;
КонецЕсли;
Возврат Строка;
КонецФункции
// Результат:
// Структура
Функция ТабличноеПолеКлючСтрокиЛкс(ТаблицаФормы, ИменаКлючевыхКолонок = "Ссылка", Знач СтрокаТаблицы = Неопределено) Экспорт
Если СтрокаТаблицы = Неопределено Тогда
СтрокаТаблицы = ТаблицаФормы.ТекущиеДанные;
КонецЕсли;
Если СтрокаТаблицы <> Неопределено Тогда
КлючТекущейСтроки = Новый Структура(ИменаКлючевыхКолонок);
ЗаполнитьЗначенияСвойств(КлючТекущейСтроки, СтрокаТаблицы, ИменаКлючевыхКолонок);
КонецЕсли;
Возврат КлючТекущейСтроки;
КонецФункции
Функция ТабличноеПолеКлючиСтрокЛкс(ТаблицаФормы, ИменаКлючевыхКолонок = "Ссылка", Знач СтрокиТаблицы = Неопределено) Экспорт
Если СтрокиТаблицы = Неопределено Тогда
СтрокиТаблицы = ТаблицаФормы.ВыделенныеСтроки;
КонецЕсли;
Результат = Новый Массив;
Для Каждого СтрокаТаблицы Из СтрокиТаблицы Цикл
Если СтрокаТаблицы = Неопределено Тогда
// Случается в дереве формы ирРедакторИзмененийНаУзлах
Продолжить;
КонецЕсли;
КлючТекущейСтроки = Новый Структура(ИменаКлючевыхКолонок);
ЗаполнитьЗначенияСвойств(КлючТекущейСтроки, СтрокаТаблицы, ИменаКлючевыхКолонок);
Результат.Добавить(КлючТекущейСтроки);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ТабличноеПолеСостояниеСтрокЛкс(Знач ТабличноеПоле, Знач ИменаКлючевыхКолонок) Экспорт
СтруктураСостояния = Новый Структура("ТекущаяСтрока, ВыделенныеСтроки");
СтруктураСостояния.ТекущаяСтрока = ТабличноеПолеКлючСтрокиЛкс(ТабличноеПоле, ИменаКлючевыхКолонок);
СтруктураСостояния.ВыделенныеСтроки = ТабличноеПолеКлючиСтрокЛкс(ТабличноеПоле, ИменаКлючевыхКолонок);
Возврат СтруктураСостояния;
КонецФункции
Функция ИмяФормыИзФормыЛкс(ЭтаФорма) Экспорт
Если ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма") Тогда
Результат = ЭтаФорма.ИмяФормы;
Иначе
Результат = СлужебныеДанныеФормыЛкс(ЭтаФорма).ИмяФормы;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СлужебныеДанныеФормыЛкс(ЭтаФорма) Экспорт
Результат = Неопределено;
#Если Клиент Тогда
Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда
Результат = ЭтаФорма.Панель.Страницы[0].Значение;
Если Результат = Неопределено Тогда
Результат = Новый Структура();
ЭтаФорма.Панель.Страницы[0].Значение = Результат;
КонецЕсли;
Иначе
#КонецЕсли
Попытка
Результат = ЭтаФорма.мСлужебныеДанные;
Исключение
КонецПопытки;
#Если Клиент Тогда
КонецЕсли;
#КонецЕсли
Возврат Результат;
КонецФункции
Процедура ОчиститьПодчиненныеЭлементыФормыЛкс(Знач Родитель, КоличествоНеудаляемых = 1) Экспорт
Если Ложь
#Если Клиент Тогда
Или ТипЗнч(Родитель) = Тип("Панель")
#КонецЕсли
Тогда
Родитель.Страницы.Очистить();
ИначеЕсли Ложь
#Если Клиент Тогда
Или ТипЗнч(Родитель) = Тип("ТабличноеПоле")
#КонецЕсли
Тогда
Родитель.Колонки.Очистить();
Иначе
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(Родитель);
ПодчиненныеЭлементы = Родитель.ПодчиненныеЭлементы;
НачальноеКоличество = ПодчиненныеЭлементы.Количество();
Для Счетчик = 1 По НачальноеКоличество Цикл
ПодчиненныйЭлемент = ПодчиненныеЭлементы[НачальноеКоличество - Счетчик];
Если ПодчиненныеЭлементы.Количество() > КоличествоНеудаляемых Тогда
ЭтаФорма.Элементы.Удалить(ПодчиненныйЭлемент);
Иначе
// Статистически добавленные нельзя удалять
ПодчиненныйЭлемент.Видимость = Ложь;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура УстановитьГотовностьДанныхСтраницыЛкс(ЭтаФорма, Страница, Готовность = Истина) Экспорт
НеготовыеСтраницы = СлужебныеДанныеФормыЛкс(ЭтаФорма).НеготовыеСтраницы;
#Если Сервер И Не Сервер Тогда
НеготовыеСтраницы = Новый СписокЗначений;
#КонецЕсли
ЭлементСписка = НеготовыеСтраницы.НайтиПоЗначению(Страница.Имя);
Если ЭлементСписка <> Неопределено И Готовность Тогда
НеготовыеСтраницы.Удалить(ЭлементСписка);
ИначеЕсли ЭлементСписка = Неопределено И Не Готовность Тогда
НеготовыеСтраницы.Добавить(Страница.Имя);
КонецЕсли;
КонецПроцедуры
Функция ПолучитьГотовностьДанныхСтраницыЛкс(ЭтаФорма, Страница, Готовность = Истина) Экспорт
НеготовыеСтраницы = СлужебныеДанныеФормыЛкс(ЭтаФорма).НеготовыеСтраницы;
#Если Сервер И Не Сервер Тогда
НеготовыеСтраницы = Новый СписокЗначений;
#КонецЕсли
ЭлементСписка = НеготовыеСтраницы.НайтиПоЗначению(Страница.Имя);
Результат = ЭлементСписка = Неопределено;
Возврат Результат;
КонецФункции
Процедура СоздатьКолонкиТабличногоПоляЛкс(ТабличноеПоле, ЗаменитьКолонкуНомерСтроки = Ложь) Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
ОчиститьПодчиненныеЭлементыФормыЛкс(ТабличноеПоле, 0);
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле);
ПутьКДанным = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТабличноеПоле);
РеквизитыТаблицы = ЭтаФорма.ПолучитьРеквизиты(ПутьКДанным);
Для Каждого РеквизитТаблицы Из РеквизитыТаблицы Цикл
ПолеФормы = ЭтаФорма.Элементы.Добавить(ТабличноеПоле.Имя + РеквизитТаблицы.Имя, Тип("ПолеФормы"), ТабличноеПоле);
ПолеФормы.Вид = ВидПоляФормы.ПолеВвода;
Попытка
ПолеФормы.ПутьКДанным = ПутьКДанным + "." + РеквизитТаблицы.Имя;
Исключение
// При РеквизитТаблицы.Имя = "КоличествоСтрок"
КонецПопытки;
КонецЦикла;
Иначе
ТабличноеПоле.СоздатьКолонки();
Если ЗаменитьКолонкуНомерСтроки И ТабличноеПоле.Значение.Колонки.Найти("НомерСтроки") <> Неопределено Тогда
ТабличноеПоле.Колонки.НомерСтроки.Данные = "";
ТабличноеПоле.Колонки.НомерСтроки.ТолькоПросмотр = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьТипЗначенияЭлементаФормыЛкс(ЭлементФормы, ВызыватьИсключение = Истина) Экспорт
Попытка
ТипЗначения = ЭлементФормы.ТипЗначения;
Исключение
// Упр
ЭтаФорма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(ЭлементФормы);
Попытка
ТипЗначения = ЭтаФорма.мСлужебныеДанные.ТипыЗначений[ЭлементФормы.Имя];
Исключение
Если ВызыватьИсключение Тогда
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
КонецПопытки;
Возврат ТипЗначения;
КонецФункции
// Чтобы функция всегда возвращала правильное значение в управляемой форме, должен быть
// выполнен общий обработчик формы _ПриСозданииНаСервереИис.
//
// Параметры:
// Поле - <тип> -
//
// Возвращаемое значение:
//
Функция ДанныеЭлементаФормыЛкс(Знач Элемент, выхПутьКДанным = "") Экспорт
Попытка
// Обычная форма
Данные = Элемент.Значение;
Попытка
выхПутьКДанным = Элемент.Данные;
Исключение
// Колонка табличного поля
выхПутьКДанным = Неопределено;
КонецПопытки;
Возврат Данные;
Исключение
КонецПопытки;
Если Ложь
#Если Клиент Тогда
Или ТипЗнч(Элемент) = Тип("ПолеТабличногоДокумента")
#КонецЕсли
Тогда
Данные = Элемент;
Иначе
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(Элемент, Тип("УправляемаяФорма")); // Переменная ЭтаФорма используется в Вычислить ниже
выхПутьКДанным = ПутьКДаннымЭлементаУправляемойФормыЛкс(Элемент, , ЭтаФорма);
Если Не ЗначениеЗаполнено(выхПутьКДанным) Тогда
выхПутьКДанным = Элемент.Имя;
КонецЕсли;
Попытка
Данные = Вычислить("ЭтаФорма." + выхПутьКДанным);
Исключение
Данные = Неопределено;
КонецПопытки;
Если Данные = Неопределено Тогда
ЧастыеИменаОбъектов = Новый Массив;
ЧастыеИменаОбъектов.Добавить("Объект");
ЧастыеИменаОбъектов.Добавить("Запись");
ЧастыеИменаОбъектов.Добавить("Отчет");
ЧастыеИменаОбъектов.Добавить("Обработка");
ЧастыеИменаОбъектов.Добавить("Задача");
Для Каждого ИмяОбъекта Из ЧастыеИменаОбъектов Цикл
выхПутьКДанным = ИмяОбъекта + "." + Элемент.Имя;
Попытка
Данные = Вычислить("ЭтаФорма." + выхПутьКДанным);
Прервать;
Исключение
КонецПопытки;
КонецЦикла;
Если Данные = Неопределено Тогда
Для Счетчик = 1 По СтрДлина(Элемент.Имя) Цикл
выхПутьКДанным = Лев(Элемент.Имя, Счетчик) + "." + Сред(Элемент.Имя, Счетчик + 1);
Попытка
Данные = Вычислить("ЭтаФорма." + выхПутьКДанным);
Прервать;
Исключение
КонецПопытки;
КонецЦикла;
КонецЕсли;
Если Данные = Неопределено Тогда
выхПутьКДанным = Неопределено;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Данные;
КонецФункции
Функция ИдентификаторСтрокиТабличногоПоляЛкс(Знач НоваяСтрока) Экспорт
Если Ложь
Или ТипЗнч(НоваяСтрока) = Тип("ДанныеФормыЭлементКоллекции")
Или ТипЗнч(НоваяСтрока) = Тип("ДанныеФормыЭлементДерева")
Тогда
НоваяСтрока = НоваяСтрока.ПолучитьИдентификатор();
КонецЕсли;
Возврат НоваяСтрока;
КонецФункции
Функция НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(Знач Коллекция, Знач Свойство, Знач Значение, Знач ТипЭлемента = Неопределено) Экспорт
Структура = Новый Структура(Свойство);
Для каждого Элемент Из Коллекция Цикл
Если Истина
И ТипЭлемента <> Неопределено
И ТипЗнч(Элемент) <> ТипЭлемента
Тогда
Продолжить;
КонецЕсли;
ЗаполнитьЗначенияСвойств(Структура, Элемент, Свойство);
Если Структура[Свойство] = Значение Тогда
Результат = Элемент;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ЗначенияСвойстваКоллекцииЛкс(Знач Коллекция, Знач Свойство = "Имя", Знач ТипЭлемента = Неопределено) Экспорт
Результат = Новый Массив;
Для каждого Элемент Из Коллекция Цикл
Если Истина
И ТипЭлемента <> Неопределено
И ТипЗнч(Элемент) <> ТипЭлемента
Тогда
Продолжить;
КонецЕсли;
Результат.Добавить(Элемент[Свойство]);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция РежимОтладкиИзКоманднойСтрокиЛкс(Знач СтрокаЗапускаПроцесса) Экспорт
МаркерОтладки = "-debug";
ПозицияСтрокиТипаОтладчика = Найти(НРег(СтрокаЗапускаПроцесса), Нрег(МаркерОтладки));
Если ЗначениеЗаполнено(ПозицияСтрокиТипаОтладчика) Тогда
СтрокаОтладчика = СокрЛ(Сред(СтрокаЗапускаПроцесса, ПозицияСтрокиТипаОтладчика + СтрДлина(МаркерОтладки)));
Если Найти(НРег(СтрокаОтладчика), "-http") = 1 Тогда
РежимОтладки = "http";
Иначе
РежимОтладки = "tcp";
КонецЕсли;
Иначе
РежимОтладки = "нет";
КонецЕсли;
Возврат РежимОтладки;
КонецФункции // Заполнить()
Функция СтрЗаменитьЛкс(Знач ГдеЗаменять, Знач ЧтоЗаменять, Знач НаЧтоЗаменять, ОставитьЧтоЗаменять = Ложь, ВыброситьИсключениеПриОтсутствии = Истина) Экспорт
Если ВыброситьИсключениеПриОтсутствии И Найти(ГдеЗаменять, ЧтоЗаменять) < 1 Тогда
ВызватьИсключение "Шаблонная строка """ + ЧтоЗаменять + """ не найдена в тексте";
КонецЕсли;
Если ОставитьЧтоЗаменять Тогда
НаЧтоЗаменять = ЧтоЗаменять + НаЧтоЗаменять;
КонецЕсли;
Результат = СтрЗаменить(ГдеЗаменять, ЧтоЗаменять, НаЧтоЗаменять);
Возврат Результат;
КонецФункции
Функция СтрНайтиЛкс(Знач Строка, Знач ПодстрокаПоиска, Знач НаправлениеПоискаСКонца = Ложь, Знач НачальнаяПозиция = Неопределено, Знач НомерВхождения = 1) Экспорт
Если ирКэш.НомерРежимаСовместимостиЛкс() >= 803006 Тогда
Возврат Вычислить("СтрНайти(Строка, ПодстрокаПоиска, ?(НаправлениеПоискаСКонца, НаправлениеПоиска.СКонца, НаправлениеПоиска.СНачала), НачальнаяПозиция, НомерВхождения)");
КонецЕсли;
ТекущаяПозиция = 0;
ЗнакНаправленияДвижения = 0;
ДлинаСтрПоиска = СтрДлина(ПодстрокаПоиска);
Попытка
Если НачальнаяПозиция <> Неопределено Тогда
НачальнаяПозиция = Число(НачальнаяПозиция);
Если НачальнаяПозиция <= 0 ИЛИ НачальнаяПозиция > СтрДлина(Строка) Тогда
ВызватьИсключение ("");
КонецЕсли;
КонецЕсли;
Исключение
ВызватьИсключение("Недопустимое значение параметра (параметр номер '4')");
КонецПопытки;
Если НаправлениеПоискаСКонца Тогда
НачальнаяПозиция = ?(НачальнаяПозиция <> Неопределено, НачальнаяПозиция, СтрДлина(Строка));
ЗнакНаправленияДвижения = -1;
Иначе
НачальнаяПозиция = ?(НачальнаяПозиция <> Неопределено, НачальнаяПозиция, 1);
ЗнакНаправленияДвижения = 1;
КонецЕсли;
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Пока Истина
И НомерВхождения <> 0
И (Ложь
Или (Истина
И Не НаправлениеПоискаСКонца
И НачальнаяПозиция <= СтрДлина(Строка))
Или (Истина
И НаправлениеПоискаСКонца
И НачальнаяПозиция >= 0))
Цикл
Позиция = Найти(Сред(Строка, НачальнаяПозиция, ДлинаСтрПоиска), ПодстрокаПоиска);
Если Позиция Тогда
ТекущаяПозиция = НачальнаяПозиция;
НачальнаяПозиция = ТекущаяПозиция + ДлинаСтрПоиска * ЗнакНаправленияДвижения;
НомерВхождения = НомерВхождения - 1;
Иначе
НачальнаяПозиция = НачальнаяПозиция + 1 * ЗнакНаправленияДвижения;
КонецЕсли;
КонецЦикла;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Пока Истина И НомерВхождения <> 0 И (Ложь Или (Истина И Не НаправлениеПоискаСКонца И НачальнаяПозиция <= СтрДлина(Строка)) Или (Истина И НаправлениеПоискаСКонца И НачальнаяПозиция >= 0)) Цикл Позиция = Найти(Сред(Строка, НачальнаяПозиция, ДлинаСтрПоиска), ПодстрокаПоиска); Если Позиция Тогда ТекущаяПозиция = НачальнаяПозиция; НачальнаяПозиция = ТекущаяПозиция + ДлинаСтрПоиска * ЗнакНаправленияДвижения; НомерВхождения = НомерВхождения - 1; Иначе НачальнаяПозиция = НачальнаяПозиция + 1 * ЗнакНаправленияДвижения; КонецЕсли; КонецЦикла;
Если НомерВхождения Тогда
ТекущаяПозиция = 0;
КонецЕсли;
Возврат ТекущаяПозиция;
КонецФункции
Функция СтрНачинаетсяСЛкс(ГдеИщем, ЧтоИщем, УчитыватьРегистр = Ложь) Экспорт
Длина = СтрДлина(ЧтоИщем);
Результат = Ложь
Или (Истина
И УчитыватьРегистр
И Лев(ГдеИщем, Длина) = ЧтоИщем)
Или (Истина
И Не УчитыватьРегистр
И Лев(НРег(ГдеИщем), Длина) = НРег(ЧтоИщем));
Возврат Результат;
КонецФункции
// Функция разбивает строку разделителем.
//
// Параметры:
// пСтрока - Строка - которую разбиваем;
// *пРазделитель - Строка, "." - символ-разделитель;
// *ОбрезатьНепечатныеСимволы - Булево, *Ложь - делать СокрЛП.
// *ОставлятьПустуюСтроку - Булево, *Истина - если передана пустая строка, то добавлять ее в массив.
//
// Возвращаемое значение:
// Массив - фрагментов.
//
Функция СтрРазделитьЛкс(Знач Стр, Знач Разделитель = ".", Знач ОбрезатьНепечатныеСимволы = Ложь, Знач ОставлятьПустуюСтроку = Истина) Экспорт
МассивСтрок = Новый Массив;
Если Истина
И Не ОставлятьПустуюСтроку
И ПустаяСтрока(Стр)
Тогда
Возврат МассивСтрок;
КонецЕсли;
//Если Найти(Стр, Символы.ПС) = 0 Тогда
// // Этот способ проще, но дольше и не допускает наличия переносов строк
// ТекстовыйДокумент = Новый ТекстовыйДокумент;
// ТекстовыйДокумент.УстановитьТекст(СтрЗаменить(Стр, Разделитель, Символы.ПС) + " ");
// КоличествоСтрок = ТекстовыйДокумент.КоличествоСтрок();
// Для Счетчик = 1 По КоличествоСтрок Цикл
// Фрагмент = ТекстовыйДокумент.ПолучитьСтроку(Счетчик);
// Если ОбрезатьНепечатныеСимволы Тогда
// Фрагмент = СокрЛП(Фрагмент);
// КонецЕсли;
// Если Счетчик = КоличествоСтрок Тогда
// Фрагмент = Сред(Фрагмент, 1, СтрДлина(Фрагмент) - 1);
// КонецЕсли;
// МассивСтрок.Добавить(Фрагмент);
// КонецЦикла;
// //лСтрока = СтрЗаменить(Стр, Разделитель, Символы.ПС);
// //// Баг платформы. СтрЧислоСтрок не учитывает терминальный перевод строки.
// //ЧислоСтрок = СтрЧислоСтрок(лСтрока + " ");
// //Для Счетчик = 1 По ЧислоСтрок Цикл
// // Фрагмент = СтрПолучитьСтроку(лСтрока, Счетчик);
// // Если ОбрезатьНепечатныеСимволы Тогда
// // Фрагмент = СокрЛП(Фрагмент);
// // КонецЕсли;
// // МассивСтрок.Добавить(Фрагмент);
// //КонецЦикла;
// Оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Если Разделитель = " " Тогда
Стр = СокрЛП(Стр);
Пока 1=1 Цикл
Поз = Найти(Стр, Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр, Поз-1));
Стр = СокрЛ(Сред(Стр, Поз));
КонецЦикла;
Иначе
ДлинаРазделителя = СтрДлина(Разделитель);
Пока 1=1 Цикл
Поз = Найти(Стр, Разделитель);
Если Поз=0 Тогда
Фрагмент = Стр;
Если ОбрезатьНепечатныеСимволы Тогда
Фрагмент = СокрЛП(Фрагмент);
КонецЕсли;
МассивСтрок.Добавить(Фрагмент);
Возврат МассивСтрок;
КонецЕсли;
Фрагмент = Лев(Стр, Поз-1);
Если ОбрезатьНепечатныеСимволы Тогда
Фрагмент = СокрЛП(Фрагмент);
КонецЕсли;
МассивСтрок.Добавить(Фрагмент);
Стр = Сред(Стр, Поз+ДлинаРазделителя);
КонецЦикла;
КонецЕсли;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы ""Инструменты разработчика"" (http://devtool1c.ucoz.ru)
Если Разделитель = " " Тогда Стр = СокрЛП(Стр); Пока 1=1 Цикл Поз = Найти(Стр, Разделитель); Если Поз=0 Тогда МассивСтрок.Добавить(Стр); Возврат МассивСтрок; КонецЕсли; МассивСтрок.Добавить(Лев(Стр, Поз-1)); Стр = СокрЛ(Сред(Стр, Поз)); КонецЦикла; Иначе ДлинаРазделителя = СтрДлина(Разделитель); Пока 1=1 Цикл Поз = Найти(Стр, Разделитель); Если Поз=0 Тогда Фрагмент = Стр; Если ОбрезатьНепечатныеСимволы Тогда Фрагмент = СокрЛП(Фрагмент); КонецЕсли; МассивСтрок.Добавить(Фрагмент); Возврат МассивСтрок; КонецЕсли; Фрагмент = Лев(Стр, Поз-1); Если ОбрезатьНепечатныеСимволы Тогда Фрагмент = СокрЛП(Фрагмент); КонецЕсли; МассивСтрок.Добавить(Фрагмент); Стр = Сред(Стр, Поз+ДлинаРазделителя); КонецЦикла; КонецЕсли;
Возврат МассивСтрок;
КонецФункции
// Получает подстроку заключенную между первым вхождением начального маркера и первым вхождением
// в правой части конечного маркера. Сами маркеры не включаются в результат. Опционально - если
// маркер не найден, то границей считается граница строки.
//
// Параметры:
// пСтрока - Строка - в которой ищем;
// *пНачальныйМаркер - Строка, *Неопределено - начальный маркер подстроки;
// *пКонечныйМаркер - Строка, *Неопределено - конечный маркер подстроки;
// *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина - разрешение использования границ строки
// в случае, если маркер не найден;
// *пЛиВключатьМаркеры - Булево, *Ложь - включение маркеров в результат.
//
// Возвращаемое значение:
// Неопределено - обязательные условия не выполнены;
// Строка – найденная подстрока.
//
Функция СтрокаМеждуМаркерамиЛкс(пСтрока, пНачальныйМаркер = Неопределено, пКонечныйМаркер = Неопределено,
пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина, пЛиВключатьМаркеры = Ложь, ВыброситьИсключениеЕслиНеНайдено = Ложь) Экспорт
ПозицияНачальногоМаркера = Найти(пСтрока, пНачальныйМаркер);
Если Истина
И ПозицияНачальногоМаркера = 0
И пЛиИспользоватьГраницуЕслиМаркерНеНайден = Ложь
Тогда
Если ВыброситьИсключениеЕслиНеНайдено Тогда
ВызватьИсключение "Не найдено вхождение начального маркера";
Иначе
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Если Ложь
ИЛИ пНачальныйМаркер = Неопределено
ИЛИ ПозицияНачальногоМаркера = 0
Тогда
ПозицияНачальногоМаркера = - СтрДлина(пНачальныйМаркер);
КонецЕсли;
Стр = Сред(пСтрока, ПозицияНачальногоМаркера + СтрДлина(пНачальныйМаркер));
ПозицияКонечногоМаркера = Найти(Стр, пКонечныйМаркер);
Если Истина
И ПозицияКонечногоМаркера = 0
И пЛиИспользоватьГраницуЕслиМаркерНеНайден = Ложь
Тогда
Если ВыброситьИсключениеЕслиНеНайдено Тогда
ВызватьИсключение "Не найдено вхождение конечного маркера";
Иначе
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Если Ложь
ИЛИ пКонечныйМаркер = Неопределено
ИЛИ ПозицияКонечногоМаркера = 0
Тогда
ПозицияКонечногоМаркера = СтрДлина(Стр) + 1;
КонецЕсли;
Результат = Лев(Стр, ПозицияКонечногоМаркера - 1);
Если пЛиВключатьМаркеры Тогда
Если пНачальныйМаркер <> Неопределено Тогда
Результат = пНачальныйМаркер + Результат;
КонецЕсли;
Если пКонечныйМаркер <> Неопределено Тогда
Результат = Результат + пКонечныйМаркер;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПервыеНепечатныеСимволыЛкс(ТекстНовогоМетода) Экспорт
RegExp = ирКэш.ВычислительРегулярныхВыраженийЛкс();
RegExp.Global = Ложь;
RegExp.Pattern = "\S";
Результат = RegExp.Execute(ТекстНовогоМетода);
Если Результат.Count > 0 Тогда
ТекстСмещения = Лев(ТекстНовогоМетода, Результат.Item(0).FirstIndex);
Иначе
ТекстСмещения = "";
КонецЕсли;
Возврат ТекстСмещения;
КонецФункции
Функция ЛиВнутриСтроковогоЛитералаЛкс(ТекущееНачалоСтроки) Экспорт
Возврат (?(Лев(СокрЛ(ТекущееНачалоСтроки), 1) = "|", 1, 0) + СтрЧислоВхождений(ТекущееНачалоСтроки, """")) % 2 = 1;
КонецФункции
// Дополняет массив МассивПриемник значениями из массива МассивИсточник.
//
// Параметры:
// МассивПриемник - Массив - массив, в который необходимо добавить значения.
// МассивИсточник - Массив - массив значений для заполнения.
// ТолькоУникальныеЗначения - Булево - если истина, то в массив будут включены только уникальные значения.
//
Процедура ДополнитьМассивЛкс(МассивПриемник, МассивИсточник, ТолькоУникальныеЗначения = Ложь) Экспорт
Если ТолькоУникальныеЗначения Тогда
УникальныеЗначения = Новый Соответствие;
Для Каждого Значение Из МассивПриемник Цикл
УникальныеЗначения.Вставить(Значение, Истина);
КонецЦикла;
Для Каждого Значение Из МассивИсточник Цикл
Если УникальныеЗначения[Значение] = Неопределено Тогда
МассивПриемник.Добавить(Значение);
УникальныеЗначения.Вставить(Значение, Истина);
КонецЕсли;
КонецЦикла;
Иначе
Для Каждого Значение Из МассивИсточник Цикл
МассивПриемник.Добавить(Значение);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
// Удаляет повторяющиеся элементы массива.
//
// Параметры:
// Массив - Массив - массив произвольных значений.
//
// Возвращаемое значение:
// Массив - коллекция уникальных элементов.
//
Функция СвернутьМассивЛкс(Массив) Экспорт
Результат = Новый Массив;
ДополнитьМассивЛкс(Результат, Массив, Истина);
Возврат Результат;
КонецФункции
Процедура СостояниеЛкс(Знач СтрокаСостояния = "", РазрешитьПрерывание = Ложь, ЭтоСостояниеИндикатора = Ложь) Экспорт
Если Не ЭтоСостояниеИндикатора Тогда
ирПлатформа = ирКэш.Получить();
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
Если ТаблицаИндикаторов.Количество() > 0 Тогда
Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1];
СтрокаСостояния = Индикатор.ТекстСостояния + ".>> " + СтрокаСостояния;
КонецЕсли;
КонецЕсли;
Если РазрешитьПрерывание Тогда
СтрокаСостояния = СтрокаСостояния + ". Прервать Ctrl+Break";
КонецЕсли;
#Если Клиент Тогда
ИспользуемПояснение = Ложь;
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если Не ЗначениеЗаполнено(СтрокаСостояния) Тогда
Возврат;
КонецЕсли;
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803017 Тогда
// http://www.hostedredmine.com/issues/875446
ИспользуемПояснение = Истина;
КонецЕсли;
#КонецЕсли
Если ИспользуемПояснение Тогда
Состояние(,, СтрокаСостояния);
Иначе
Состояние(СтрокаСостояния);
КонецЕсли;
#КонецЕсли
КонецПроцедуры
Функция ЛиДоступноВТолстомКлиентеЛкс() Экспорт
Доступно = Ложь;
Если ирКэш.ЛиТолстыйКлиентЛкс() Тогда
Доступно = Истина;
#Если Клиент Тогда
ИначеЕсли ирКэш.ЛиТонкийКлиентЛкс() Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#КонецЕсли
Иначе
СообщитьЛкс("Команда доступна только в толстом клиенте");
КонецЕсли;
Возврат Доступно;
КонецФункции
///////////////////////////////////////////////////
// Управляемые формы
// Рекурсивно идет вверх до родителя нужного типа
// Параметры:
// ТипРодителя - Тип, *Неопределено - Неопределено=Тип("УправляемаяФорма") Возвращаемое значение:
//
Функция РодительЭлементаУправляемойФормыЛкс(Знач Элемент, ТипРодителя = Неопределено) Экспорт
ТипУправляемаяФорма = Тип("УправляемаяФорма");
Если ТипРодителя = Неопределено Тогда
ТипРодителя = ТипУправляемаяФорма;
КонецЕсли;
Пока ТипЗнч(Элемент) <> ТипРодителя Цикл
Если ТипЗнч(Элемент) = ТипУправляемаяФорма Тогда
Элемент = Неопределено;
Прервать;
КонецЕсли;
Попытка
Элемент = Элемент.Родитель;
Исключение
// Ошибка платформы http://www.hostedredmine.com/issues/880476
Родитель = Неопределено;
Прервать;
КонецПопытки;
КонецЦикла;
Возврат Элемент;
КонецФункции
// Путь - можно передавать как полный путь к реквизиту, так и путь к родительскому реквизиту
//
// Параметры:
// ЭтаФорма - <тип> -
// Путь - <тип>, "" -
// ИмяРеквизита - <тип>, "" -
//
// Возвращаемое значение:
//
Функция ПолучитьРеквизитФормыЛкс(ЭтаФорма, Знач Путь = "", Знач ИмяРеквизита = "") Экспорт
Если Не ЗначениеЗаполнено(ИмяРеквизита) Тогда
Фрагменты = ирОбщий.СтрРазделитьЛкс(Путь);
ИмяРеквизита = Фрагменты[Фрагменты.Количество() - 1];
Фрагменты.Удалить(Фрагменты.Количество() - 1);
Путь = ирОбщий.СтрСоединитьЛкс(Фрагменты, ".");
КонецЕсли;
Результат = Неопределено;
РеквизитыФормы = ЭтаФорма.ПолучитьРеквизиты(Путь);
Для Каждого РеквизитФормы Из РеквизитыФормы Цикл
Если НРег(РеквизитФормы.Имя) = Нрег(ИмяРеквизита) Тогда
Результат = РеквизитФормы;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции // ПолучитьРеквизитФормы()
// Получить тип реквизита формы
//
// Параметры:
// ЭтаФорма - <тип> -
// Путь - <тип>, "" -
// ИмяРеквизита - <тип> -
//
// Возвращаемое значение:
//
Функция ПолучитьТипРеквизитаФормыЛкс(ЭтаФорма, Путь = "", ИмяРеквизита = "") Экспорт
РеквизитФормы = ПолучитьРеквизитФормыЛкс(ЭтаФорма, Путь, ИмяРеквизита);
Результат = РеквизитФормы.ТипЗначения.Типы()[0];
Возврат Результат;
КонецФункции // ПолучитьРеквизитФормы()
// Получить путь К данным элемента управляемой формы. Чтобы функция возвращала правильное значение, в форме должен быть
// выполнен общий обработчик формы _ПриСозданииНаСервереИис.
//
// Параметры:
// Поле - <тип> -
//
// Возвращаемое значение:
//
Функция ПутьКДаннымЭлементаУправляемойФормыЛкс(Знач ЭлементФормы, ОтносительноРодителя = Ложь, Знач ЭтаФорма = Неопределено) Экспорт
Если ЭтаФорма = Неопределено Тогда
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ЭлементФормы, Тип("УправляемаяФорма"));
КонецЕсли;
ПутьКДаннымПоля = "";
Если ЭлементФормы <> ЭтаФорма Тогда
СнимокФормы = Новый Структура("мСлужебныеДанные");
ЗаполнитьЗначенияСвойств(СнимокФормы, ЭтаФорма);
//СообщитьЛкс(Поле.Имя); // Для отладки http://www.hostedredmine.com/issues/850205, http://www.hostedredmine.com/issues/850204
Если СнимокФормы.мСлужебныеДанные <> Неопределено И Не ЭтаФорма.мСлужебныеДанные.ПутиКДанным.Свойство(ЭлементФормы.Имя, ПутьКДаннымПоля) Тогда
ПутьКДаннымПоля = "";
КонецЕсли;
Если ОтносительноРодителя Тогда
ПутьКДаннымПоля = ПоследнийФрагментЛкс(ПутьКДаннымПоля);
КонецЕсли;
КонецЕсли;
Возврат ПутьКДаннымПоля;
КонецФункции
Процедура СкопироватьКнопкиКоманднойПанелиУправляемойФормыЛкс(Знач КоманднаяПанельИсточник, Знач КоманднаяПанельПриемник, Знач ПрефиксИмени) Экспорт
ЭтаФорма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(КоманднаяПанельИсточник);
ЭлементыФормы = ЭтаФорма.Элементы;
Для Каждого КнопкаОбразец Из КоманднаяПанельИсточник.ПодчиненныеЭлементы Цикл
Если Ложь
Или ТипЗнч(КнопкаОбразец) = Тип("ГруппаФормы")
Или Не ЗначениеЗаполнено(КнопкаОбразец.ИмяКоманды)
Тогда
// Это - системная команда
Продолжить;
КонецЕсли;
ИмяНовойКнопки = ПрефиксИмени + КнопкаОбразец.Имя;
НоваяКнопка = ЭлементыФормы.Добавить(ИмяНовойКнопки, ТипЗнч(КнопкаОбразец), КоманднаяПанельПриемник);
ЗаполнитьЗначенияСвойств(НоваяКнопка, КнопкаОбразец,, "Имя");
КонецЦикла;
КонецПроцедуры
Функция НайтиСтрокуДереваФормыПоАдресуЛкс(НачальнаяСтрока, КлючиУровней, Знач ИмяКлючевойКолонки = "Ссылка") Экспорт
ТекущаяСтрока = НачальнаяСтрока;
Уровень = 0;
Для Уровень = 0 По КлючиУровней.Количество() - 1 Цикл
ЭлементыДерева = ТекущаяСтрока.ПолучитьЭлементы();
лТекущаяСтрока = НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(ЭлементыДерева, ИмяКлючевойКолонки, КлючиУровней[Уровень]);
Если лТекущаяСтрока <> Неопределено Тогда
ТекущаяСтрока = лТекущаяСтрока;
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
Возврат ТекущаяСтрока;
КонецФункции
Процедура НастроитьЗаголовкиАвтоТаблицыФормыДинамическогоСпискаЛкс(Знач ОсновнойЭУ, Знач ПолноеИмяТаблицы, Знач РежимИмяСиноним) Экспорт
ПоляТаблицы = ирОбщий.ПоляТаблицыМДЛкс(ПолноеИмяТаблицы);
ПоляТаблицы = ПоляТаблицы.Скопировать();
СтрокаПоляИденитификатора = ПоляТаблицы.Добавить();
СтрокаПоляИденитификатора.Имя = "ИдентификаторСсылкиЛкс";
СтрокаПоляИденитификатора.Заголовок = "Идентификатор ссылки";
Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл
Колонка = ОсновнойЭУ.ПодчиненныеЭлементы.Найти(ОсновнойЭУ.Имя + ПолеТаблицы.Имя);
Если Колонка = Неопределено Тогда
Продолжить;
КонецЕсли;
Если РежимИмяСиноним Тогда
Колонка.Заголовок = ПолеТаблицы.Имя;
Иначе
Колонка.Заголовок = ПолеТаблицы.Заголовок;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // НастроитьАвтоТабличноеПолеДинамическогоСписка()
Функция ЛиАсинхронностьДоступнаЛкс() Экспорт
//Возврат Ложь; // Для отладки
#Если Клиент Тогда
Возврат Не ирКэш.ЭтоФайловаяБазаЛкс() И Не ирКэш.ЛиПортативныйРежимЛкс();
#Иначе
Возврат Ложь;
#КонецЕсли
КонецФункции
#Если Клиент Тогда
// Параметры:
// ЭтаФорма - Форма - обязательный для обычных форм
Процедура Форма_ВнешнееСобытиеЛкс(ЭтаФорма = Неопределено, Источник, Событие, Данные) Экспорт
Если Источник = "KeyboardHook" Тогда
Если ЭтаФорма = Неопределено Тогда
ЭтаФорма = АктивнаяУправляемаяФормаЛкс();
КонецЕсли;
Если ЭтаФорма = Неопределено Тогда
Возврат;
КонецЕсли;
Если Не ЭтаФорма.ВводДоступен() Тогда
Возврат;
КонецЕсли;
ПолученноеЧисло = Лев(Данные,5);
ПолученноеЧисло = Число(ПолученноеЧисло);
ВиртуальнаяКлавиша = ПолученноеЧисло % 256;
ПолученноеЧисло = ПолученноеЧисло - ВиртуальнаяКлавиша;
РасширеннаяКлавиша = ПолученноеЧисло % 512;
ПолученноеЧисло = ПолученноеЧисло - РасширеннаяКлавиша;
ПравыйАльт = ПолученноеЧисло % 1024;
ПолученноеЧисло = ПолученноеЧисло - ПравыйАльт;
ЛевыйАльт = ПолученноеЧисло % 2048;
ПолученноеЧисло = ПолученноеЧисло - ЛевыйАльт;
ПравыйКонтрол = ПолученноеЧисло % 4096;
ПолученноеЧисло = ПолученноеЧисло - ПравыйКонтрол;
ЛевыйКонтрол = ПолученноеЧисло % 8192;
ПолученноеЧисло = ПолученноеЧисло - ЛевыйКонтрол;
ПравыйШифт = ПолученноеЧисло % 16384;
ПолученноеЧисло = ПолученноеЧисло - ПравыйШифт;
ЛевыйШифт = ПолученноеЧисло;
Если СтрДлина(Данные)>5 Тогда
Символ = Сред(Данные, 6);
Иначе
Символ = "";
КонецЕсли;
КодыКлавиш = ирКэш.КодыКлавишЛкс();
Если Ложь
Или Найти(Данные, КодыКлавиш["CTRL+ALT+E"]) = 1
Или Найти(Данные, КодыКлавиш["CTRL+`"]) = 1
Тогда
ирОбщий.ОткрытьГлобальноеМенюЛкс(ЭтаФорма);
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
ИначеЕсли Ложь
Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ПолеВвода")
Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ТабличноеПоле")
Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ПолеФормы")
Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ТаблицаФормы")
Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ПолеТабличногоДокумента")
Тогда
Если Найти(Данные, КодыКлавиш["CTRL+C"]) = 1 Тогда
Попытка
ирОбщий.БуферОбмена_КопироватьЛкс(ЭтаФорма);
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
Сообщить(ОписаниеОшибки);
КонецПопытки;
ИначеЕсли Ложь
//Или Найти(Данные, КодыКлавиш["CTRL+V"]) = 1 // Много нежелательных действий
Или Найти(Данные, КодыКлавиш["ALT+SHIFT+V"]) = 1
Тогда
ирОбщий.БуферОбмена_ВставитьЛкс(ЭтаФорма);
ИначеЕсли Найти(Данные, КодыКлавиш["CTRL+A"]) = 1 Тогда
Если ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ТабличноеПоле") Тогда
ирОбщий.ТабличноеПолеОбновитьТекстыПодваловЛкс(ЭтаФорма.ТекущийЭлемент);
КонецЕсли;
ИначеЕсли Найти(Данные, "00032") = 1 Тогда // SPACE
Если ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ТабличноеПоле") Тогда // Только для форм инструментов
ТабличноеПоле = ЭтаФорма.ТекущийЭлемент;
КолонкаПометки = КолонкаПометкиТабличногоПоляЛкс(ТабличноеПоле);
Если Истина
И Не ТабличноеПоле.ТолькоПросмотр
И ТабличноеПоле.ТекущаяКолонка <> Неопределено
И ТабличноеПоле.ТекущаяКолонка <> КолонкаПометки
И (Ложь
Или ТабличноеПоле.ТекущаяКолонка.ТолькоПросмотр
Или ТабличноеПоле.ТекущаяКолонка.ЭлементУправления = Неопределено)
И (Ложь
Или Не ТабличноеПоле.ИзменяетДанные
Или Не ЭтаФорма.ТолькоПросмотр)
Тогда
ТабличноеПоле_ИнтерактивноУстановитьПометкуТекущейСтрокиЛкс(ТабличноеПоле,, Неопределено);
КонецЕсли;
КонецЕсли;
КонецЕсли;
#КонецЕсли
КонецЕсли;
//Сообщить(Данные);
КонецЕсли;
КонецПроцедуры
Функция АктивнаяУправляемаяФормаЛкс() Экспорт
#Если ТолстыйКлиентОбычноеПриложение Тогда
Возврат Неопределено;
#КонецЕсли
ТекущееОкно = АктивноеОкно();
Если ТекущееОкно = Неопределено Тогда
Окна = ПолучитьОкна();
Для Каждого ТекущееОкно Из Окна Цикл
Если ТекущееОкно.НачальнаяСтраница Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ТипЗнч(ТекущееОкно) = Тип("ОкноКлиентскогоПриложения") Тогда
АктивнаяФорма = Неопределено;
Для Каждого Форма Из ТекущееОкно.Содержимое Цикл
Если Форма.ВводДоступен() Тогда
АктивнаяФорма = Форма;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат АктивнаяФорма;
КонецФункции
#КонецЕсли